diff --git a/AUTHORS b/AUTHORS
index dc45a9a..56667bc 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -82,6 +82,7 @@
 Arunoday Sarkar <a.sarkar.arun@gmail.com>
 Arunprasad Rajkumar <ararunprasad@gmail.com>
 Arunprasad Rajkumar <arurajku@cisco.com>
+Ashish Kumar Gupta <guptaag@amazon.com>
 Ashlin Joseph <ashlin.j@samsung.com>
 Attila Dusnoki <dati91@gmail.com>
 Avinaash Doreswamy <avi.nitk@samsung.com>
diff --git a/DEPS b/DEPS
index 8cbf4bab..c82c3bf 100644
--- a/DEPS
+++ b/DEPS
@@ -40,11 +40,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': '651cbe9af67b49c5a3ad3788c3a50a003827a8e2',
+  'skia_revision': '0bb6f38e511365670b9917ad76ece6f0bee9e282',
   # 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': 'c9b4087f4a00632b7133c491addac7272d45cbef',
+  'v8_revision': '97674cb813b238739f33a160b20b2dd0f0033af8',
   # 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.
@@ -64,7 +64,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
-  'pdfium_revision': '9a785afee976e60fa2bd3d462cdcb1c3636d97dd',
+  'pdfium_revision': '9a8a965829be736e3d7b0f20f6b1ef21d9af1b6e',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling openmax_dl
   # and whatever else without interference from each other.
@@ -90,13 +90,13 @@
   # and whatever else without interference from each other.
   'nacl_revision': 'c948e9b82582e695d16ee6696a484f82239a86d7',
   # Three lines of non-changing comments so that
-  # the commit queue can handle CLs rolling freetype-android
+  # the commit queue can handle CLs rolling freetype
   # and whatever else without interference from each other.
-  'freetype_android_revision': '66725768cdf758cfb3f9abf03cbf5e5a77f42088',
+  'freetype_revision': '66725768cdf758cfb3f9abf03cbf5e5a77f42088',
   # 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': '3c626eaf72a7b8acde9fe17ec63b0b6d851a1a00',
+  'catapult_revision': '353ee60a4567ec80252bb4047e54b2df3151717e',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -236,7 +236,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' + '@' + '59324a62dc4b926f3a3cd37fcbac0418ea6ab01a', # commit position 16996
+    Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + '17d9d862b82ff297f2338f36717296067b5a6952', # commit position 17066
 
   'src/third_party/openmax_dl':
     Var('chromium_git') + '/external/webrtc/deps/third_party/openmax.git' + '@' +  Var('openmax_dl_revision'),
@@ -245,7 +245,7 @@
     Var('chromium_git') + '/external/github.com/open-source-parsers/jsoncpp.git' + '@' + 'f572e8e42e22cfcf5ab0aea26574f408943edfa4', # from svn 248
 
   'src/third_party/libyuv':
-    Var('chromium_git') + '/libyuv/libyuv.git' + '@' + '45b176d153c61732d81b2df0109bd292e67d2b6b',  # from r1645
+    Var('chromium_git') + '/libyuv/libyuv.git' + '@' + '0741a3d70400dc96e59726674b0acf3bca02d710',
 
   'src/third_party/smhasher/src':
     Var('chromium_git') + '/external/smhasher.git' + '@' + 'e87738e57558e0ec472b2fc3a643b838e5b6e88f',
@@ -413,8 +413,8 @@
     'src/third_party/cros_system_api':
       Var('chromium_git') + '/chromiumos/platform/system_api.git' + '@' + 'c08ae470458b06cf23c1907817490d2fc917ac29',
 
-    'src/third_party/freetype-android/src':
-      Var('chromium_git') + '/chromium/src/third_party/freetype2.git' + '@' + Var('freetype_android_revision'),
+    'src/third_party/freetype/src':
+      Var('chromium_git') + '/chromium/src/third_party/freetype2.git' + '@' + Var('freetype_revision'),
 
     # Build tools for Chrome OS. Note: This depends on third_party/pyelftools.
     'src/third_party/chromite':
@@ -479,8 +479,8 @@
     'src/third_party/findbugs':
       Var('chromium_git') + '/chromium/deps/findbugs.git' + '@' + '57f05238d3ac77ea0a194813d3065dd780c6e566',
 
-    'src/third_party/freetype-android/src':
-      Var('chromium_git') + '/chromium/src/third_party/freetype2.git' + '@' + Var('freetype_android_revision'),
+    'src/third_party/freetype/src':
+      Var('chromium_git') + '/chromium/src/third_party/freetype2.git' + '@' + Var('freetype_revision'),
 
     'src/third_party/elfutils/src':
       Var('chromium_git') + '/external/elfutils.git' + '@' + '249673729a7e5dbd5de4f3760bdcaa3d23d154d7',
diff --git a/ash/common/shelf/shelf_button.cc b/ash/common/shelf/shelf_button.cc
index b39fa9c2..d5d32ff7 100644
--- a/ash/common/shelf/shelf_button.cc
+++ b/ash/common/shelf/shelf_button.cc
@@ -32,7 +32,7 @@
 const int kIconSize = 32;
 const int kAttentionThrobDurationMS = 800;
 const int kMaxAnimationSeconds = 10;
-const int kIndicatorOffsetFromBottom = 2;
+const int kIndicatorOffsetFromBottom = 3;
 const int kIndicatorRadiusDip = 2;
 const SkColor kIndicatorColor = SK_ColorWHITE;
 
@@ -146,11 +146,23 @@
 
     DCHECK_EQ(width(), height());
     DCHECK_EQ(kIndicatorRadiusDip, width() / 2);
+    const float dsf = canvas->UndoDeviceScaleFactor();
+    const int kStrokeWidthPx = 1;
+    gfx::PointF center = gfx::RectF(GetLocalBounds()).CenterPoint();
+    center.Scale(dsf);
+
+    // Fill the center.
     cc::PaintFlags flags;
     flags.setColor(kIndicatorColor);
     flags.setFlags(cc::PaintFlags::kAntiAlias_Flag);
-    canvas->DrawCircle(gfx::Point(width() / 2, height() / 2),
-                       kIndicatorRadiusDip, flags);
+    canvas->DrawCircle(center, dsf * kIndicatorRadiusDip - kStrokeWidthPx,
+                       flags);
+
+    // Stroke the border.
+    flags.setColor(SkColorSetA(SK_ColorBLACK, 0x4D));
+    flags.setStyle(SkPaint::kStroke_Style);
+    canvas->DrawCircle(
+        center, dsf * kIndicatorRadiusDip - kStrokeWidthPx / 2.0f, flags);
   }
 
   // ShelfButtonAnimation::Observer
diff --git a/ash/common/system/chromeos/network/network_state_list_detailed_view.cc b/ash/common/system/chromeos/network/network_state_list_detailed_view.cc
index 99332ef..14e9becd 100644
--- a/ash/common/system/chromeos/network/network_state_list_detailed_view.cc
+++ b/ash/common/system/chromeos/network/network_state_list_detailed_view.cc
@@ -532,6 +532,16 @@
         NetworkHandler::Get()->network_state_handler()->DefaultNetwork() !=
         nullptr);
   }
+
+  if (list_type_ != LIST_TYPE_VPN) {
+    bool scanning =
+        NetworkHandler::Get()->network_state_handler()->GetScanningByType(
+            NetworkTypePattern::WiFi());
+    ShowProgress(-1, scanning);
+    info_button_md_->SetTooltipText(l10n_util::GetStringUTF16(
+        scanning ? IDS_ASH_STATUS_TRAY_WIFI_SCANNING_MESSAGE
+                 : IDS_ASH_STATUS_TRAY_NETWORK_INFO));
+  }
 }
 
 bool NetworkStateListDetailedView::OrderChild(views::View* view, int index) {
diff --git a/ash/laser/laser_segment_utils_unittest.cc b/ash/laser/laser_segment_utils_unittest.cc
index 33f4adc5..4d41dce 100644
--- a/ash/laser/laser_segment_utils_unittest.cc
+++ b/ash/laser/laser_segment_utils_unittest.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include <math.h>
+#include <cmath>
 
 #include "ash/laser/laser_segment_utils.h"
 #include "ash/test/ash_test_base.h"
@@ -60,9 +60,9 @@
   ComputeNormalLineVariables(start_point, end_point, &calculated_slope,
                              &calculated_start_y_intercept,
                              &calculated_end_y_intercept);
-  EXPECT_TRUE(isnan(calculated_slope));
-  EXPECT_TRUE(isnan(calculated_start_y_intercept));
-  EXPECT_TRUE(isnan(calculated_end_y_intercept));
+  EXPECT_TRUE(std::isnan(calculated_slope));
+  EXPECT_TRUE(std::isnan(calculated_start_y_intercept));
+  EXPECT_TRUE(std::isnan(calculated_end_y_intercept));
 }
 
 // Helper function to check that the projections from the given line variables
diff --git a/base/BUILD.gn b/base/BUILD.gn
index 21c303d..59b3207 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -2560,6 +2560,7 @@
       "test/android/javatests/src/org/chromium/base/test/BaseChromiumInstrumentationTestRunner.java",
       "test/android/javatests/src/org/chromium/base/test/BaseInstrumentationTestRunner.java",
       "test/android/javatests/src/org/chromium/base/test/BaseJUnit4ClassRunner.java",
+      "test/android/javatests/src/org/chromium/base/test/BaseChromiumAndroidJUnitRunner.java",
       "test/android/javatests/src/org/chromium/base/test/BaseTestResult.java",
       "test/android/javatests/src/org/chromium/base/test/util/AdvancedMockContext.java",
       "test/android/javatests/src/org/chromium/base/test/util/CallbackHelper.java",
diff --git a/base/android/java/src/org/chromium/base/ResourceExtractor.java b/base/android/java/src/org/chromium/base/ResourceExtractor.java
index 898b4910..c1d18560 100644
--- a/base/android/java/src/org/chromium/base/ResourceExtractor.java
+++ b/base/android/java/src/org/chromium/base/ResourceExtractor.java
@@ -17,6 +17,7 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.Locale;
 import java.util.concurrent.CancellationException;
@@ -187,6 +188,10 @@
                 activeLocalePakFiles.add(locale + ".pak");
             }
         }
+        if (activeLocalePakFiles.isEmpty() && BuildConfig.COMPRESSED_LOCALES.length > 0) {
+            assert Arrays.asList(BuildConfig.COMPRESSED_LOCALES).contains(FALLBACK_LOCALE);
+            activeLocalePakFiles.add(FALLBACK_LOCALE + ".pak");
+        }
         return activeLocalePakFiles.toArray(new String[activeLocalePakFiles.size()]);
     }
 
diff --git a/base/files/file_util_unittest.cc b/base/files/file_util_unittest.cc
index 5c918f8..84a7a45 100644
--- a/base/files/file_util_unittest.cc
+++ b/base/files/file_util_unittest.cc
@@ -1744,7 +1744,7 @@
 TEST_F(FileUtilTest, OpenFileNoInheritance) {
   FilePath file_path(temp_dir_.GetPath().Append(FPL("a_file")));
 
-  for (const char* mode : {"wb", "r,ccs=UNICODE"}) {
+  for (const char* mode : {"wb", "r,ccs=UTF-8"}) {
     SCOPED_TRACE(mode);
     ASSERT_NO_FATAL_FAILURE(CreateTextFile(file_path, L"Geepers"));
     FILE* file = OpenFile(file_path, mode);
diff --git a/base/json/json_parser.cc b/base/json/json_parser.cc
index 1666c12..c6f6409d 100644
--- a/base/json/json_parser.cc
+++ b/base/json/json_parser.cc
@@ -444,7 +444,7 @@
   if (!ConsumeStringRaw(&string))
     return nullptr;
 
-  return base::MakeUnique<StringValue>(string.DestructiveAsString());
+  return base::MakeUnique<Value>(string.DestructiveAsString());
 }
 
 bool JSONParser::ConsumeStringRaw(StringBuilder* out) {
diff --git a/base/json/json_parser.h b/base/json/json_parser.h
index d2850e5..4f264583 100644
--- a/base/json/json_parser.h
+++ b/base/json/json_parser.h
@@ -31,7 +31,7 @@
 // to be used directly; it encapsulates logic that need not be exposed publicly.
 //
 // This parser guarantees O(n) time through the input string. It also optimizes
-// base::StringValue by using StringPiece where possible when returning Value
+// base::Value by using StringPiece where possible when returning Value
 // objects by using "hidden roots," discussed in the implementation.
 //
 // Iteration happens on the byte level, with the functions CanConsume and
diff --git a/base/json/json_perftest.cc b/base/json/json_perftest.cc
index 345f226..15222468 100644
--- a/base/json/json_perftest.cc
+++ b/base/json/json_perftest.cc
@@ -26,7 +26,7 @@
   list->Set(0, MakeUnique<Value>(2.718));
   list->Set(1, MakeUnique<Value>(false));
   list->Set(2, MakeUnique<Value>(123));
-  list->Set(3, MakeUnique<StringValue>("Bar"));
+  list->Set(3, MakeUnique<Value>("Bar"));
   root->Set("List", std::move(list));
 
   return root;
diff --git a/base/json/json_writer_unittest.cc b/base/json/json_writer_unittest.cc
index 083fdc7..6cb236f 100644
--- a/base/json/json_writer_unittest.cc
+++ b/base/json/json_writer_unittest.cc
@@ -47,7 +47,7 @@
   EXPECT_EQ("-0.8", output_js);
 
   // Test String values.
-  EXPECT_TRUE(JSONWriter::Write(StringValue("foo"), &output_js));
+  EXPECT_TRUE(JSONWriter::Write(Value("foo"), &output_js));
   EXPECT_EQ("\"foo\"", output_js);
 }
 
diff --git a/base/mac/sdk_forward_declarations.h b/base/mac/sdk_forward_declarations.h
index 5416c6f..b477347 100644
--- a/base/mac/sdk_forward_declarations.h
+++ b/base/mac/sdk_forward_declarations.h
@@ -199,6 +199,12 @@
 - (void)performWindowDragWithEvent:(NSEvent*)event;
 @end
 
+@interface CIRectangleFeature (ElCapitanSDK)
+@property(readonly) CGRect bounds;
+@end
+
+@class CIRectangleFeature;
+
 #endif  // MAC_OS_X_VERSION_10_11
 
 // Once Chrome no longer supports OSX 10.11, everything within this
diff --git a/base/memory/memory_pressure_monitor_mac.cc b/base/memory/memory_pressure_monitor_mac.cc
index 39158902..6261de2 100644
--- a/base/memory/memory_pressure_monitor_mac.cc
+++ b/base/memory/memory_pressure_monitor_mac.cc
@@ -4,6 +4,8 @@
 
 #include "base/memory/memory_pressure_monitor_mac.h"
 
+#include <CoreFoundation/CoreFoundation.h>
+
 #include <dlfcn.h>
 #include <stddef.h>
 #include <sys/sysctl.h>
@@ -26,9 +28,9 @@
 namespace mac {
 
 MemoryPressureListener::MemoryPressureLevel
-MemoryPressureMonitor::MemoryPressureLevelForMacMemoryPressure(
-    int mac_memory_pressure) {
-  switch (mac_memory_pressure) {
+MemoryPressureMonitor::MemoryPressureLevelForMacMemoryPressureLevel(
+    int mac_memory_pressure_level) {
+  switch (mac_memory_pressure_level) {
     case DISPATCH_MEMORYPRESSURE_NORMAL:
       return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
     case DISPATCH_MEMORYPRESSURE_WARN:
@@ -39,6 +41,13 @@
   return MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
 }
 
+void MemoryPressureMonitor::OnRunLoopExit(CFRunLoopObserverRef observer,
+                                          CFRunLoopActivity activity,
+                                          void* info) {
+  MemoryPressureMonitor* self = static_cast<MemoryPressureMonitor*>(info);
+  self->UpdatePressureLevelOnRunLoopExit();
+}
+
 MemoryPressureMonitor::MemoryPressureMonitor()
     : memory_level_event_source_(dispatch_source_create(
           DISPATCH_SOURCE_TYPE_MEMORYPRESSURE,
@@ -48,77 +57,140 @@
           dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0))),
       dispatch_callback_(
           base::Bind(&MemoryPressureListener::NotifyMemoryPressure)),
-      last_statistic_report_(CFAbsoluteTimeGetCurrent()),
+      last_statistic_report_time_(CFAbsoluteTimeGetCurrent()),
       last_pressure_level_(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE),
-      reporting_error_(0) {
-  if (memory_level_event_source_.get() != nullptr) {
+      subtick_seconds_(0) {
+  // Attach an event handler to the memory pressure event source.
+  if (memory_level_event_source_.get()) {
     dispatch_source_set_event_handler(memory_level_event_source_, ^{
       OnMemoryPressureChanged(memory_level_event_source_.get(),
                               dispatch_callback_);
     });
+
+    // Start monitoring the event source.
     dispatch_resume(memory_level_event_source_);
   }
+
+  // Create a CFRunLoopObserver to check the memory pressure at the end of
+  // every pass through the event loop (modulo kUMATickSize).
+  CFRunLoopObserverContext observer_context = {0, this, NULL, NULL, NULL};
+
+  exit_observer_.reset(
+      CFRunLoopObserverCreate(kCFAllocatorDefault, kCFRunLoopExit, true, 0,
+                              OnRunLoopExit, &observer_context));
+
+  CFRunLoopRef run_loop = CFRunLoopGetCurrent();
+  CFRunLoopAddObserver(run_loop, exit_observer_, kCFRunLoopCommonModes);
+  CFRunLoopAddObserver(run_loop, exit_observer_,
+                       kMessageLoopExclusiveRunLoopMode);
 }
 
 MemoryPressureMonitor::~MemoryPressureMonitor() {
-  if (memory_level_event_source_.get() != nullptr)
+  // Detach from the run loop.
+  CFRunLoopRef run_loop = CFRunLoopGetCurrent();
+  CFRunLoopRemoveObserver(run_loop, exit_observer_, kCFRunLoopCommonModes);
+  CFRunLoopRemoveObserver(run_loop, exit_observer_,
+                          kMessageLoopExclusiveRunLoopMode);
+
+  // Remove the memory pressure event source.
+  if (memory_level_event_source_.get()) {
     dispatch_source_cancel(memory_level_event_source_);
+  }
+}
+
+int MemoryPressureMonitor::GetMacMemoryPressureLevel() {
+  // Get the raw memory pressure level from macOS.
+  int mac_memory_pressure_level;
+  size_t length = sizeof(int);
+  sysctlbyname("kern.memorystatus_vm_pressure_level",
+               &mac_memory_pressure_level, &length, nullptr, 0);
+
+  return mac_memory_pressure_level;
+}
+
+void MemoryPressureMonitor::UpdatePressureLevel() {
+  // Get the current macOS pressure level and convert to the corresponding
+  // Chrome pressure level.
+  int mac_memory_pressure_level = GetMacMemoryPressureLevel();
+  MemoryPressureListener::MemoryPressureLevel new_pressure_level =
+      MemoryPressureLevelForMacMemoryPressureLevel(mac_memory_pressure_level);
+
+  // Compute the number of "ticks" spent at |last_pressure_level_| (since the
+  // last report sent to UMA).
+  CFTimeInterval now = CFAbsoluteTimeGetCurrent();
+  CFTimeInterval time_since_last_report = now - last_statistic_report_time_;
+  last_statistic_report_time_ = now;
+
+  double accumulated_time = time_since_last_report + subtick_seconds_;
+  int ticks_to_report = static_cast<int>(accumulated_time / kUMATickSize);
+  // Save for later the seconds that didn't make it into a full tick.
+  subtick_seconds_ = std::fmod(accumulated_time, kUMATickSize);
+
+  // Round the tick count up on a pressure level change to ensure we capture it.
+  bool pressure_level_changed = (new_pressure_level != last_pressure_level_);
+  if (pressure_level_changed && ticks_to_report < 1) {
+    ticks_to_report = 1;
+    subtick_seconds_ = 0;
+  }
+
+  // Send elapsed ticks to UMA.
+  if (ticks_to_report >= 1) {
+    RecordMemoryPressure(last_pressure_level_, ticks_to_report);
+  }
+
+  // Save the now-current memory pressure level.
+  last_pressure_level_ = new_pressure_level;
+}
+
+void MemoryPressureMonitor::UpdatePressureLevelOnRunLoopExit() {
+  // Wait until it's time to check the pressure level.
+  CFTimeInterval now = CFAbsoluteTimeGetCurrent();
+  if (now >= next_run_loop_update_time_) {
+    UpdatePressureLevel();
+
+    // Update again in kUMATickSize seconds. We can update at any frequency,
+    // but because we're only checking memory pressure levels for UMA there's
+    // no need to update more frequently than we're keeping statistics on.
+    next_run_loop_update_time_ = now + kUMATickSize - subtick_seconds_;
+  }
+}
+
+// Static.
+int MemoryPressureMonitor::GetSecondsPerUMATick() {
+  return kUMATickSize;
 }
 
 MemoryPressureListener::MemoryPressureLevel
 MemoryPressureMonitor::GetCurrentPressureLevel() {
-  int mac_memory_pressure;
-  size_t length = sizeof(int);
-  sysctlbyname("kern.memorystatus_vm_pressure_level", &mac_memory_pressure,
-               &length, nullptr, 0);
-  MemoryPressureListener::MemoryPressureLevel memory_pressure_level =
-      MemoryPressureLevelForMacMemoryPressure(mac_memory_pressure);
-  bool pressure_level_changed = false;
-  if (last_pressure_level_ != memory_pressure_level) {
-    pressure_level_changed = true;
-  }
-  SendStatisticsIfNecessary(pressure_level_changed);
-  last_pressure_level_ = memory_pressure_level;
-  return memory_pressure_level;
+  UpdatePressureLevel();
+  return last_pressure_level_;
 }
 
 void MemoryPressureMonitor::OnMemoryPressureChanged(
     dispatch_source_s* event_source,
     const MemoryPressureMonitor::DispatchCallback& dispatch_callback) {
-  int mac_memory_pressure = dispatch_source_get_data(event_source);
+  // Get the Chrome-equvialent memory pressure level.
+  int mac_memory_pressure_level = dispatch_source_get_data(event_source);
   MemoryPressureListener::MemoryPressureLevel memory_pressure_level =
-      MemoryPressureLevelForMacMemoryPressure(mac_memory_pressure);
-  bool pressure_level_changed = false;
-  if (last_pressure_level_ != memory_pressure_level) {
-    pressure_level_changed = true;
-  }
-  SendStatisticsIfNecessary(pressure_level_changed);
-  last_pressure_level_ = memory_pressure_level;
+      MemoryPressureLevelForMacMemoryPressureLevel(mac_memory_pressure_level);
+
+  // Run the callback that's waiting on memory pressure change notifications.
+  // Note that we don't bother with updating |last_pressure_level_| or
+  // causing memory pressure stats to be sent to UMA. Memory pressure change
+  // notifications are delayed on the Mac, so the current actual memory pressure
+  // level may be different than the incoming pressure level from the event.
+  //
+  // In general we don't want to take action (such as freeing memory) on
+  // memory pressure change events, but that's how the current system is
+  // designed. Given that it's incorrect to act on either stale or current
+  // pressure level info, it's not clear which level is better to send. For
+  // now stick with how it's been implemented to date, which is to send the
+  // stale value.
   if (memory_pressure_level !=
       MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE)
     dispatch_callback.Run(memory_pressure_level);
 }
 
-void MemoryPressureMonitor::SendStatisticsIfNecessary(
-    bool pressure_level_changed) {
-  CFTimeInterval now = CFAbsoluteTimeGetCurrent();
-  CFTimeInterval since_last_report = now - last_statistic_report_;
-  last_statistic_report_ = now;
-
-  double accumulated_time = since_last_report + reporting_error_;
-  int ticks_to_report = static_cast<int>(accumulated_time / kUMATickSize);
-  reporting_error_ = std::fmod(accumulated_time, kUMATickSize);
-
-  // Round up on change to ensure we capture it
-  if (pressure_level_changed && ticks_to_report < 1) {
-    ticks_to_report = 1;
-    reporting_error_ = 0;
-  }
-
-  if (ticks_to_report >= 1)
-    RecordMemoryPressure(last_pressure_level_, ticks_to_report);
-}
-
 void MemoryPressureMonitor::SetDispatchCallback(
     const DispatchCallback& callback) {
   dispatch_callback_ = callback;
diff --git a/base/memory/memory_pressure_monitor_mac.h b/base/memory/memory_pressure_monitor_mac.h
index 9118632..b85b6c90 100644
--- a/base/memory/memory_pressure_monitor_mac.h
+++ b/base/memory/memory_pressure_monitor_mac.h
@@ -9,10 +9,12 @@
 #include <dispatch/dispatch.h>
 
 #include "base/base_export.h"
+#include "base/mac/scoped_cftyperef.h"
 #include "base/mac/scoped_dispatch_object.h"
 #include "base/macros.h"
 #include "base/memory/memory_pressure_listener.h"
 #include "base/memory/memory_pressure_monitor.h"
+#include "base/message_loop/message_pump_mac.h"
 
 namespace base {
 namespace mac {
@@ -34,24 +36,51 @@
  private:
   friend TestMemoryPressureMonitor;
 
-  static MemoryPressureLevel
-      MemoryPressureLevelForMacMemoryPressure(int mac_memory_pressure);
+  static MemoryPressureLevel MemoryPressureLevelForMacMemoryPressureLevel(
+      int mac_memory_pressure_level);
+  static void OnRunLoopExit(CFRunLoopObserverRef observer,
+                            CFRunLoopActivity activity,
+                            void* info);
+  // Returns the raw memory pressure level from the macOS. Exposed for
+  // unit testing.
+  virtual int GetMacMemoryPressureLevel();
+
+  // Updates |last_pressure_level_| with the current memory pressure level.
+  void UpdatePressureLevel();
+
+  // Updates |last_pressure_level_| at the end of every run loop pass (modulo
+  // some number of seconds).
+  void UpdatePressureLevelOnRunLoopExit();
+
+  // Run |dispatch_callback| on memory pressure notifications from the OS.
   void OnMemoryPressureChanged(dispatch_source_s* event_source,
                                const DispatchCallback& dispatch_callback);
-  void SendStatisticsIfNecessary(bool pressure_level_changed);
 
+  // Returns the number of seconds per UMA tick (for statistics recording).
+  // Exposed for testing.
+  static int GetSecondsPerUMATick();
+
+  // The dispatch source that generates memory pressure change notifications.
   ScopedDispatchObject<dispatch_source_t> memory_level_event_source_;
 
+  // The callback to call upon receiving a memory pressure change notification.
   DispatchCallback dispatch_callback_;
 
-  CFTimeInterval last_statistic_report_;
+  // Last UMA report time.
+  CFTimeInterval last_statistic_report_time_;
 
+  // Most-recent memory pressure level.
   MemoryPressureLevel last_pressure_level_;
 
-  // The UMA statistic is recorded in 5 second increments. This
-  // accumulates the remaining time to be rolled into the next
-  // call.
-  CFTimeInterval reporting_error_;
+  // Observer that tracks exits from the main run loop.
+  ScopedCFTypeRef<CFRunLoopObserverRef> exit_observer_;
+
+  // Next time to update the memory pressure level when exiting the run loop.
+  CFTimeInterval next_run_loop_update_time_;
+
+  // Seconds left over from the last UMA tick calculation (to be added to the
+  // next calculation).
+  CFTimeInterval subtick_seconds_;
 
   DISALLOW_COPY_AND_ASSIGN(MemoryPressureMonitor);
 };
diff --git a/base/memory/memory_pressure_monitor_mac_unittest.cc b/base/memory/memory_pressure_monitor_mac_unittest.cc
index b7c29cd..9d251f0 100644
--- a/base/memory/memory_pressure_monitor_mac_unittest.cc
+++ b/base/memory/memory_pressure_monitor_mac_unittest.cc
@@ -4,7 +4,11 @@
 
 #include "base/memory/memory_pressure_monitor_mac.h"
 
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/mac/scoped_cftyperef.h"
 #include "base/macros.h"
+#include "base/test/histogram_tester.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace base {
@@ -12,43 +16,87 @@
 
 class TestMemoryPressureMonitor : public MemoryPressureMonitor {
  public:
-  using MemoryPressureMonitor::MemoryPressureLevelForMacMemoryPressure;
+  using MemoryPressureMonitor::MemoryPressureLevelForMacMemoryPressureLevel;
+
+  // A HistogramTester for verifying correct UMA stat generation.
+  base::HistogramTester tester;
 
   TestMemoryPressureMonitor() { }
 
+  // Clears the next run loop update time so that the next pass of the run
+  // loop checks the memory pressure level immediately. Normally there's a
+  // 5 second delay between pressure readings.
+  void ResetRunLoopUpdateTime() { next_run_loop_update_time_ = 0; }
+
+  // Access to the last-recorded memory pressure level.
+  MemoryPressureListener::MemoryPressureLevel LastPressureLevel() {
+    return last_pressure_level_;
+  }
+
+  // Sets the last UMA stat report time. Time spent in memory pressure is
+  // recorded in 5-second "ticks" from the last time statistics were recorded.
+  void SetLastStatisticReportTime(CFTimeInterval time) {
+    last_statistic_report_time_ = time;
+  }
+
+  // Sets the raw macOS memory pressure level read by the memory pressure
+  // monitor.
+  int macos_pressure_level_for_testing_;
+
+  // Exposes the UpdatePressureLevel() method for testing.
+  void UpdatePressureLevel() { MemoryPressureMonitor::UpdatePressureLevel(); }
+
+  // Returns the number of seconds left over from the last UMA tick
+  // calculation.
+  int SubTickSeconds() { return subtick_seconds_; }
+
+  // Returns the number of seconds per UMA tick.
+  static int GetSecondsPerUMATick() {
+    return MemoryPressureMonitor::GetSecondsPerUMATick();
+  }
+
  private:
   DISALLOW_COPY_AND_ASSIGN(TestMemoryPressureMonitor);
+
+  int GetMacMemoryPressureLevel() override {
+    return macos_pressure_level_for_testing_;
+  }
 };
 
 TEST(MacMemoryPressureMonitorTest, MemoryPressureFromMacMemoryPressure) {
-  EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
-            TestMemoryPressureMonitor::
-                MemoryPressureLevelForMacMemoryPressure(
-                    DISPATCH_MEMORYPRESSURE_NORMAL));
-  EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
-            TestMemoryPressureMonitor::
-                MemoryPressureLevelForMacMemoryPressure(
-                    DISPATCH_MEMORYPRESSURE_WARN));
-  EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL,
-            TestMemoryPressureMonitor::
-                MemoryPressureLevelForMacMemoryPressure(
-                    DISPATCH_MEMORYPRESSURE_CRITICAL));
-  EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
-            TestMemoryPressureMonitor::
-                MemoryPressureLevelForMacMemoryPressure(0));
-  EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
-            TestMemoryPressureMonitor::
-                MemoryPressureLevelForMacMemoryPressure(3));
-  EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
-            TestMemoryPressureMonitor::
-                MemoryPressureLevelForMacMemoryPressure(5));
-  EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
-            TestMemoryPressureMonitor::
-                MemoryPressureLevelForMacMemoryPressure(-1));
+  EXPECT_EQ(
+      MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
+      TestMemoryPressureMonitor::MemoryPressureLevelForMacMemoryPressureLevel(
+          DISPATCH_MEMORYPRESSURE_NORMAL));
+  EXPECT_EQ(
+      MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
+      TestMemoryPressureMonitor::MemoryPressureLevelForMacMemoryPressureLevel(
+          DISPATCH_MEMORYPRESSURE_WARN));
+  EXPECT_EQ(
+      MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL,
+      TestMemoryPressureMonitor::MemoryPressureLevelForMacMemoryPressureLevel(
+          DISPATCH_MEMORYPRESSURE_CRITICAL));
+  EXPECT_EQ(
+      MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
+      TestMemoryPressureMonitor::MemoryPressureLevelForMacMemoryPressureLevel(
+          0));
+  EXPECT_EQ(
+      MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
+      TestMemoryPressureMonitor::MemoryPressureLevelForMacMemoryPressureLevel(
+          3));
+  EXPECT_EQ(
+      MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
+      TestMemoryPressureMonitor::MemoryPressureLevelForMacMemoryPressureLevel(
+          5));
+  EXPECT_EQ(
+      MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
+      TestMemoryPressureMonitor::MemoryPressureLevelForMacMemoryPressureLevel(
+          -1));
 }
 
 TEST(MacMemoryPressureMonitorTest, CurrentMemoryPressure) {
   TestMemoryPressureMonitor monitor;
+
   MemoryPressureListener::MemoryPressureLevel memory_pressure =
       monitor.GetCurrentPressureLevel();
   EXPECT_TRUE(memory_pressure ==
@@ -59,5 +107,124 @@
                   MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
 }
 
+TEST(MacMemoryPressureMonitorTest, MemoryPressureConversion) {
+  TestMemoryPressureMonitor monitor;
+
+  monitor.macos_pressure_level_for_testing_ = DISPATCH_MEMORYPRESSURE_NORMAL;
+  MemoryPressureListener::MemoryPressureLevel memory_pressure =
+      monitor.GetCurrentPressureLevel();
+  EXPECT_EQ(memory_pressure,
+            MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE);
+
+  monitor.macos_pressure_level_for_testing_ = DISPATCH_MEMORYPRESSURE_WARN;
+  memory_pressure = monitor.GetCurrentPressureLevel();
+  EXPECT_EQ(memory_pressure,
+            MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE);
+
+  monitor.macos_pressure_level_for_testing_ = DISPATCH_MEMORYPRESSURE_CRITICAL;
+  memory_pressure = monitor.GetCurrentPressureLevel();
+  EXPECT_EQ(memory_pressure,
+            MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
+}
+
+TEST(MacMemoryPressureMonitorTest, MemoryPressureRunLoopChecking) {
+  TestMemoryPressureMonitor monitor;
+
+  // To test grabbing the memory presure at the end of the run loop, we have to
+  // run the run loop, but to do that the run loop needs a run loop source. Add
+  // a timer as the source. We know that the exit observer is attached to
+  // the kMessageLoopExclusiveRunLoopMode mode, so use that mode.
+  ScopedCFTypeRef<CFRunLoopTimerRef> timer_ref(CFRunLoopTimerCreate(
+      NULL, CFAbsoluteTimeGetCurrent() + 10, 0, 0, 0, nullptr, nullptr));
+  CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer_ref,
+                    kMessageLoopExclusiveRunLoopMode);
+
+  monitor.macos_pressure_level_for_testing_ = DISPATCH_MEMORYPRESSURE_WARN;
+  monitor.ResetRunLoopUpdateTime();
+  CFRunLoopRunInMode(kMessageLoopExclusiveRunLoopMode, 0, true);
+  EXPECT_EQ(monitor.LastPressureLevel(),
+            MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE);
+
+  monitor.macos_pressure_level_for_testing_ = DISPATCH_MEMORYPRESSURE_CRITICAL;
+  monitor.ResetRunLoopUpdateTime();
+  CFRunLoopRunInMode(kMessageLoopExclusiveRunLoopMode, 0, true);
+  EXPECT_EQ(monitor.LastPressureLevel(),
+            MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
+
+  monitor.macos_pressure_level_for_testing_ = DISPATCH_MEMORYPRESSURE_NORMAL;
+  monitor.ResetRunLoopUpdateTime();
+  CFRunLoopRunInMode(kMessageLoopExclusiveRunLoopMode, 0, true);
+  EXPECT_EQ(monitor.LastPressureLevel(),
+            MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE);
+
+  CFRunLoopRemoveTimer(CFRunLoopGetCurrent(), timer_ref,
+                       kMessageLoopExclusiveRunLoopMode);
+}
+
+TEST(MacMemoryPressureMonitorTest, RecordMemoryPressureStats) {
+  TestMemoryPressureMonitor monitor;
+  const char* kHistogram = "Memory.PressureLevel";
+  CFTimeInterval now = CFAbsoluteTimeGetCurrent();
+  const int seconds_per_tick =
+      TestMemoryPressureMonitor::GetSecondsPerUMATick();
+
+  // Set the initial pressure level.
+  monitor.macos_pressure_level_for_testing_ = DISPATCH_MEMORYPRESSURE_NORMAL;
+  // Incur one UMA tick of time (and include one extra second of elapsed time).
+  monitor.SetLastStatisticReportTime(now - (seconds_per_tick + 1));
+  monitor.UpdatePressureLevel();
+  monitor.tester.ExpectTotalCount(kHistogram, 1);
+  monitor.tester.ExpectBucketCount(kHistogram, 0, 1);
+  // The report time above included an extra second so there should be 1
+  // sub-tick second left over.
+  EXPECT_EQ(1, monitor.SubTickSeconds());
+
+  // Simulate sitting in normal pressure for 1 second less than 6 UMA tick
+  // seconds and then elevating to warning. With the left over sub-tick second
+  // from above, the total elapsed ticks should be an even 6 UMA ticks.
+  monitor.macos_pressure_level_for_testing_ = DISPATCH_MEMORYPRESSURE_WARN;
+  monitor.SetLastStatisticReportTime(now - (seconds_per_tick * 6 - 1));
+  monitor.UpdatePressureLevel();
+  monitor.tester.ExpectTotalCount(kHistogram, 7);
+  monitor.tester.ExpectBucketCount(kHistogram, 0, 7);
+  monitor.tester.ExpectBucketCount(kHistogram, 1, 0);
+  EXPECT_EQ(0, monitor.SubTickSeconds());
+
+  // Simulate sitting in warning pressure for 20 UMA ticks and 2 seconds, and
+  // then elevating to critical.
+  monitor.macos_pressure_level_for_testing_ = DISPATCH_MEMORYPRESSURE_CRITICAL;
+  monitor.SetLastStatisticReportTime(now - (20 * seconds_per_tick + 2));
+  monitor.UpdatePressureLevel();
+  monitor.tester.ExpectTotalCount(kHistogram, 27);
+  monitor.tester.ExpectBucketCount(kHistogram, 0, 7);
+  monitor.tester.ExpectBucketCount(kHistogram, 1, 20);
+  monitor.tester.ExpectBucketCount(kHistogram, 2, 0);
+  EXPECT_EQ(2, monitor.SubTickSeconds());
+
+  // A quick update while critical - the stats should not budge because less
+  // than 1 tick of time has elapsed.
+  monitor.macos_pressure_level_for_testing_ = DISPATCH_MEMORYPRESSURE_CRITICAL;
+  monitor.SetLastStatisticReportTime(now - 1);
+  monitor.UpdatePressureLevel();
+  monitor.tester.ExpectTotalCount(kHistogram, 27);
+  monitor.tester.ExpectBucketCount(kHistogram, 0, 7);
+  monitor.tester.ExpectBucketCount(kHistogram, 1, 20);
+  monitor.tester.ExpectBucketCount(kHistogram, 2, 0);
+  EXPECT_EQ(3, monitor.SubTickSeconds());
+
+  // A quick change back to normal. Less than 1 tick of time has elapsed, but
+  // in this case the pressure level changed, so the critical bucket should
+  // get another sample (otherwise we could miss quick level changes).
+  monitor.macos_pressure_level_for_testing_ = DISPATCH_MEMORYPRESSURE_NORMAL;
+  monitor.SetLastStatisticReportTime(now - 1);
+  monitor.UpdatePressureLevel();
+  monitor.tester.ExpectTotalCount(kHistogram, 28);
+  monitor.tester.ExpectBucketCount(kHistogram, 0, 7);
+  monitor.tester.ExpectBucketCount(kHistogram, 1, 20);
+  monitor.tester.ExpectBucketCount(kHistogram, 2, 1);
+  // When less than 1 tick of time has elapsed but the pressure level changed,
+  // the subtick remainder gets zeroed out.
+  EXPECT_EQ(0, monitor.SubTickSeconds());
+}
 }  // namespace mac
 }  // namespace base
diff --git a/base/strings/string_util_unittest.cc b/base/strings/string_util_unittest.cc
index 6c054f8..6ac307ec 100644
--- a/base/strings/string_util_unittest.cc
+++ b/base/strings/string_util_unittest.cc
@@ -676,6 +676,10 @@
   std::vector<std::string> parts;
   EXPECT_EQ(std::string(), JoinString(parts, separator));
 
+  parts.push_back(std::string());
+  EXPECT_EQ(std::string(), JoinString(parts, separator));
+  parts.clear();
+
   parts.push_back("a");
   EXPECT_EQ("a", JoinString(parts, separator));
 
@@ -694,6 +698,10 @@
   std::vector<string16> parts;
   EXPECT_EQ(string16(), JoinString(parts, separator));
 
+  parts.push_back(string16());
+  EXPECT_EQ(string16(), JoinString(parts, separator));
+  parts.clear();
+
   parts.push_back(ASCIIToUTF16("a"));
   EXPECT_EQ(ASCIIToUTF16("a"), JoinString(parts, separator));
 
@@ -709,8 +717,13 @@
 
 TEST(StringUtilTest, JoinStringPiece) {
   std::string separator(", ");
-  std::vector<base::StringPiece> parts;
-  EXPECT_EQ(base::StringPiece(), JoinString(parts, separator));
+  std::vector<StringPiece> parts;
+  EXPECT_EQ(std::string(), JoinString(parts, separator));
+
+  // Test empty first part (https://crbug.com/698073).
+  parts.push_back(StringPiece());
+  EXPECT_EQ(std::string(), JoinString(parts, separator));
+  parts.clear();
 
   parts.push_back("a");
   EXPECT_EQ("a", JoinString(parts, separator));
@@ -719,7 +732,7 @@
   parts.push_back("c");
   EXPECT_EQ("a, b, c", JoinString(parts, separator));
 
-  parts.push_back(base::StringPiece());
+  parts.push_back(StringPiece());
   EXPECT_EQ("a, b, c, ", JoinString(parts, separator));
   parts.push_back(" ");
   EXPECT_EQ("a|b|c|| ", JoinString(parts, "|"));
@@ -727,8 +740,13 @@
 
 TEST(StringUtilTest, JoinStringPiece16) {
   string16 separator = ASCIIToUTF16(", ");
-  std::vector<base::StringPiece16> parts;
-  EXPECT_EQ(base::StringPiece16(), JoinString(parts, separator));
+  std::vector<StringPiece16> parts;
+  EXPECT_EQ(string16(), JoinString(parts, separator));
+
+  // Test empty first part (https://crbug.com/698073).
+  parts.push_back(StringPiece16());
+  EXPECT_EQ(string16(), JoinString(parts, separator));
+  parts.clear();
 
   const string16 kA = ASCIIToUTF16("a");
   parts.push_back(kA);
@@ -740,7 +758,7 @@
   parts.push_back(kC);
   EXPECT_EQ(ASCIIToUTF16("a, b, c"), JoinString(parts, separator));
 
-  parts.push_back(base::StringPiece16());
+  parts.push_back(StringPiece16());
   EXPECT_EQ(ASCIIToUTF16("a, b, c, "), JoinString(parts, separator));
   const string16 kSpace = ASCIIToUTF16(" ");
   parts.push_back(kSpace);
@@ -749,13 +767,16 @@
 
 TEST(StringUtilTest, JoinStringInitializerList) {
   std::string separator(", ");
-  EXPECT_EQ(base::StringPiece(), JoinString({}, separator));
+  EXPECT_EQ(std::string(), JoinString({}, separator));
+
+  // Test empty first part (https://crbug.com/698073).
+  EXPECT_EQ(std::string(), JoinString({StringPiece()}, separator));
 
   // With const char*s.
   EXPECT_EQ("a", JoinString({"a"}, separator));
   EXPECT_EQ("a, b, c", JoinString({"a", "b", "c"}, separator));
-  EXPECT_EQ("a, b, c, ", JoinString({"a", "b", "c", ""}, separator));
-  EXPECT_EQ("a|b|c|| ", JoinString({"a", "b", "c", "", " "}, "|"));
+  EXPECT_EQ("a, b, c, ", JoinString({"a", "b", "c", StringPiece()}, separator));
+  EXPECT_EQ("a|b|c|| ", JoinString({"a", "b", "c", StringPiece(), " "}, "|"));
 
   // With std::strings.
   const std::string kA = "a";
@@ -770,7 +791,10 @@
 
 TEST(StringUtilTest, JoinStringInitializerList16) {
   string16 separator = ASCIIToUTF16(", ");
-  EXPECT_EQ(base::StringPiece16(), JoinString({}, separator));
+  EXPECT_EQ(string16(), JoinString({}, separator));
+
+  // Test empty first part (https://crbug.com/698073).
+  EXPECT_EQ(string16(), JoinString({StringPiece16()}, separator));
 
   // With string16s.
   const string16 kA = ASCIIToUTF16("a");
@@ -780,12 +804,12 @@
   const string16 kC = ASCIIToUTF16("c");
   EXPECT_EQ(ASCIIToUTF16("a, b, c"), JoinString({kA, kB, kC}, separator));
 
-  const string16 kEmpty = ASCIIToUTF16("");
   EXPECT_EQ(ASCIIToUTF16("a, b, c, "),
-            JoinString({kA, kB, kC, kEmpty}, separator));
+            JoinString({kA, kB, kC, StringPiece16()}, separator));
   const string16 kSpace = ASCIIToUTF16(" ");
-  EXPECT_EQ(ASCIIToUTF16("a|b|c|| "),
-            JoinString({kA, kB, kC, kEmpty, kSpace}, ASCIIToUTF16("|")));
+  EXPECT_EQ(
+      ASCIIToUTF16("a|b|c|| "),
+      JoinString({kA, kB, kC, StringPiece16(), kSpace}, ASCIIToUTF16("|")));
 
   // With StringPiece16s.
   const StringPiece16 kPieceA = kA;
diff --git a/base/test/android/javatests/src/org/chromium/base/test/BaseChromiumAndroidJUnitRunner.java b/base/test/android/javatests/src/org/chromium/base/test/BaseChromiumAndroidJUnitRunner.java
new file mode 100644
index 0000000..fcd60869
--- /dev/null
+++ b/base/test/android/javatests/src/org/chromium/base/test/BaseChromiumAndroidJUnitRunner.java
@@ -0,0 +1,25 @@
+// Copyright 2017 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.
+
+package org.chromium.base.test;
+
+import android.os.Bundle;
+import android.support.test.runner.AndroidJUnitRunner;
+
+import org.chromium.base.multidex.ChromiumMultiDexInstaller;
+
+/**
+ * A custom AndroidJUnitRunner that supports multidex installer.
+ *
+ * This class is the equivalent of BaseChromiumInstrumentationTestRunner in JUnit3. Please
+ * beware that is this not a class runner. It is declared in test apk AndroidManifest.xml
+ * <instrumentation>
+ */
+public class BaseChromiumAndroidJUnitRunner extends AndroidJUnitRunner {
+    @Override
+    public void onCreate(Bundle arguments) {
+        ChromiumMultiDexInstaller.install(getTargetContext());
+        super.onCreate(arguments);
+    }
+}
diff --git a/base/test/values_test_util.cc b/base/test/values_test_util.cc
index 6c1ee7d..ab12cfb 100644
--- a/base/test/values_test_util.cc
+++ b/base/test/values_test_util.cc
@@ -53,9 +53,8 @@
   EXPECT_EQ(expected_value, string_value) << key;
 }
 
-void ExpectStringValue(const std::string& expected_str,
-                       StringValue* actual) {
-  std::unique_ptr<StringValue> scoped_actual(actual);
+void ExpectStringValue(const std::string& expected_str, Value* actual) {
+  std::unique_ptr<Value> scoped_actual(actual);
   std::string actual_str;
   EXPECT_TRUE(scoped_actual->GetAsString(&actual_str));
   EXPECT_EQ(expected_str, actual_str);
diff --git a/base/test/values_test_util.h b/base/test/values_test_util.h
index 04af92e5..e545660 100644
--- a/base/test/values_test_util.h
+++ b/base/test/values_test_util.h
@@ -14,7 +14,6 @@
 class DictionaryValue;
 class ListValue;
 class Value;
-using StringValue = Value;
 
 // All the functions below expect that the value for the given key in
 // the given dictionary equals the given expected value.
@@ -40,8 +39,7 @@
                            const std::string& key);
 
 // Takes ownership of |actual|.
-void ExpectStringValue(const std::string& expected_str,
-                       StringValue* actual);
+void ExpectStringValue(const std::string& expected_str, Value* actual);
 
 namespace test {
 
diff --git a/base/trace_event/trace_event_argument.cc b/base/trace_event/trace_event_argument.cc
index da33c6d..db702b6 100644
--- a/base/trace_event/trace_event_argument.cc
+++ b/base/trace_event/trace_event_argument.cc
@@ -268,7 +268,7 @@
     } break;
 
     case base::Value::Type::STRING: {
-      const StringValue* string_value;
+      const Value* string_value;
       value.GetAsString(&string_value);
       SetStringWithCopiedName(name, string_value->GetString());
     } break;
@@ -322,7 +322,7 @@
     } break;
 
     case base::Value::Type::STRING: {
-      const StringValue* string_value;
+      const Value* string_value;
       value.GetAsString(&string_value);
       AppendString(string_value->GetString());
     } break;
diff --git a/base/trace_event/trace_event_memory_overhead.cc b/base/trace_event/trace_event_memory_overhead.cc
index 48a0d29f..8d56e1d8 100644
--- a/base/trace_event/trace_event_memory_overhead.cc
+++ b/base/trace_event/trace_event_memory_overhead.cc
@@ -77,9 +77,9 @@
       break;
 
     case Value::Type::STRING: {
-      const StringValue* string_value = nullptr;
+      const Value* string_value = nullptr;
       value.GetAsString(&string_value);
-      Add("StringValue", sizeof(StringValue));
+      Add("StringValue", sizeof(Value));
       AddString(string_value->GetString());
     } break;
 
diff --git a/base/value_conversions.cc b/base/value_conversions.cc
index a461e2c..9320fee 100644
--- a/base/value_conversions.cc
+++ b/base/value_conversions.cc
@@ -17,8 +17,8 @@
 
 // |Value| internally stores strings in UTF-8, so we have to convert from the
 // system native code to UTF-8 and back.
-StringValue* CreateFilePathValue(const FilePath& in_value) {
-  return new StringValue(in_value.AsUTF8Unsafe());
+Value* CreateFilePathValue(const FilePath& in_value) {
+  return new Value(in_value.AsUTF8Unsafe());
 }
 
 bool GetValueAsFilePath(const Value& value, FilePath* file_path) {
@@ -32,9 +32,9 @@
 
 // |Value| does not support 64-bit integers, and doubles do not have enough
 // precision, so we store the 64-bit time value as a string instead.
-StringValue* CreateTimeDeltaValue(const TimeDelta& time) {
+Value* CreateTimeDeltaValue(const TimeDelta& time) {
   std::string string_value = base::Int64ToString(time.ToInternalValue());
-  return new StringValue(string_value);
+  return new Value(string_value);
 }
 
 bool GetValueAsTimeDelta(const Value& value, TimeDelta* time) {
diff --git a/base/value_conversions.h b/base/value_conversions.h
index 6ce1bff..8a464ab 100644
--- a/base/value_conversions.h
+++ b/base/value_conversions.h
@@ -15,13 +15,12 @@
 class FilePath;
 class TimeDelta;
 class Value;
-using StringValue = Value;
 
 // The caller takes ownership of the returned value.
-BASE_EXPORT StringValue* CreateFilePathValue(const FilePath& in_value);
+BASE_EXPORT Value* CreateFilePathValue(const FilePath& in_value);
 BASE_EXPORT bool GetValueAsFilePath(const Value& value, FilePath* file_path);
 
-BASE_EXPORT StringValue* CreateTimeDeltaValue(const TimeDelta& time);
+BASE_EXPORT Value* CreateTimeDeltaValue(const TimeDelta& time);
 BASE_EXPORT bool GetValueAsTimeDelta(const Value& value, TimeDelta* time);
 
 }  // namespace base
diff --git a/base/values.cc b/base/values.cc
index 9aa04f33..18be7c79 100644
--- a/base/values.cc
+++ b/base/values.cc
@@ -290,9 +290,9 @@
   return is_string();
 }
 
-bool Value::GetAsString(const StringValue** out_value) const {
+bool Value::GetAsString(const Value** out_value) const {
   if (out_value && is_string()) {
-    *out_value = static_cast<const StringValue*>(this);
+    *out_value = static_cast<const Value*>(this);
     return true;
   }
   return is_string();
@@ -359,14 +359,12 @@
       return new Value(int_value_);
     case Type::DOUBLE:
       return new Value(double_value_);
-    // For now, make StringValues for backward-compatibility. Convert to
-    // Value when that code is deleted.
     case Type::STRING:
-      return new StringValue(*string_value_);
+      return new Value(*string_value_);
     // For now, make BinaryValues for backward-compatibility. Convert to
     // Value when that code is deleted.
     case Type::BINARY:
-      return new BinaryValue(*binary_value_);
+      return new Value(*binary_value_);
 
     // TODO(crbug.com/646113): Clean this up when DictionaryValue and ListValue
     // are completely inlined.
@@ -683,11 +681,11 @@
 }
 
 void DictionaryValue::SetString(StringPiece path, StringPiece in_value) {
-  Set(path, new StringValue(in_value));
+  Set(path, new Value(in_value));
 }
 
 void DictionaryValue::SetString(StringPiece path, const string16& in_value) {
-  Set(path, new StringValue(in_value));
+  Set(path, new Value(in_value));
 }
 
 void DictionaryValue::SetWithoutPathExpansion(StringPiece key,
@@ -717,12 +715,12 @@
 
 void DictionaryValue::SetStringWithoutPathExpansion(StringPiece path,
                                                     StringPiece in_value) {
-  SetWithoutPathExpansion(path, base::MakeUnique<base::StringValue>(in_value));
+  SetWithoutPathExpansion(path, base::MakeUnique<base::Value>(in_value));
 }
 
 void DictionaryValue::SetStringWithoutPathExpansion(StringPiece path,
                                                     const string16& in_value) {
-  SetWithoutPathExpansion(path, base::MakeUnique<base::StringValue>(in_value));
+  SetWithoutPathExpansion(path, base::MakeUnique<base::Value>(in_value));
 }
 
 bool DictionaryValue::Get(StringPiece path,
@@ -1281,11 +1279,11 @@
 }
 
 void ListValue::AppendString(StringPiece in_value) {
-  Append(MakeUnique<StringValue>(in_value));
+  Append(MakeUnique<Value>(in_value));
 }
 
 void ListValue::AppendString(const string16& in_value) {
-  Append(MakeUnique<StringValue>(in_value));
+  Append(MakeUnique<Value>(in_value));
 }
 
 void ListValue::AppendStrings(const std::vector<std::string>& in_values) {
diff --git a/base/values.h b/base/values.h
index a9578687..9610c281 100644
--- a/base/values.h
+++ b/base/values.h
@@ -39,7 +39,6 @@
 class DictionaryValue;
 class ListValue;
 class Value;
-using StringValue = Value;
 using BinaryValue = Value;
 
 // The Value class is the base class for Values. A Value can be instantiated
@@ -143,7 +142,7 @@
   bool GetAsDouble(double* out_value) const;
   bool GetAsString(std::string* out_value) const;
   bool GetAsString(string16* out_value) const;
-  bool GetAsString(const StringValue** out_value) const;
+  bool GetAsString(const Value** out_value) const;
   bool GetAsString(StringPiece* out_value) const;
   bool GetAsBinary(const BinaryValue** out_value) const;
   // ListValue::From is the equivalent for std::unique_ptr conversions.
diff --git a/base/values_unittest.cc b/base/values_unittest.cc
index b44f80c..3bcdc16 100644
--- a/base/values_unittest.cc
+++ b/base/values_unittest.cc
@@ -43,42 +43,42 @@
 
 TEST(ValuesTest, ConstructStringFromConstCharPtr) {
   const char* str = "foobar";
-  StringValue value(str);
+  Value value(str);
   EXPECT_EQ(Value::Type::STRING, value.type());
   EXPECT_EQ("foobar", value.GetString());
 }
 
 TEST(ValuesTest, ConstructStringFromStdStringConstRef) {
   std::string str = "foobar";
-  StringValue value(str);
+  Value value(str);
   EXPECT_EQ(Value::Type::STRING, value.type());
   EXPECT_EQ("foobar", value.GetString());
 }
 
 TEST(ValuesTest, ConstructStringFromStdStringRefRef) {
   std::string str = "foobar";
-  StringValue value(std::move(str));
+  Value value(std::move(str));
   EXPECT_EQ(Value::Type::STRING, value.type());
   EXPECT_EQ("foobar", value.GetString());
 }
 
 TEST(ValuesTest, ConstructStringFromConstChar16Ptr) {
   string16 str = ASCIIToUTF16("foobar");
-  StringValue value(str.c_str());
+  Value value(str.c_str());
   EXPECT_EQ(Value::Type::STRING, value.type());
   EXPECT_EQ("foobar", value.GetString());
 }
 
 TEST(ValuesTest, ConstructStringFromString16) {
   string16 str = ASCIIToUTF16("foobar");
-  StringValue value(str);
+  Value value(str);
   EXPECT_EQ(Value::Type::STRING, value.type());
   EXPECT_EQ("foobar", value.GetString());
 }
 
 TEST(ValuesTest, ConstructStringFromStringPiece) {
   StringPiece str = "foobar";
-  StringValue value(str);
+  Value value(str);
   EXPECT_EQ(Value::Type::STRING, value.type());
   EXPECT_EQ("foobar", value.GetString());
 }
@@ -151,8 +151,8 @@
 }
 
 TEST(ValuesTest, CopyString) {
-  StringValue value("foobar");
-  StringValue copied_value(value);
+  Value value("foobar");
+  Value copied_value(value);
   EXPECT_EQ(value.type(), copied_value.type());
   EXPECT_EQ(value.GetString(), copied_value.GetString());
 
@@ -270,14 +270,14 @@
 }
 
 TEST(ValuesTest, MoveString) {
-  StringValue value("foobar");
-  StringValue moved_value(std::move(value));
+  Value value("foobar");
+  Value moved_value(std::move(value));
   EXPECT_EQ(Value::Type::STRING, moved_value.type());
   EXPECT_EQ("foobar", moved_value.GetString());
 
   Value blank;
 
-  blank = StringValue("foobar");
+  blank = Value("foobar");
   EXPECT_EQ(Value::Type::STRING, blank.type());
   EXPECT_EQ("foobar", blank.GetString());
 }
@@ -382,7 +382,7 @@
   mixed_list->Set(0, MakeUnique<Value>(true));
   mixed_list->Set(1, MakeUnique<Value>(42));
   mixed_list->Set(2, MakeUnique<Value>(88.8));
-  mixed_list->Set(3, MakeUnique<StringValue>("foo"));
+  mixed_list->Set(3, MakeUnique<Value>("foo"));
   ASSERT_EQ(4u, mixed_list->GetSize());
 
   Value *value = NULL;
@@ -459,17 +459,17 @@
 
 TEST(ValuesTest, StringValue) {
   // Test overloaded StringValue constructor.
-  std::unique_ptr<Value> narrow_value(new StringValue("narrow"));
+  std::unique_ptr<Value> narrow_value(new Value("narrow"));
   ASSERT_TRUE(narrow_value.get());
   ASSERT_TRUE(narrow_value->IsType(Value::Type::STRING));
-  std::unique_ptr<Value> utf16_value(new StringValue(ASCIIToUTF16("utf16")));
+  std::unique_ptr<Value> utf16_value(new Value(ASCIIToUTF16("utf16")));
   ASSERT_TRUE(utf16_value.get());
   ASSERT_TRUE(utf16_value->IsType(Value::Type::STRING));
 
   // Test overloaded GetAsString.
   std::string narrow = "http://google.com";
   string16 utf16 = ASCIIToUTF16("http://google.com");
-  const StringValue* string_value = NULL;
+  const Value* string_value = NULL;
   ASSERT_TRUE(narrow_value->GetAsString(&narrow));
   ASSERT_TRUE(narrow_value->GetAsString(&utf16));
   ASSERT_TRUE(narrow_value->GetAsString(&string_value));
@@ -487,8 +487,7 @@
   // Don't choke on NULL values.
   ASSERT_TRUE(narrow_value->GetAsString(static_cast<string16*>(NULL)));
   ASSERT_TRUE(narrow_value->GetAsString(static_cast<std::string*>(NULL)));
-  ASSERT_TRUE(narrow_value->GetAsString(
-                  static_cast<const StringValue**>(NULL)));
+  ASSERT_TRUE(narrow_value->GetAsString(static_cast<const Value**>(NULL)));
 }
 
 TEST(ValuesTest, ListDeletion) {
@@ -651,12 +650,11 @@
   std::unique_ptr<Value> scoped_double(new Value(3.14));
   Value* original_double = scoped_double.get();
   original_dict.Set("double", std::move(scoped_double));
-  std::unique_ptr<StringValue> scoped_string(new StringValue("hello"));
-  StringValue* original_string = scoped_string.get();
+  std::unique_ptr<Value> scoped_string(new Value("hello"));
+  Value* original_string = scoped_string.get();
   original_dict.Set("string", std::move(scoped_string));
-  std::unique_ptr<StringValue> scoped_string16(
-      new StringValue(ASCIIToUTF16("hello16")));
-  StringValue* original_string16 = scoped_string16.get();
+  std::unique_ptr<Value> scoped_string16(new Value(ASCIIToUTF16("hello16")));
+  Value* original_string16 = scoped_string16.get();
   original_dict.Set("string16", std::move(scoped_string16));
 
   std::vector<char> original_buffer(42, '!');
@@ -866,11 +864,10 @@
   std::unique_ptr<Value> scoped_double(new Value(3.14));
   Value* original_double = scoped_double.get();
   original_dict.Set("double", std::move(scoped_double));
-  std::unique_ptr<StringValue> scoped_string(new StringValue("hello"));
+  std::unique_ptr<Value> scoped_string(new Value("hello"));
   Value* original_string = scoped_string.get();
   original_dict.Set("string", std::move(scoped_string));
-  std::unique_ptr<StringValue> scoped_string16(
-      new StringValue(ASCIIToUTF16("hello16")));
+  std::unique_ptr<Value> scoped_string16(new Value(ASCIIToUTF16("hello16")));
   Value* original_string16 = scoped_string16.get();
   original_dict.Set("string16", std::move(scoped_string16));
 
@@ -972,7 +969,7 @@
   {
     std::unique_ptr<ListValue> inner(new ListValue);
     std::unique_ptr<ListValue> inner2(new ListValue);
-    inner2->Append(MakeUnique<StringValue>("hello"));
+    inner2->Append(MakeUnique<Value>("hello"));
     inner->Append(WrapUnique(new DictionaryValue));
     inner->Append(std::move(inner2));
     root->Set("list_with_empty_children", std::move(inner));
@@ -1070,7 +1067,7 @@
     ADD_FAILURE();
   }
 
-  StringValue value1("value1");
+  Value value1("value1");
   dict.Set("key1", value1.CreateDeepCopy());
   bool seen1 = false;
   for (DictionaryValue::Iterator it(dict); !it.IsAtEnd(); it.Advance()) {
@@ -1081,7 +1078,7 @@
   }
   EXPECT_TRUE(seen1);
 
-  StringValue value2("value2");
+  Value value2("value2");
   dict.Set("key2", value2.CreateDeepCopy());
   bool seen2 = seen1 = false;
   for (DictionaryValue::Iterator it(dict); !it.IsAtEnd(); it.Advance()) {
@@ -1110,7 +1107,7 @@
   Value bool_value(false);
   Value int_value(1234);
   Value double_value(12.34567);
-  StringValue string_value("foo");
+  Value string_value("foo");
   BinaryValue binary_value(Value::Type::BINARY);
   DictionaryValue dict_value;
   ListValue list_value;
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
index 9137028..1f89686 100644
--- a/build/config/compiler/BUILD.gn
+++ b/build/config/compiler/BUILD.gn
@@ -1100,9 +1100,6 @@
         # TODO(hans): https://crbug.com/637306
         "-Wno-address-of-packed-member",
 
-        # TODO(thakis): Consider turning this on, https://crbug.com/691120
-        "-Wno-block-capture-autoreleasing",
-
         # TODO(hans): https://crbug.com/681136
         "-Wno-unused-lambda-capture",
 
diff --git a/build/linux/BUILD.gn b/build/linux/BUILD.gn
index 410f832a..4adeeb3 100644
--- a/build/linux/BUILD.gn
+++ b/build/linux/BUILD.gn
@@ -58,9 +58,8 @@
 group("freetype2") {
   if (is_chromecast) {
     # Chromecast platform doesn't provide freetype, so use Chromium's.
-    # The version in freetype-android is unmodified from freetype2 upstream.
     public_deps = [
-      "//third_party/freetype-android:freetype",
+      "//third_party/freetype",
     ]
   } else {
     public_configs = [ ":freetype2_config" ]
diff --git a/build/sample_arg_file.gn b/build/sample_arg_file.gn
new file mode 100644
index 0000000..91e9045
--- /dev/null
+++ b/build/sample_arg_file.gn
@@ -0,0 +1,6 @@
+# Build arguments go here. Here are some of the most commonly set ones.
+# Run `gn args <out_dir> --list` for the full list.
+#   is_component_build = true
+#   is_debug = true
+#   symbol_level = 2
+#   use_goma = false
diff --git a/cc/ipc/cc_param_traits_macros.h b/cc/ipc/cc_param_traits_macros.h
index 42e97e4..b740e66 100644
--- a/cc/ipc/cc_param_traits_macros.h
+++ b/cc/ipc/cc_param_traits_macros.h
@@ -197,7 +197,6 @@
   IPC_STRUCT_TRAITS_MEMBER(selection)
   IPC_STRUCT_TRAITS_MEMBER(latency_info)
   IPC_STRUCT_TRAITS_MEMBER(referenced_surfaces)
-  IPC_STRUCT_TRAITS_MEMBER(content_source_id)
 IPC_STRUCT_TRAITS_END()
 
 #endif  // CC_IPC_CC_PARAM_TRAITS_MACROS_H_
diff --git a/cc/ipc/compositor_frame_metadata.mojom b/cc/ipc/compositor_frame_metadata.mojom
index 74deb837..2634925 100644
--- a/cc/ipc/compositor_frame_metadata.mojom
+++ b/cc/ipc/compositor_frame_metadata.mojom
@@ -31,5 +31,4 @@
   array<ui.mojom.LatencyInfo> latency_info;
   array<SurfaceId> referenced_surfaces;
   bool can_activate_before_dependencies;
-  uint32 content_source_id;
 };
diff --git a/cc/ipc/compositor_frame_metadata_struct_traits.cc b/cc/ipc/compositor_frame_metadata_struct_traits.cc
index cdef417..e64f6727 100644
--- a/cc/ipc/compositor_frame_metadata_struct_traits.cc
+++ b/cc/ipc/compositor_frame_metadata_struct_traits.cc
@@ -36,7 +36,6 @@
   out->top_controls_shown_ratio = data.top_controls_shown_ratio();
   out->bottom_controls_height = data.bottom_controls_height();
   out->bottom_controls_shown_ratio = data.bottom_controls_shown_ratio();
-  out->content_source_id = data.content_source_id();
 
   out->root_background_color = data.root_background_color();
   out->can_activate_before_dependencies =
diff --git a/cc/ipc/compositor_frame_metadata_struct_traits.h b/cc/ipc/compositor_frame_metadata_struct_traits.h
index c58ba45b..381edb3 100644
--- a/cc/ipc/compositor_frame_metadata_struct_traits.h
+++ b/cc/ipc/compositor_frame_metadata_struct_traits.h
@@ -111,11 +111,6 @@
     return metadata.can_activate_before_dependencies;
   }
 
-  static uint32_t content_source_id(
-      const cc::CompositorFrameMetadata& metadata) {
-    return metadata.content_source_id;
-  }
-
   static bool Read(cc::mojom::CompositorFrameMetadataDataView data,
                    cc::CompositorFrameMetadata* out);
 };
diff --git a/cc/ipc/struct_traits_unittest.cc b/cc/ipc/struct_traits_unittest.cc
index 5647cb51..8088ac9 100644
--- a/cc/ipc/struct_traits_unittest.cc
+++ b/cc/ipc/struct_traits_unittest.cc
@@ -240,7 +240,6 @@
   const gfx::Vector2dF root_scroll_offset(1234.5f, 6789.1f);
   const float page_scale_factor = 1337.5f;
   const gfx::SizeF scrollable_viewport_size(1337.7f, 1234.5f);
-  const uint32_t content_source_id = 3;
 
   CompositorFrame input;
   input.metadata.device_scale_factor = device_scale_factor;
@@ -249,7 +248,6 @@
   input.metadata.scrollable_viewport_size = scrollable_viewport_size;
   input.render_pass_list.push_back(std::move(render_pass));
   input.resource_list.push_back(resource);
-  input.metadata.content_source_id = content_source_id;
 
   mojom::TraitsTestServicePtr proxy = GetTraitsTestProxy();
   CompositorFrame output;
@@ -259,7 +257,6 @@
   EXPECT_EQ(root_scroll_offset, output.metadata.root_scroll_offset);
   EXPECT_EQ(page_scale_factor, output.metadata.page_scale_factor);
   EXPECT_EQ(scrollable_viewport_size, output.metadata.scrollable_viewport_size);
-  EXPECT_EQ(content_source_id, output.metadata.content_source_id);
 
   ASSERT_EQ(1u, output.resource_list.size());
   TransferableResource out_resource = output.resource_list[0];
diff --git a/cc/layers/scrollbar_layer_unittest.cc b/cc/layers/scrollbar_layer_unittest.cc
index 5abdca7..8824b28 100644
--- a/cc/layers/scrollbar_layer_unittest.cc
+++ b/cc/layers/scrollbar_layer_unittest.cc
@@ -224,8 +224,8 @@
   scoped_refptr<Layer> layer_tree_root = Layer::Create();
   scoped_refptr<Layer> scroll_layer = Layer::Create();
   scoped_refptr<Layer> content_layer = Layer::Create();
-  scoped_refptr<Layer> scrollbar_layer = PaintedScrollbarLayer::Create(
-      std::move(scrollbar), layer_tree_root->id());
+  scoped_refptr<Layer> scrollbar_layer =
+      PaintedScrollbarLayer::Create(std::move(scrollbar), scroll_layer->id());
 
   // Choose bounds to give max_scroll_offset = (30, 50).
   layer_tree_root->SetBounds(gfx::Size(70, 150));
@@ -238,7 +238,6 @@
   layer_tree_root->AddChild(scroll_layer);
   scroll_layer->AddChild(content_layer);
   layer_tree_root->AddChild(scrollbar_layer);
-  scrollbar_layer->ToScrollbarLayer()->SetScrollLayer(scroll_layer->id());
 
   layer_tree_root->SavePaintProperties();
   content_layer->SavePaintProperties();
@@ -531,8 +530,7 @@
   const bool kIsLeftSideVerticalScrollbar = false;
   child2 = SolidColorScrollbarLayer::Create(
       scrollbar->Orientation(), kThumbThickness, kTrackStart,
-      kIsLeftSideVerticalScrollbar, child1->id());
-  child2->ToScrollbarLayer()->SetScrollLayer(scroll_layer->id());
+      kIsLeftSideVerticalScrollbar, scroll_layer->id());
   scroll_layer->AddChild(child1);
   scroll_layer->InsertChild(child2, 1);
   layer_tree_root->AddChild(scroll_layer);
@@ -584,8 +582,7 @@
   const bool kIsLeftSideVerticalScrollbar = false;
   scrollbar_layer = SolidColorScrollbarLayer::Create(
       scrollbar->Orientation(), kThumbThickness, kTrackStart,
-      kIsLeftSideVerticalScrollbar, child1->id());
-  scrollbar_layer->ToScrollbarLayer()->SetScrollLayer(scroll_layer->id());
+      kIsLeftSideVerticalScrollbar, scroll_layer->id());
   scroll_layer->AddChild(child1);
   scroll_layer->InsertChild(scrollbar_layer, 1);
   layer_tree_root->AddChild(scroll_layer);
@@ -666,9 +663,8 @@
   const bool kIsLeftSideVerticalScrollbar = false;
   scrollbar_layer = SolidColorScrollbarLayer::Create(
       scrollbar->Orientation(), kThumbThickness, kTrackStart,
-      kIsLeftSideVerticalScrollbar, child1->id());
+      kIsLeftSideVerticalScrollbar, scroll_layer->id());
   scroll_layer->SetScrollClipLayerId(layer_tree_root->id());
-  scrollbar_layer->ToScrollbarLayer()->SetScrollLayer(scroll_layer->id());
   scroll_layer->AddChild(child1);
   scroll_layer->InsertChild(scrollbar_layer, 1);
   layer_tree_root->AddChild(scroll_layer);
diff --git a/cc/layers/solid_color_scrollbar_layer.cc b/cc/layers/solid_color_scrollbar_layer.cc
index 2670fd3..2eb5484 100644
--- a/cc/layers/solid_color_scrollbar_layer.cc
+++ b/cc/layers/solid_color_scrollbar_layer.cc
@@ -39,7 +39,7 @@
                                    int track_start,
                                    bool is_left_side_vertical_scrollbar,
                                    int scroll_layer_id)
-    : scroll_layer_id(Layer::INVALID_ID),
+    : scroll_layer_id(scroll_layer_id),
       orientation(orientation),
       thumb_thickness(thumb_thickness),
       track_start(track_start),
diff --git a/cc/output/compositor_frame_metadata.h b/cc/output/compositor_frame_metadata.h
index 59023b43..e383e50 100644
--- a/cc/output/compositor_frame_metadata.h
+++ b/cc/output/compositor_frame_metadata.h
@@ -82,12 +82,6 @@
   // dependencies have been resolved.
   bool can_activate_before_dependencies = true;
 
-  // This is a value that allows the browser to associate compositor frames
-  // with the content that they represent -- typically top-level page loads.
-  // TODO(kenrb, fsamuel): This should eventually by SurfaceID, when they
-  // become available in all renderer processes. See https://crbug.com/695579.
-  uint32_t content_source_id;
-
  private:
   CompositorFrameMetadata(const CompositorFrameMetadata& other);
   CompositorFrameMetadata operator=(const CompositorFrameMetadata&) = delete;
diff --git a/cc/scheduler/compositor_timing_history.cc b/cc/scheduler/compositor_timing_history.cc
index eee7dd0..b1a9837 100644
--- a/cc/scheduler/compositor_timing_history.cc
+++ b/cc/scheduler/compositor_timing_history.cc
@@ -62,10 +62,6 @@
 constexpr base::TimeDelta kSubmitAckWatchdogTimeout =
     base::TimeDelta::FromSeconds(8);
 
-const int kUmaDurationMinMicros = 1;
-const int64_t kUmaDurationMaxMicros = base::Time::kMicrosecondsPerSecond / 5;
-const int kUmaDurationBucketCount = 100;
-
 // This macro is deprecated since its bucket count uses too much bandwidth.
 // It also has sub-optimal range and bucket distribution.
 // TODO(brianderson): Delete this macro and associated UMAs once there is
@@ -111,7 +107,6 @@
 
 #define UMA_HISTOGRAM_CUSTOM_TIMES_VSYNC_ALIGNED(name, sample)             \
   do {                                                                     \
-    UMA_HISTOGRAM_CUSTOM_TIMES_MICROS(name, sample);                       \
     UMA_HISTOGRAM_CUSTOM_ENUMERATION(                                      \
         name "2", sample.InMicroseconds(),                                 \
         std::vector<int>(kUMAVSyncBuckets,                                 \
@@ -120,7 +115,6 @@
 
 #define UMA_HISTOGRAM_CUSTOM_TIMES_DURATION(name, sample)           \
   do {                                                              \
-    UMA_HISTOGRAM_CUSTOM_TIMES_MICROS(name, sample);                \
     UMA_HISTOGRAM_CUSTOM_ENUMERATION(                               \
         name "2", sample.InMicroseconds(),                          \
         std::vector<int>(                                           \
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc
index 942d593..4ad7918 100644
--- a/cc/trees/layer_tree_host.cc
+++ b/cc/trees/layer_tree_host.cc
@@ -104,7 +104,6 @@
       debug_state_(settings_.initial_debug_state),
       id_(s_layer_tree_host_sequence_number.GetNext() + 1),
       task_graph_runner_(params->task_graph_runner),
-      content_source_id_(0),
       event_listener_properties_(),
       mutator_host_(params->mutator_host) {
   DCHECK(task_graph_runner_);
@@ -973,13 +972,6 @@
       this, [](Layer* layer) { layer->SetNeedsDisplay(); });
 }
 
-void LayerTreeHost::SetContentSourceId(uint32_t id) {
-  if (content_source_id_ == id)
-    return;
-  content_source_id_ = id;
-  SetNeedsCommit();
-}
-
 void LayerTreeHost::RegisterLayer(Layer* layer) {
   DCHECK(!LayerById(layer->id()));
   DCHECK(!in_paint_layer_contents_);
@@ -1150,8 +1142,6 @@
 
   tree_impl->SetDeviceColorSpace(device_color_space_);
 
-  tree_impl->set_content_source_id(content_source_id_);
-
   if (pending_page_scale_animation_) {
     tree_impl->SetPendingPageScaleAnimation(
         std::move(pending_page_scale_animation_));
diff --git a/cc/trees/layer_tree_host.h b/cc/trees/layer_tree_host.h
index 9a5deabf..809ffb6 100644
--- a/cc/trees/layer_tree_host.h
+++ b/cc/trees/layer_tree_host.h
@@ -309,9 +309,6 @@
     return painted_device_scale_factor_;
   }
 
-  void SetContentSourceId(uint32_t);
-  uint32_t content_source_id() const { return content_source_id_; }
-
   void SetDeviceColorSpace(const gfx::ColorSpace& device_color_space);
   const gfx::ColorSpace& device_color_space() const {
     return device_color_space_;
@@ -573,8 +570,6 @@
   float max_page_scale_factor_ = 1.f;
   gfx::ColorSpace device_color_space_;
 
-  uint32_t content_source_id_;
-
   SkColor background_color_ = SK_ColorWHITE;
   bool has_transparent_background_ = false;
 
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index 15d72e6e..26208cb4 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -1581,7 +1581,6 @@
   metadata.bottom_controls_shown_ratio =
       browser_controls_offset_manager_->BottomControlsShownRatio();
   metadata.root_background_color = active_tree_->background_color();
-  metadata.content_source_id = active_tree_->content_source_id();
 
   active_tree_->GetViewportSelection(&metadata.selection);
 
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc
index 1f2059cb..eaf3c475 100644
--- a/cc/trees/layer_tree_host_unittest.cc
+++ b/cc/trees/layer_tree_host_unittest.cc
@@ -7010,32 +7010,5 @@
 
 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSubmitFrameResources);
 
-// Ensure that content_source_id is propagated to the frame's metadata.
-class LayerTreeHostTestContentSourceId : public LayerTreeHostTest {
- protected:
-  void BeginTest() override {
-    layer_tree_host()->SetContentSourceId(5);
-    PostSetNeedsCommitToMainThread();
-  }
-
-  DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
-                                   LayerTreeHostImpl::FrameData* frame_data,
-                                   DrawResult draw_result) override {
-    EXPECT_EQ(DRAW_SUCCESS, draw_result);
-    EXPECT_EQ(5U, host_impl->active_tree()->content_source_id());
-    return draw_result;
-  }
-
-  void DisplayReceivedCompositorFrameOnThread(
-      const CompositorFrame& frame) override {
-    EXPECT_EQ(5U, frame.metadata.content_source_id);
-    EndTest();
-  }
-
-  void AfterTest() override {}
-};
-
-SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestContentSourceId);
-
 }  // namespace
 }  // namespace cc
diff --git a/cc/trees/layer_tree_host_unittest_damage.cc b/cc/trees/layer_tree_host_unittest_damage.cc
index 5873138c..d2f0b86 100644
--- a/cc/trees/layer_tree_host_unittest_damage.cc
+++ b/cc/trees/layer_tree_host_unittest_damage.cc
@@ -354,7 +354,6 @@
         FakePaintedScrollbarLayer::Create(false, true, content_layer_->id());
     scrollbar_layer->SetPosition(gfx::PointF(300.f, 300.f));
     scrollbar_layer->SetBounds(gfx::Size(10, 100));
-    scrollbar_layer->ToScrollbarLayer()->SetScrollLayer(content_layer_->id());
     root_layer->AddChild(scrollbar_layer);
 
     gfx::RectF content_rect(content_layer_->position(),
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc
index fa6f8add..6dd6aff 100644
--- a/cc/trees/layer_tree_impl.cc
+++ b/cc/trees/layer_tree_impl.cc
@@ -73,7 +73,6 @@
       max_page_scale_factor_(0),
       device_scale_factor_(1.f),
       painted_device_scale_factor_(1.f),
-      content_source_id_(0),
       elastic_overscroll_(elastic_overscroll),
       layers_(new OwnedLayerImplList),
       viewport_size_invalid_(false),
@@ -488,8 +487,6 @@
   target_tree->SetDeviceColorSpace(device_color_space_);
   target_tree->elastic_overscroll()->PushPendingToActive();
 
-  target_tree->set_content_source_id(content_source_id());
-
   target_tree->pending_page_scale_animation_ =
       std::move(pending_page_scale_animation_);
 
diff --git a/cc/trees/layer_tree_impl.h b/cc/trees/layer_tree_impl.h
index 02c6e99..09cd850f 100644
--- a/cc/trees/layer_tree_impl.h
+++ b/cc/trees/layer_tree_impl.h
@@ -229,9 +229,6 @@
     return painted_device_scale_factor_;
   }
 
-  void set_content_source_id(uint32_t id) { content_source_id_ = id; }
-  uint32_t content_source_id() { return content_source_id_; }
-
   void SetDeviceColorSpace(const gfx::ColorSpace& device_color_space);
   const gfx::ColorSpace& device_color_space() const {
     return device_color_space_;
@@ -498,8 +495,6 @@
   float painted_device_scale_factor_;
   gfx::ColorSpace device_color_space_;
 
-  uint32_t content_source_id_;
-
   scoped_refptr<SyncedElasticOverscroll> elastic_overscroll_;
 
   std::unique_ptr<OwnedLayerImplList> layers_;
diff --git a/chrome/VERSION b/chrome/VERSION
index ed06da4..67ffb9d 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=59
 MINOR=0
-BUILD=3030
+BUILD=3033
 PATCH=0
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java
index 3348468..a24fcb5 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java
@@ -2059,10 +2059,7 @@
     @Nullable public static ChromeActivity fromWebContents(@Nullable WebContents webContents) {
         if (webContents == null) return null;
 
-        ContentViewCore contentViewCore = ContentViewCore.fromWebContents(webContents);
-        if (contentViewCore == null) return null;
-
-        WindowAndroid window = contentViewCore.getWindowAndroid();
+        WindowAndroid window = webContents.getTopLevelNativeWindow();
         if (window == null) return null;
 
         Activity activity = window.getActivity().get();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ShortcutHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/ShortcutHelper.java
index 769b930..b494a36 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ShortcutHelper.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ShortcutHelper.java
@@ -671,10 +671,19 @@
      */
     @CalledByNative
     public static void retrieveWebApks(long callbackPointer) {
+        List<String> names = new ArrayList<>();
         List<String> shortNames = new ArrayList<>();
         List<String> packageNames = new ArrayList<>();
         List<Integer> shellApkVersions = new ArrayList<>();
         List<Integer> versionCodes = new ArrayList<>();
+        List<String> uris = new ArrayList<>();
+        List<String> scopes = new ArrayList<>();
+        List<String> manifestUrls = new ArrayList<>();
+        List<String> manifestStartUrls = new ArrayList<>();
+        List<Integer> displayModes = new ArrayList<>();
+        List<Integer> orientations = new ArrayList<>();
+        List<Long> themeColors = new ArrayList<>();
+        List<Long> backgroundColors = new ArrayList<>();
 
         Context context = ContextUtils.getApplicationContext();
         PackageManager packageManager = context.getPackageManager();
@@ -685,16 +694,29 @@
                 WebApkInfo webApkInfo =
                         WebApkInfo.create(packageInfo.packageName, "", ShortcutSource.UNKNOWN);
                 if (webApkInfo != null) {
+                    names.add(webApkInfo.name());
                     shortNames.add(webApkInfo.shortName());
                     packageNames.add(webApkInfo.webApkPackageName());
                     shellApkVersions.add(webApkInfo.shellApkVersion());
                     versionCodes.add(packageInfo.versionCode);
+                    uris.add(webApkInfo.uri().toString());
+                    scopes.add(webApkInfo.scopeUri().toString());
+                    manifestUrls.add(webApkInfo.manifestUrl());
+                    manifestStartUrls.add(webApkInfo.manifestStartUrl());
+                    displayModes.add(webApkInfo.displayMode());
+                    orientations.add(webApkInfo.orientation());
+                    themeColors.add(webApkInfo.themeColor());
+                    backgroundColors.add(webApkInfo.backgroundColor());
                 }
             }
         }
-        nativeOnWebApksRetrieved(callbackPointer, shortNames.toArray(new String[0]),
-                packageNames.toArray(new String[0]), integerListToIntArray(shellApkVersions),
-                integerListToIntArray(versionCodes));
+        nativeOnWebApksRetrieved(callbackPointer, names.toArray(new String[0]),
+                shortNames.toArray(new String[0]), packageNames.toArray(new String[0]),
+                integerListToIntArray(shellApkVersions), integerListToIntArray(versionCodes),
+                uris.toArray(new String[0]), scopes.toArray(new String[0]),
+                manifestUrls.toArray(new String[0]), manifestStartUrls.toArray(new String[0]),
+                integerListToIntArray(displayModes), integerListToIntArray(orientations),
+                longListToLongArray(themeColors), longListToLongArray(backgroundColors));
     }
 
     private static int[] integerListToIntArray(@NonNull List<Integer> list) {
@@ -705,7 +727,17 @@
         return array;
     }
 
+    private static long[] longListToLongArray(@NonNull List<Long> list) {
+        long[] array = new long[list.size()];
+        for (int i = 0; i < list.size(); i++) {
+            array[i] = list.get(i);
+        }
+        return array;
+    }
+
     private static native void nativeOnWebappDataStored(long callbackPointer);
-    private static native void nativeOnWebApksRetrieved(long callbackPointer, String[] shortNames,
-            String[] packageName, int[] shellApkVersions, int[] versionCodes);
+    private static native void nativeOnWebApksRetrieved(long callbackPointer, String[] names,
+            String[] shortNames, String[] packageName, int[] shellApkVersions, int[] versionCodes,
+            String[] uris, String[] scopes, String[] manifestUrls, String[] manifestStartUrls,
+            int[] displayModes, int[] orientations, long[] themeColors, long[] backgroundColors);
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/DomDistillerUIUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/DomDistillerUIUtils.java
index 0084faf6..fcf48f1 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/DomDistillerUIUtils.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/DomDistillerUIUtils.java
@@ -17,7 +17,6 @@
 import org.chromium.chrome.browser.feedback.FeedbackCollector;
 import org.chromium.chrome.browser.feedback.FeedbackReporter;
 import org.chromium.chrome.browser.profiles.Profile;
-import org.chromium.content.browser.ContentViewCore;
 import org.chromium.content_public.browser.WebContents;
 import org.chromium.ui.base.WindowAndroid;
 
@@ -118,10 +117,7 @@
     private static Activity getActivityFromWebContents(WebContents webContents) {
         if (webContents == null) return null;
 
-        ContentViewCore contentView = ContentViewCore.fromWebContents(webContents);
-        if (contentView == null) return null;
-
-        WindowAndroid window = contentView.getWindowAndroid();
+        WindowAndroid window = webContents.getTopLevelNativeWindow();
         if (window == null) return null;
 
         return window.getActivity().get();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationService.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationService.java
index 29ce08ba..a51f908 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationService.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationService.java
@@ -44,6 +44,7 @@
 import org.chromium.chrome.browser.init.EmptyBrowserParts;
 import org.chromium.chrome.browser.notifications.ChromeNotificationBuilder;
 import org.chromium.chrome.browser.notifications.NotificationConstants;
+import org.chromium.chrome.browser.notifications.NotificationUmaTracker;
 import org.chromium.chrome.browser.offlinepages.downloads.OfflinePageDownloadBridge;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.util.IntentUtils;
@@ -552,11 +553,9 @@
                 mContext.getResources().getString(R.string.download_notification_cancel_button),
                 buildPendingIntent(cancelIntent, notificationId));
 
-        updateNotification(notificationId, builder.build());
-
         int itemType = isOfflinePage ? DownloadSharedPreferenceEntry.ITEM_TYPE_OFFLINE_PAGE
                                      : DownloadSharedPreferenceEntry.ITEM_TYPE_DOWNLOAD;
-        mDownloadSharedPreferenceHelper.addOrReplaceSharedPreferenceEntry(
+        updateNotification(notificationId, builder.build(), downloadGuid, isOfflinePage,
                 new DownloadSharedPreferenceEntry(notificationId, isOffTheRecord,
                         canDownloadWhileMetered, downloadGuid, fileName, itemType, true));
         startTrackingInProgressDownload(downloadGuid);
@@ -599,7 +598,7 @@
                 mDownloadSharedPreferenceHelper.getDownloadSharedPreferenceEntry(downloadGuid);
         if (entry == null) return;
         if (!isResumable) {
-            notifyDownloadFailed(downloadGuid, entry.fileName);
+            notifyDownloadFailed(entry.isOfflinePage(), downloadGuid, entry.fileName);
             return;
         }
         // If download is already paused, do nothing.
@@ -640,11 +639,9 @@
         dismissIntent.putExtra(EXTRA_NOTIFICATION_DISMISSED, true);
         builder.setDeleteIntent(buildPendingIntent(dismissIntent, entry.notificationId));
 
-        updateNotification(entry.notificationId, builder.build());
-        // Update the SharedPreference entry with the new isAutoResumable value.
-        mDownloadSharedPreferenceHelper.addOrReplaceSharedPreferenceEntry(
-                new DownloadSharedPreferenceEntry(
-                        entry.notificationId, entry.isOffTheRecord,
+        updateNotification(entry.notificationId, builder.build(), downloadGuid,
+                entry.isOfflinePage(),
+                new DownloadSharedPreferenceEntry(entry.notificationId, entry.isOffTheRecord,
                         entry.canDownloadWhileMetered, entry.downloadGuid, entry.fileName,
                         entry.itemType, isAutoResumable));
         stopTrackingInProgressDownload(downloadGuid);
@@ -689,19 +686,19 @@
             mDownloadSuccessLargeIcon = getLargeNotificationIcon(bitmap);
         }
         builder.setLargeIcon(mDownloadSuccessLargeIcon);
-        updateNotification(notificationId, builder.build());
-        mDownloadSharedPreferenceHelper.removeSharedPreferenceEntry(downloadGuid);
+        updateNotification(notificationId, builder.build(), downloadGuid, isOfflinePage, null);
         stopTrackingInProgressDownload(downloadGuid);
         return notificationId;
     }
 
     /**
      * Add a download failed notification.
+     * @param isOfflinePage Whether or not the download was for an offline page.
      * @param downloadGuid GUID of the download.
      * @param fileName GUID of the download.
      */
     @VisibleForTesting
-    public void notifyDownloadFailed(String downloadGuid, String fileName) {
+    public void notifyDownloadFailed(boolean isOfflinePage, String downloadGuid, String fileName) {
         // If the download is not in history db, fileName could be empty. Get it from
         // SharedPreferences.
         if (TextUtils.isEmpty(fileName)) {
@@ -715,8 +712,7 @@
         ChromeNotificationBuilder builder =
                 buildNotification(android.R.drawable.stat_sys_download_done, fileName,
                         mContext.getResources().getString(R.string.download_notification_failed));
-        updateNotification(notificationId, builder.build());
-        mDownloadSharedPreferenceHelper.removeSharedPreferenceEntry(downloadGuid);
+        updateNotification(notificationId, builder.build(), downloadGuid, isOfflinePage, null);
         stopTrackingInProgressDownload(downloadGuid);
     }
 
@@ -964,17 +960,33 @@
         }
         return DownloadManagerService.getDownloadManagerService(getApplicationContext());
     }
-
-    /**
-     * Update the notification with id.
-     * @param id Id of the notification that has to be updated.
-     * @param notification the notification object that needs to be updated.
-     */
     @VisibleForTesting
     void updateNotification(int id, Notification notification) {
         mNotificationManager.notify(NOTIFICATION_NAMESPACE, id, notification);
     }
 
+    private void updateNotification(int id, Notification notification, String downloadGuid,
+            boolean isOfflinePage, DownloadSharedPreferenceEntry entry) {
+        updateNotification(id, notification);
+        trackNotificationUma(isOfflinePage, downloadGuid);
+
+        if (entry != null) {
+            mDownloadSharedPreferenceHelper.addOrReplaceSharedPreferenceEntry(entry);
+        } else {
+            mDownloadSharedPreferenceHelper.removeSharedPreferenceEntry(downloadGuid);
+        }
+    }
+
+    private void trackNotificationUma(boolean isOfflinePage, String downloadGuid) {
+        // Check if we already have an entry in the DownloadSharedPreferenceHelper.  This is a
+        // reasonable indicator for whether or not a notification is already showing (or at least if
+        // we had built one for this download before.
+        if (mDownloadSharedPreferenceHelper.hasEntry(downloadGuid)) return;
+        NotificationUmaTracker.getInstance().onNotificationShown(isOfflinePage
+                        ? NotificationUmaTracker.DOWNLOAD_PAGES
+                        : NotificationUmaTracker.DOWNLOAD_FILES);
+    }
+
     /**
      * Checks if an intent requires operations on a download.
      * @param intent An intent to validate.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadSharedPreferenceHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadSharedPreferenceHelper.java
index 0f5bc9d..fa156a5 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadSharedPreferenceHelper.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadSharedPreferenceHelper.java
@@ -53,6 +53,15 @@
     }
 
     /**
+     * Helper method to make querying whether or not an entry exists for {@code guid} easier.
+     * @param guid The guid that represents the download entry.
+     * @return Whether or not that entry currently has metadata.
+     */
+    public boolean hasEntry(String guid) {
+        return getDownloadSharedPreferenceEntry(guid) != null;
+    }
+
+    /**
      * Adds a DownloadSharedPreferenceEntry to SharedPrefs. If an entry with the GUID already exists
      * in SharedPrefs, update it if it has changed.
      * @param pendingEntry A DownloadSharedPreferenceEntry to be added.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/SystemDownloadNotifier.java b/chrome/android/java/src/org/chromium/chrome/browser/download/SystemDownloadNotifier.java
index 7e5d29ab..c27a782 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/download/SystemDownloadNotifier.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/download/SystemDownloadNotifier.java
@@ -286,7 +286,8 @@
                 onSuccessNotificationShown(notificationInfo, notificationId);
                 break;
             case DOWNLOAD_NOTIFICATION_TYPE_FAILURE:
-                mBoundService.notifyDownloadFailed(info.getDownloadGuid(), info.getFileName());
+                mBoundService.notifyDownloadFailed(
+                        info.isOfflinePage(), info.getDownloadGuid(), info.getFileName());
                 break;
             case DOWNLOAD_NOTIFICATION_TYPE_CANCEL:
                 mBoundService.notifyDownloadCanceled(info.getDownloadGuid());
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoNotificationManager.java b/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoNotificationManager.java
index 3555760..b56b9b6 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoNotificationManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoNotificationManager.java
@@ -13,6 +13,7 @@
 import org.chromium.chrome.browser.AppHooks;
 import org.chromium.chrome.browser.notifications.ChromeNotificationBuilder;
 import org.chromium.chrome.browser.notifications.NotificationConstants;
+import org.chromium.chrome.browser.notifications.NotificationUmaTracker;
 
 /**
  * Manages the notification indicating that there are incognito tabs opened in Document mode.
@@ -51,6 +52,8 @@
         NotificationManager nm =
                 (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
         nm.notify(INCOGNITO_TABS_OPEN_TAG, INCOGNITO_TABS_OPEN_ID, builder.build());
+        NotificationUmaTracker.getInstance().onNotificationShown(
+                NotificationUmaTracker.CLOSE_INCOGNITO);
     }
 
     /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationUmaTracker.java b/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationUmaTracker.java
new file mode 100644
index 0000000..d97bf8f9
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationUmaTracker.java
@@ -0,0 +1,93 @@
+// Copyright 2017 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.
+
+package org.chromium.chrome.browser.notifications;
+
+import android.content.SharedPreferences;
+import android.support.annotation.IntDef;
+import android.support.v4.app.NotificationManagerCompat;
+
+import org.chromium.base.ContextUtils;
+import org.chromium.base.library_loader.LibraryLoader;
+import org.chromium.base.metrics.RecordHistogram;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Helper class to make tracking notification UMA stats easier for various features.  Having a
+ * single entry point here to make more complex tracking easier to add in the future.
+ */
+public class NotificationUmaTracker {
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({DOWNLOAD_FILES, DOWNLOAD_PAGES, CLOSE_INCOGNITO, SYSTEM_NOTIFICATION_TYPE_BOUNDARY})
+    public @interface SystemNotificationType {}
+
+    /*
+     * A list of notification types.  To add a type to this list please update
+     * SystemNotificationType in histograms.xml and make sure to keep this list in sync.  Additions
+     * should be treated as APPEND ONLY to keep the UMA metric semantics the same over time.
+     *
+     * A SystemNotificationType value can also be saved in shared preferences.
+     */
+    public static final int DOWNLOAD_FILES = 0;
+    public static final int DOWNLOAD_PAGES = 1;
+    public static final int CLOSE_INCOGNITO = 2;
+
+    private static final int SYSTEM_NOTIFICATION_TYPE_BOUNDARY = 3;
+
+    private static final String LAST_SHOWN_NOTIFICATION_TYPE_KEY =
+            "NotificationUmaTracker.LastShownNotificationType";
+
+    private static class LazyHolder {
+        private static final NotificationUmaTracker INSTANCE = new NotificationUmaTracker();
+    }
+
+    /** Cached objects. */
+    private final SharedPreferences mSharedPreferences;
+    private final NotificationManagerCompat mNotificationManager;
+
+    public static NotificationUmaTracker getInstance() {
+        return LazyHolder.INSTANCE;
+    }
+
+    private NotificationUmaTracker() {
+        mSharedPreferences = ContextUtils.getAppSharedPreferences();
+        mNotificationManager = NotificationManagerCompat.from(ContextUtils.getApplicationContext());
+    }
+
+    /**
+     * Logs {@link android.app.Notification} usage, categorized into {@link SystemNotificationType}
+     * types.  Splits the logs by the global enabled state of notifications and also logs the last
+     * notification shown prior to the global notifications state being disabled by the user.
+     * @param type The type of notification that was shown.
+     * @see SystemNotificationType
+     */
+    public void onNotificationShown(@SystemNotificationType int type) {
+        if (mNotificationManager.areNotificationsEnabled()) {
+            saveLastShownNotification(type);
+            recordHistogram("Mobile.SystemNotification.Shown", type);
+        } else {
+            logPotentialBlockedCause();
+            recordHistogram("Mobile.SystemNotification.Blocked", type);
+        }
+    }
+
+    private void saveLastShownNotification(@SystemNotificationType int type) {
+        mSharedPreferences.edit().putInt(LAST_SHOWN_NOTIFICATION_TYPE_KEY, type).apply();
+    }
+
+    private void logPotentialBlockedCause() {
+        int lastType = mSharedPreferences.getInt(LAST_SHOWN_NOTIFICATION_TYPE_KEY, -1);
+        if (lastType == -1) return;
+        mSharedPreferences.edit().remove(LAST_SHOWN_NOTIFICATION_TYPE_KEY).apply();
+
+        recordHistogram("Mobile.SystemNotification.BlockedAfterShown", lastType);
+    }
+
+    private static void recordHistogram(String name, @SystemNotificationType int type) {
+        if (!LibraryLoader.isInitialized()) return;
+        RecordHistogram.recordEnumeratedHistogram(name, type, SYSTEM_NOTIFICATION_TYPE_BOUNDARY);
+    }
+}
\ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/pageinfo/WebsiteSettingsPopup.java b/chrome/android/java/src/org/chromium/chrome/browser/pageinfo/WebsiteSettingsPopup.java
index f49786c4..7685ecd 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/pageinfo/WebsiteSettingsPopup.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/pageinfo/WebsiteSettingsPopup.java
@@ -68,7 +68,6 @@
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.util.UrlUtilities;
 import org.chromium.components.location.LocationUtils;
-import org.chromium.content.browser.ContentViewCore;
 import org.chromium.content_public.browser.WebContents;
 import org.chromium.content_public.browser.WebContentsObserver;
 import org.chromium.ui.base.DeviceFormFactor;
@@ -312,7 +311,7 @@
         if (offlinePageCreationDate != null) {
             mOfflinePageCreationDate = offlinePageCreationDate;
         }
-        mWindowAndroid = ContentViewCore.fromWebContents(mTab.getWebContents()).getWindowAndroid();
+        mWindowAndroid = mTab.getWebContents().getTopLevelNativeWindow();
         mContentPublisher = publisher;
 
         // Find the container and all it's important subviews.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/AndroidPaymentApp.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/AndroidPaymentApp.java
index 1e977e7..f7658449 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/payments/AndroidPaymentApp.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/AndroidPaymentApp.java
@@ -21,7 +21,6 @@
 import org.chromium.IsReadyToPayServiceCallback;
 import org.chromium.base.ThreadUtils;
 import org.chromium.chrome.R;
-import org.chromium.content.browser.ContentViewCore;
 import org.chromium.content_public.browser.WebContents;
 import org.chromium.payments.mojom.PaymentDetailsModifier;
 import org.chromium.payments.mojom.PaymentItem;
@@ -143,13 +142,7 @@
         if (mIsReadyToPayService != null) {
             sendIsReadyToPayIntentToPaymentApp();
         } else {
-            ContentViewCore contentView = ContentViewCore.fromWebContents(mWebContents);
-            if (contentView == null) {
-                respondToGetInstrumentsQuery(null);
-                return;
-            }
-
-            WindowAndroid window = contentView.getWindowAndroid();
+            WindowAndroid window = mWebContents.getTopLevelNativeWindow();
             if (window == null) {
                 respondToGetInstrumentsQuery(null);
                 return;
@@ -248,13 +241,7 @@
 
         mInstrumentDetailsCallback = callback;
 
-        ContentViewCore contentView = ContentViewCore.fromWebContents(mWebContents);
-        if (contentView == null) {
-            notifyError();
-            return;
-        }
-
-        WindowAndroid window = contentView.getWindowAndroid();
+        WindowAndroid window = mWebContents.getTopLevelNativeWindow();
         if (window == null) {
             notifyError();
             return;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/LocationSettings.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/LocationSettings.java
index 1cdf3ec..27bbad0 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/LocationSettings.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/LocationSettings.java
@@ -15,7 +15,6 @@
 import org.chromium.components.location.LocationSettingsDialogContext.LocationSettingsDialogContextEnum;
 import org.chromium.components.location.LocationSettingsDialogOutcome;
 import org.chromium.components.location.LocationUtils;
-import org.chromium.content.browser.ContentViewCore;
 import org.chromium.content_public.browser.WebContents;
 import org.chromium.ui.base.WindowAndroid;
 
@@ -55,7 +54,7 @@
 
     @CalledByNative
     private static boolean canPromptForAndroidLocationPermission(WebContents webContents) {
-        WindowAndroid windowAndroid = windowFromWebContents(webContents);
+        WindowAndroid windowAndroid = webContents.getTopLevelNativeWindow();
         if (windowAndroid == null) return false;
 
         return windowAndroid.canRequestPermission(Manifest.permission.ACCESS_FINE_LOCATION);
@@ -75,7 +74,7 @@
     private static void promptToEnableSystemLocationSetting(
             @LocationSettingsDialogContextEnum int promptContext, WebContents webContents,
             final long nativeCallback) {
-        WindowAndroid window = windowFromWebContents(webContents);
+        WindowAndroid window = webContents.getTopLevelNativeWindow();
         if (window == null) {
             nativeOnLocationSettingsDialogOutcome(
                     nativeCallback, LocationSettingsDialogOutcome.NO_PROMPT);
@@ -110,11 +109,5 @@
         sInstance = instance;
     }
 
-    private static WindowAndroid windowFromWebContents(WebContents webContents) {
-        ContentViewCore contentViewCore = ContentViewCore.fromWebContents(webContents);
-        if (contentViewCore == null) return null;
-        return contentViewCore.getWindowAndroid();
-    }
-
     private static native void nativeOnLocationSettingsDialogOutcome(long callback, int result);
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/SearchEngineAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/SearchEngineAdapter.java
index 846049f..751a190 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/SearchEngineAdapter.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/SearchEngineAdapter.java
@@ -82,6 +82,8 @@
 
     private boolean mHasLoadObserver;
 
+    private boolean mIsLocationPermissionChanged;
+
     /**
      * Construct a SearchEngineAdapter.
      * @param context The current context.
@@ -139,7 +141,13 @@
         }
 
         List<TemplateUrl> templateUrls = templateUrlService.getSearchEngines();
-        if (!didSearchEnginesChange(templateUrls)) return;
+        boolean forceRefresh = mIsLocationPermissionChanged;
+        mIsLocationPermissionChanged = false;
+        if (!didSearchEnginesChange(templateUrls)) {
+            if (forceRefresh) notifyDataSetChanged();
+            return;
+        }
+
         mPrepopulatedSearchEngines = new ArrayList<>();
         mRecentSearchEngines = new ArrayList<>();
 
@@ -424,6 +432,7 @@
     }
 
     private void onLocationLinkClicked() {
+        mIsLocationPermissionChanged = true;
         if (!LocationUtils.getInstance().isSystemLocationSettingEnabled()) {
             mContext.startActivity(LocationUtils.getInstance().getSystemLocationSettingsIntent());
         } else {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/TileGroup.java b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/TileGroup.java
index 8c8b078..672f2d35 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/TileGroup.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/TileGroup.java
@@ -23,6 +23,7 @@
 
 import org.chromium.base.ApiCompatibilityUtils;
 import org.chromium.base.Log;
+import org.chromium.base.VisibleForTesting;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.ChromeFeatureList;
 import org.chromium.chrome.browser.favicon.LargeIconBridge.LargeIconCallback;
@@ -240,34 +241,32 @@
     /**
      * Renders tile views in the given {@link TileGridLayout}, reusing existing tile views where
      * possible because view inflation and icon loading are slow.
-     * @param tileGridLayout The layout to render the tile views into.
+     * @param parent The layout to render the tile views into.
      * @param trackLoadTasks Whether to track load tasks.
      * @param condensed Whether to use a condensed layout.
      */
-    public void renderTileViews(
-            TileGridLayout tileGridLayout, boolean trackLoadTasks, boolean condensed) {
+    public void renderTileViews(ViewGroup parent, boolean trackLoadTasks, boolean condensed) {
         // Map the old tile views by url so they can be reused later.
         Map<String, TileView> oldTileViews = new HashMap<>();
-        int childCount = tileGridLayout.getChildCount();
+        int childCount = parent.getChildCount();
         for (int i = 0; i < childCount; i++) {
-            TileView tileView = (TileView) tileGridLayout.getChildAt(i);
+            TileView tileView = (TileView) parent.getChildAt(i);
             oldTileViews.put(tileView.getUrl(), tileView);
         }
 
         // Remove all views from the layout because even if they are reused later they'll have to be
         // added back in the correct order.
-        tileGridLayout.removeAllViews();
+        parent.removeAllViews();
 
         for (Tile tile : mTiles) {
             TileView tileView = oldTileViews.get(tile.getUrl());
             if (tileView == null) {
-                tileView = buildTileView(
-                        tile, tileGridLayout, trackLoadTasks, mTitleLinesCount, condensed);
+                tileView = buildTileView(tile, parent, trackLoadTasks, condensed);
             } else {
                 tileView.updateIfDataChanged(tile);
             }
 
-            tileGridLayout.addView(tileView);
+            parent.addView(tileView);
         }
     }
 
@@ -284,15 +283,15 @@
      * @param tile The tile that holds the data to populate the new tile view.
      * @param parentView The parent of the new tile view.
      * @param trackLoadTask Whether to track a load task.
-     * @param titleLines The number of text lines to use for each tile title.
      * @param condensed Whether to use a condensed layout.
      * @return The new tile view.
      */
-    private TileView buildTileView(Tile tile, ViewGroup parentView, boolean trackLoadTask,
-            int titleLines, boolean condensed) {
+    @VisibleForTesting
+    TileView buildTileView(
+            Tile tile, ViewGroup parentView, boolean trackLoadTask, boolean condensed) {
         TileView tileView = (TileView) LayoutInflater.from(parentView.getContext())
                                     .inflate(R.layout.tile_view, parentView, false);
-        tileView.initialize(tile, titleLines, condensed);
+        tileView.initialize(tile, mTitleLinesCount, condensed);
 
         // Note: It is important that the callbacks below don't keep a reference to the tile or
         // modify them as there is no guarantee that the same tile would be used to update the view.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webshare/ShareServiceImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/webshare/ShareServiceImpl.java
index 93b4a79..36745ee01 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/webshare/ShareServiceImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/webshare/ShareServiceImpl.java
@@ -10,7 +10,6 @@
 
 import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.chrome.browser.share.ShareHelper;
-import org.chromium.content.browser.ContentViewCore;
 import org.chromium.content_public.browser.WebContents;
 import org.chromium.mojo.system.MojoException;
 import org.chromium.ui.base.WindowAndroid;
@@ -82,10 +81,7 @@
     private static Activity activityFromWebContents(@Nullable WebContents webContents) {
         if (webContents == null) return null;
 
-        ContentViewCore contentViewCore = ContentViewCore.fromWebContents(webContents);
-        if (contentViewCore == null) return null;
-
-        WindowAndroid window = contentViewCore.getWindowAndroid();
+        WindowAndroid window = webContents.getTopLevelNativeWindow();
         if (window == null) return null;
 
         return window.getActivity().get();
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni
index 27084cd..91faecf 100644
--- a/chrome/android/java_sources.gni
+++ b/chrome/android/java_sources.gni
@@ -558,6 +558,7 @@
   "java/src/org/chromium/chrome/browser/notifications/NotificationJobService.java",
   "java/src/org/chromium/chrome/browser/notifications/NotificationService.java",
   "java/src/org/chromium/chrome/browser/notifications/NotificationSystemStatusUtil.java",
+  "java/src/org/chromium/chrome/browser/notifications/NotificationUmaTracker.java",
   "java/src/org/chromium/chrome/browser/notifications/StandardNotificationBuilder.java",
   "java/src/org/chromium/chrome/browser/notifications/WebApkNotificationClient.java",
   "java/src/org/chromium/chrome/browser/ntp/ChromeHomeNewTabPage.java",
@@ -1608,6 +1609,7 @@
   "junit/src/org/chromium/chrome/browser/physicalweb/UrlInfoTest.java",
   "junit/src/org/chromium/chrome/browser/snackbar/SnackbarCollectionUnitTest.java",
   "junit/src/org/chromium/chrome/browser/suggestions/TileGroupTest.java",
+  "junit/src/org/chromium/chrome/browser/suggestions/TileTest.java",
   "junit/src/org/chromium/chrome/browser/superviseduser/SupervisedUserContentProviderUnitTest.java",
   "junit/src/org/chromium/chrome/browser/tabstate/TabStateUnitTest.java",
   "junit/src/org/chromium/chrome/browser/webapps/WebappDataStorageTest.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadNotificationServiceTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadNotificationServiceTest.java
index 5ffac6e..a41d5a4 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadNotificationServiceTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadNotificationServiceTest.java
@@ -294,7 +294,7 @@
                 sharedPrefs, DownloadSharedPreferenceHelper.KEY_PENDING_DOWNLOAD_NOTIFICATIONS);
         assertEquals(2, entries.size());
 
-        service.notifyDownloadFailed(guid2, "failed");
+        service.notifyDownloadFailed(false, guid2, "failed");
         entries = DownloadManagerService.getStoredDownloadInfo(
                 sharedPrefs, DownloadSharedPreferenceHelper.KEY_PENDING_DOWNLOAD_NOTIFICATIONS);
         assertEquals(1, entries.size());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/download/MockDownloadNotificationService.java b/chrome/android/javatests/src/org/chromium/chrome/browser/download/MockDownloadNotificationService.java
index 28284a5..d547137 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/download/MockDownloadNotificationService.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/download/MockDownloadNotificationService.java
@@ -100,12 +100,13 @@
     }
 
     @Override
-    public void notifyDownloadFailed(final String downloadGuid, final String fileName) {
+    public void notifyDownloadFailed(
+            final boolean isOfflinePage, final String downloadGuid, final String fileName) {
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
                 MockDownloadNotificationService.super.notifyDownloadFailed(
-                        downloadGuid, fileName);
+                        isOfflinePage, downloadGuid, fileName);
             }
         });
     }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/suggestions/TileGroupTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/suggestions/TileGroupTest.java
index fc193a7..045a9a0 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/suggestions/TileGroupTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/suggestions/TileGroupTest.java
@@ -4,35 +4,54 @@
 
 package org.chromium.chrome.browser.suggestions;
 
-import static junit.framework.TestCase.assertNotNull;
-
-import static org.mockito.Mockito.inOrder;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
 
+import android.content.Context;
 import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.Color;
 import android.support.annotation.ColorRes;
 import android.support.annotation.DimenRes;
+import android.support.annotation.LayoutRes;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
 
+import org.hamcrest.CoreMatchers;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.mockito.InOrder;
+import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
 import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
+import org.robolectric.annotation.Implementation;
 import org.robolectric.annotation.Implements;
-import org.robolectric.annotation.RealObject;
 import org.robolectric.shadows.ShadowResources;
 
 import org.chromium.chrome.R;
-import org.chromium.chrome.browser.ChromeFeatureList;
 import org.chromium.chrome.browser.EnableFeatures;
+import org.chromium.chrome.browser.favicon.LargeIconBridge.LargeIconCallback;
 import org.chromium.chrome.browser.ntp.ContextMenuManager;
-import org.chromium.chrome.browser.ntp.cards.NodeParent;
-import org.chromium.chrome.browser.ntp.cards.SuggestionsSection;
+import org.chromium.chrome.browser.ntp.NTPTileSource;
 import org.chromium.chrome.browser.offlinepages.OfflinePageBridge;
 import org.chromium.testing.local.LocalRobolectricTestRunner;
 
@@ -40,7 +59,10 @@
  * Unit tests for {@link TileGroup}.
  */
 @RunWith(LocalRobolectricTestRunner.class)
-@Config(manifest = Config.NONE, shadows = {TileGroupTest.TileShadowResources.class})
+@Config(manifest = Config.NONE,
+        shadows = {TileGroupTest.TileShadowResources.class,
+                TileGroupTest.ShadowLayoutInflater.class})
+@EnableFeatures({})
 public class TileGroupTest {
     private static final int MAX_TILES_TO_FETCH = 4;
     private static final int TILE_TITLE_LINES = 1;
@@ -50,15 +72,7 @@
     public EnableFeatures.Processor mEnableFeatureProcessor = new EnableFeatures.Processor();
 
     @Mock
-    private SuggestionsSection.Delegate mDelegate;
-    @Mock
-    private NodeParent mParent;
-    @Mock
-    private SuggestionsUiDelegate mUiDelegate;
-    @Mock
     private TileGroup.Observer mTileGroupObserver;
-    @Mock
-    private OfflinePageBridge mOfflinePageBridge;
 
     private FakeTileGroupDelegate mTileGroupDelegate;
 
@@ -70,36 +84,243 @@
     }
 
     @Test
-    @EnableFeatures({ChromeFeatureList.NTP_OFFLINE_PAGES_FEATURE_NAME})
     public void testInitialiseWithEmptyTileList() {
-        TileGroup tileGroup = new TileGroup(RuntimeEnvironment.application, mUiDelegate,
-                mock(ContextMenuManager.class), mTileGroupDelegate, mTileGroupObserver,
-                mOfflinePageBridge, TILE_TITLE_LINES);
+        TileGroup tileGroup =
+                new TileGroup(RuntimeEnvironment.application, mock(SuggestionsUiDelegate.class),
+                        mock(ContextMenuManager.class), mTileGroupDelegate, mTileGroupObserver,
+                        mock(OfflinePageBridge.class), TILE_TITLE_LINES);
         tileGroup.startObserving(MAX_TILES_TO_FETCH);
         notifyTileUrlsAvailable();
 
+        // The TileGroup.Observer methods should be called even though no tiles are added, which is
+        // an initialisation but not real state change.
+        verify(mTileGroupObserver).onTileCountChanged();
+        verify(mTileGroupObserver).onLoadTaskCompleted();
+        verify(mTileGroupObserver).onTileDataChanged();
+    }
+
+    @Test
+    public void testInitialiseWithTileList() {
+        TileGroup tileGroup =
+                new TileGroup(RuntimeEnvironment.application, mock(SuggestionsUiDelegate.class),
+                        mock(ContextMenuManager.class), mTileGroupDelegate, mTileGroupObserver,
+                        mock(OfflinePageBridge.class), TILE_TITLE_LINES);
+        tileGroup.startObserving(MAX_TILES_TO_FETCH);
+
+        notifyTileUrlsAvailable(URLS);
+
         verify(mTileGroupObserver).onTileCountChanged();
         verify(mTileGroupObserver).onLoadTaskCompleted();
         verify(mTileGroupObserver).onTileDataChanged();
     }
 
     @Test
-    @EnableFeatures({ChromeFeatureList.NTP_OFFLINE_PAGES_FEATURE_NAME})
-    public void testInitialiseWithTileList() {
-        TileGroup tileGroup = new TileGroup(RuntimeEnvironment.application, mUiDelegate,
-                mock(ContextMenuManager.class), mTileGroupDelegate, mTileGroupObserver,
-                mOfflinePageBridge, TILE_TITLE_LINES);
+    public void testReceiveNewTilesWithoutChanges() {
+        TileGroup tileGroup =
+                new TileGroup(RuntimeEnvironment.application, mock(SuggestionsUiDelegate.class),
+                        mock(ContextMenuManager.class), mTileGroupDelegate, mTileGroupObserver,
+                        mock(OfflinePageBridge.class), TILE_TITLE_LINES);
         tileGroup.startObserving(MAX_TILES_TO_FETCH);
 
+        // First initialisation
         notifyTileUrlsAvailable(URLS);
+        reset(mTileGroupObserver);
 
-        InOrder inOrder = inOrder(mTileGroupObserver);
-        inOrder.verify(mTileGroupObserver).onTileCountChanged();
-        inOrder.verify(mTileGroupObserver).onLoadTaskCompleted();
-        inOrder.verify(mTileGroupObserver).onTileDataChanged();
-        inOrder.verifyNoMoreInteractions();
+        // Notify the same thing. No changes so|mTileGroupObserver| should not be notified.
+        notifyTileUrlsAvailable(URLS);
+        verifyNoMoreInteractions(mTileGroupObserver);
     }
 
+    @Test
+    public void testReceiveNewTilesWithDataChanges() {
+        TileGroup tileGroup =
+                new TileGroup(RuntimeEnvironment.application, mock(SuggestionsUiDelegate.class),
+                        mock(ContextMenuManager.class), mTileGroupDelegate, mTileGroupObserver,
+                        mock(OfflinePageBridge.class), TILE_TITLE_LINES);
+        tileGroup.startObserving(MAX_TILES_TO_FETCH);
+
+        // First initialisation
+        notifyTileUrlsAvailable(URLS);
+        reset(mTileGroupObserver);
+
+        // Notify the about different URLs, but the same number. #onTileCountChanged() should not be
+        // called.
+        notifyTileUrlsAvailable("foo", "bar");
+        verify(mTileGroupObserver, never()).onTileCountChanged(); // Tile count is still 2
+        verify(mTileGroupObserver, never()).onLoadTaskCompleted(); // No load task the second time.
+        verify(mTileGroupObserver).onTileDataChanged(); // Data DID change.
+    }
+
+    @Test
+    public void testReceiveNewTilesWithCountChanges() {
+        TileGroup tileGroup =
+                new TileGroup(RuntimeEnvironment.application, mock(SuggestionsUiDelegate.class),
+                        mock(ContextMenuManager.class), mTileGroupDelegate, mTileGroupObserver,
+                        mock(OfflinePageBridge.class), TILE_TITLE_LINES);
+        tileGroup.startObserving(MAX_TILES_TO_FETCH);
+
+        // First initialisation
+        notifyTileUrlsAvailable(URLS);
+        reset(mTileGroupObserver);
+
+        notifyTileUrlsAvailable(URLS[0]);
+        verify(mTileGroupObserver).onTileCountChanged(); // Tile count DID change.
+        verify(mTileGroupObserver, never()).onLoadTaskCompleted(); // No load task the second time.
+        verify(mTileGroupObserver).onTileDataChanged(); // Data DID change.
+    }
+
+    @Test
+    public void testRenderTileView() {
+        TileGroup tileGroup =
+                new TileGroup(RuntimeEnvironment.application, mock(SuggestionsUiDelegate.class),
+                        mock(ContextMenuManager.class), mTileGroupDelegate, mTileGroupObserver,
+                        mock(OfflinePageBridge.class), TILE_TITLE_LINES);
+        tileGroup.startObserving(MAX_TILES_TO_FETCH);
+        ViewGroup layout = new FrameLayout(RuntimeEnvironment.application, null);
+
+        // Initialise the internal list of tiles
+        notifyTileUrlsAvailable(URLS);
+
+        // Render them to the layout.
+        tileGroup.renderTileViews(layout, false, false);
+        assertThat(layout.getChildCount(), is(2));
+        assertThat(((TileView) layout.getChildAt(0)).getUrl(), is(URLS[0]));
+        assertThat(((TileView) layout.getChildAt(1)).getUrl(), is(URLS[1]));
+    }
+
+    @Test
+    public void testRenderTileViewReplacing() {
+        TileGroup tileGroup =
+                new TileGroup(RuntimeEnvironment.application, mock(SuggestionsUiDelegate.class),
+                        mock(ContextMenuManager.class), mTileGroupDelegate, mTileGroupObserver,
+                        mock(OfflinePageBridge.class), TILE_TITLE_LINES);
+        tileGroup.startObserving(MAX_TILES_TO_FETCH);
+        notifyTileUrlsAvailable(URLS);
+
+        // Initialise the layout with views whose URLs don't match the ones of the new tiles.
+        ViewGroup layout = new FrameLayout(RuntimeEnvironment.application, null);
+        TileView view1 = mock(TileView.class);
+        layout.addView(view1);
+
+        TileView view2 = mock(TileView.class);
+        layout.addView(view2);
+
+        // The tiles should be updated, the old ones removed.
+        tileGroup.renderTileViews(layout, false, false);
+        assertThat(layout.getChildCount(), is(2));
+        assertThat(layout.indexOfChild(view1), is(-1));
+        assertThat(layout.indexOfChild(view2), is(-1));
+        verify(view1, never()).updateIfDataChanged(tileGroup.getTiles()[0]);
+        verify(view2, never()).updateIfDataChanged(tileGroup.getTiles()[1]);
+    }
+
+    @Test
+    public void testRenderTileViewRecycling() {
+        TileGroup tileGroup =
+                new TileGroup(RuntimeEnvironment.application, mock(SuggestionsUiDelegate.class),
+                        mock(ContextMenuManager.class), mTileGroupDelegate, mTileGroupObserver,
+                        mock(OfflinePageBridge.class), TILE_TITLE_LINES);
+        tileGroup.startObserving(MAX_TILES_TO_FETCH);
+        notifyTileUrlsAvailable(URLS);
+
+        // Initialise the layout with views whose URLs match the ones of the new tiles.
+        ViewGroup layout = new FrameLayout(RuntimeEnvironment.application, null);
+        TileView view1 = mock(TileView.class);
+        when(view1.getUrl()).thenReturn(URLS[0]);
+        layout.addView(view1);
+
+        TileView view2 = mock(TileView.class);
+        when(view2.getUrl()).thenReturn(URLS[1]);
+        layout.addView(view2);
+
+        // The tiles should be updated, the old ones reused.
+        tileGroup.renderTileViews(layout, false, false);
+        assertThat(layout.getChildCount(), is(2));
+        assertThat(layout.getChildAt(0), CoreMatchers.<View>is(view1));
+        assertThat(layout.getChildAt(1), CoreMatchers.<View>is(view2));
+        verify(view1).updateIfDataChanged(tileGroup.getTiles()[0]);
+        verify(view2).updateIfDataChanged(tileGroup.getTiles()[1]);
+    }
+
+    @Test
+    public void testIconLoading() {
+        SuggestionsUiDelegate uiDelegate = mock(SuggestionsUiDelegate.class);
+        TileGroup tileGroup = new TileGroup(RuntimeEnvironment.application, uiDelegate,
+                mock(ContextMenuManager.class), mTileGroupDelegate, mTileGroupObserver,
+                mock(OfflinePageBridge.class), TILE_TITLE_LINES);
+        tileGroup.startObserving(MAX_TILES_TO_FETCH);
+        notifyTileUrlsAvailable(URLS); // Initialise the internal state to include the test tile.
+        reset(mTileGroupObserver);
+        Tile tile = tileGroup.getTiles()[0];
+
+        ViewGroup layout = new FrameLayout(RuntimeEnvironment.application, null);
+        tileGroup.buildTileView(tile, layout, /* trackLoadTask = */ true, /* condensed = */ false);
+
+        verify(mTileGroupObserver).onLoadTaskAdded();
+
+        ArgumentCaptor<LargeIconCallback> captor = ArgumentCaptor.forClass(LargeIconCallback.class);
+        verify(uiDelegate).getLargeIconForUrl(any(String.class), anyInt(), captor.capture());
+        for (LargeIconCallback cb : captor.getAllValues()) {
+            cb.onLargeIconAvailable(mock(Bitmap.class), Color.BLACK, /* isColorDefault = */ false);
+        }
+
+        verify(mTileGroupObserver).onLoadTaskCompleted();
+        verify(mTileGroupObserver).onTileIconChanged(tile);
+    }
+
+    @Test
+    public void testIconLoadingNoTask() {
+        SuggestionsUiDelegate uiDelegate = mock(SuggestionsUiDelegate.class);
+        TileGroup tileGroup = new TileGroup(RuntimeEnvironment.application, uiDelegate,
+                mock(ContextMenuManager.class), mTileGroupDelegate, mTileGroupObserver,
+                mock(OfflinePageBridge.class), TILE_TITLE_LINES);
+        tileGroup.startObserving(MAX_TILES_TO_FETCH);
+        notifyTileUrlsAvailable(URLS); // Initialise the internal state to include the test tile.
+        reset(mTileGroupObserver);
+        Tile tile = tileGroup.getTiles()[0];
+
+        ViewGroup layout = new FrameLayout(RuntimeEnvironment.application, null);
+        tileGroup.buildTileView(tile, layout, /* trackLoadTask = */ false, /* condensed = */ false);
+
+        verify(mTileGroupObserver, never()).onLoadTaskAdded();
+
+        ArgumentCaptor<LargeIconCallback> captor = ArgumentCaptor.forClass(LargeIconCallback.class);
+        verify(uiDelegate).getLargeIconForUrl(any(String.class), anyInt(), captor.capture());
+        for (LargeIconCallback cb : captor.getAllValues()) {
+            cb.onLargeIconAvailable(mock(Bitmap.class), Color.BLACK, /* isColorDefault = */ false);
+        }
+
+        verify(mTileGroupObserver, never()).onLoadTaskCompleted();
+        verify(mTileGroupObserver).onTileIconChanged(tile);
+    }
+
+    @Test
+    public void testIconLoadingWhenTileNotRegistered() {
+        SuggestionsUiDelegate uiDelegate = mock(SuggestionsUiDelegate.class);
+        TileGroup tileGroup = new TileGroup(RuntimeEnvironment.application, uiDelegate,
+                mock(ContextMenuManager.class), mTileGroupDelegate, mTileGroupObserver,
+                mock(OfflinePageBridge.class), TILE_TITLE_LINES);
+        tileGroup.startObserving(MAX_TILES_TO_FETCH);
+        reset(mTileGroupObserver);
+        Tile tile = new Tile("title", URLS[0], "", 0, NTPTileSource.POPULAR);
+
+        ViewGroup layout = new FrameLayout(RuntimeEnvironment.application, null);
+        tileGroup.buildTileView(tile, layout, /* trackLoadTask = */ true, /* condensed = */ false);
+        verify(mTileGroupObserver).onLoadTaskAdded();
+
+        ArgumentCaptor<LargeIconCallback> captor = ArgumentCaptor.forClass(LargeIconCallback.class);
+        verify(uiDelegate).getLargeIconForUrl(any(String.class), anyInt(), captor.capture());
+        captor.getValue().onLargeIconAvailable(mock(Bitmap.class), Color.BLACK, false);
+
+        verify(mTileGroupObserver).onLoadTaskCompleted();
+        verify(mTileGroupObserver, never()).onTileIconChanged(tile);
+    }
+
+    /**
+     * Notifies the tile group of new tiles created from the provided URLs. Requires
+     * {@link TileGroup#startObserving(int)} to have been called on the tile group under test.
+     * @see TileGroup#onMostVisitedURLsAvailable(String[], String[], String[], int[])
+     */
     private void notifyTileUrlsAvailable(String... urls) {
         assertNotNull("MostVisitedObserver has not been registered.", mTileGroupDelegate.mObserver);
 
@@ -111,6 +332,25 @@
                 titles, urls, whitelistIconPaths, sources);
     }
 
+    /**
+     * Creates a mocked {@link TileView} that will return the URL of the tile it has been
+     * initialised with.
+     */
+    private static TileView createMockTileView() {
+        final TileView tileView = mock(TileView.class);
+        doAnswer(new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                Tile tile = invocation.getArgument(0);
+                when(tileView.getUrl()).thenReturn(tile.getUrl());
+                return null;
+            }
+        })
+                .when(tileView)
+                .initialize(any(Tile.class), anyInt(), anyBoolean());
+        return tileView;
+    }
+
     private class FakeTileGroupDelegate implements TileGroup.Delegate {
         public MostVisitedSites.Observer mObserver;
 
@@ -140,17 +380,38 @@
      */
     @Implements(Resources.class)
     public static class TileShadowResources extends ShadowResources {
-        @RealObject
-        private Resources mRealResources;
+        @Implementation
         public int getDimensionPixelSize(@DimenRes int id) {
-            if (id == R.dimen.tile_view_icon_size) return 2;
-            return mRealResources.getDimensionPixelSize(id);
+            if (id == R.dimen.tile_view_icon_size) return 48;
+
+            throw new IllegalArgumentException();
         }
 
-        @SuppressWarnings("deprecation")
+        @Implementation
         public int getColor(@ColorRes int id) {
-            if (id == R.color.default_favicon_background_color) return 2;
-            return mRealResources.getColor(id);
+            if (id == R.color.default_favicon_background_color) return Color.BLACK;
+
+            throw new IllegalArgumentException();
+        }
+    }
+
+    /** Intercepts calls to inflate views to replace them with mocks. */
+    @Implements(LayoutInflater.class)
+    public static class ShadowLayoutInflater {
+        @Implementation
+        public static LayoutInflater from(Context context) {
+            LayoutInflater layoutInflater = mock(LayoutInflater.class);
+            when(layoutInflater.inflate(anyInt(), any(ViewGroup.class), anyBoolean()))
+                    .thenAnswer(new Answer<View>() {
+                        @Override
+                        public View answer(InvocationOnMock invocation) throws Throwable {
+                            @LayoutRes
+                            int layoutId = invocation.getArgument(0);
+                            if (layoutId != R.layout.tile_view) fail("Unexpected resource id.");
+                            return createMockTileView();
+                        }
+                    });
+            return layoutInflater;
         }
     }
 }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/suggestions/TileTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/suggestions/TileTest.java
new file mode 100644
index 0000000..08ce230
--- /dev/null
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/suggestions/TileTest.java
@@ -0,0 +1,114 @@
+// Copyright 2017 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.
+
+package org.chromium.chrome.browser.suggestions;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.GradientDrawable;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+
+import org.chromium.chrome.browser.ntp.MostVisitedTileType;
+import org.chromium.chrome.browser.ntp.NTPTileSource;
+import org.chromium.testing.local.LocalRobolectricTestRunner;
+
+/**
+ * Unit tests for {@link Tile}.
+ */
+@RunWith(LocalRobolectricTestRunner.class)
+@Config(manifest = Config.NONE)
+public class TileTest {
+    private static final String[] URLS = {"https://www.google.com", "https://tellmedadjokes.com"};
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    @Test
+    public void testImportDataWithNewTitle() {
+        Tile tile = new Tile("title", URLS[0], "", 0, NTPTileSource.TOP_SITES);
+        Tile oldTile = new Tile("oldTitle", URLS[0], "", 0, NTPTileSource.TOP_SITES);
+
+        // importData should report the change, and the new tile should keep its own data.
+        assertTrue(tile.importData(oldTile));
+        assertThat(tile.getTitle(), equalTo("title"));
+    }
+
+    @Test(expected = AssertionError.class)
+    public void testImportDataWithNewUrl() {
+        Tile tile = new Tile("title", URLS[0], "", 0, NTPTileSource.TOP_SITES);
+        Tile oldTile = new Tile("title", URLS[1], "", 0, NTPTileSource.TOP_SITES);
+
+        // Importing from a tile associated to a different URL should crash, as bug detection
+        // measure.
+        tile.importData(oldTile);
+    }
+
+    @Test
+    public void testImportDataWithNewWhitelistIconPath() {
+        Tile tile = new Tile("title", URLS[0], "", 0, NTPTileSource.TOP_SITES);
+        Tile oldTile = new Tile("title", URLS[0], "foobar", 0, NTPTileSource.TOP_SITES);
+
+        // importData should report the change, and the new tile should keep its own data.
+        assertTrue(tile.importData(oldTile));
+        assertThat(tile.getWhitelistIconPath(), equalTo(""));
+    }
+
+    @Test
+    public void testImportDataWithNewIndex() {
+        Tile tile = new Tile("title", URLS[0], "", 0, NTPTileSource.TOP_SITES);
+        Tile oldTile = new Tile("title", URLS[0], "", 1, NTPTileSource.TOP_SITES);
+
+        // importData should report the change, and the new tile should keep its own data.
+        assertTrue(tile.importData(oldTile));
+        assertThat(tile.getIndex(), equalTo(0));
+    }
+
+    @Test
+    public void testImportDataWithNewSource() {
+        Tile tile = new Tile("title", URLS[0], "", 0, NTPTileSource.TOP_SITES);
+        Tile oldTile = new Tile("title", URLS[0], "", 0, NTPTileSource.POPULAR);
+
+        // importData should not report the change since it has no visible impact. The new tile
+        // still keeps its own data.
+        assertFalse(tile.importData(oldTile));
+        assertThat(tile.getSource(), equalTo(NTPTileSource.TOP_SITES));
+    }
+
+    @Test
+    public void testTileImportWithSameData() {
+        Tile tile = new Tile("title", URLS[0], "", 0, NTPTileSource.TOP_SITES);
+        Tile oldTile = new Tile("title", URLS[0], "", 0, NTPTileSource.TOP_SITES);
+
+        // No change should be reported
+        assertFalse(tile.importData(oldTile));
+    }
+
+    @Test
+    public void testTileImportWithTransientData() {
+        Tile tile = new Tile("title", URLS[0], "", 0, NTPTileSource.TOP_SITES);
+
+        Drawable dummyDrawable = new GradientDrawable();
+        Tile oldTile = new Tile("title", URLS[0], "", 0, NTPTileSource.TOP_SITES);
+        oldTile.setOfflinePageOfflineId(42L);
+        oldTile.setIcon(dummyDrawable);
+        oldTile.setType(MostVisitedTileType.ICON_REAL);
+
+        // Old transient data should be copied over to the new tile without flagging the change.
+        assertFalse(tile.importData(oldTile));
+        assertThat(tile.getOfflinePageOfflineId(), equalTo(42L));
+        assertThat(tile.getIcon(), equalTo(dummyDrawable));
+        assertThat(tile.getType(), equalTo(MostVisitedTileType.ICON_REAL));
+    }
+}
diff --git a/chrome/app/chrome_command_ids.h b/chrome/app/chrome_command_ids.h
index 61f2197..b7d3732 100644
--- a/chrome/app/chrome_command_ids.h
+++ b/chrome/app/chrome_command_ids.h
@@ -29,10 +29,6 @@
 #define IDC_RELOAD_BYPASSING_CACHE      33007
 #define IDC_LOAD_NEW_TAB_PAGE           33008
 #define IDC_RELOAD_CLEARING_CACHE       33009
-// Temporary commands to capture the old Back/Forward shortcuts and tell users
-// the new shortcut. May also trigger Back/Forward action if the
-// BackspaceGoesBack field trial is enabled.
-// TODO(mgiuca): Remove these in M54 (https://crbug.com/610039).
 #define IDC_BACKSPACE_BACK              33010
 #define IDC_BACKSPACE_FORWARD           33011
 
diff --git a/chrome/app/main_dll_loader_win.h b/chrome/app/main_dll_loader_win.h
index a2a9d64..be48fff 100644
--- a/chrome/app/main_dll_loader_win.h
+++ b/chrome/app/main_dll_loader_win.h
@@ -20,7 +20,7 @@
 
 // Implements the common aspects of loading the main dll for both chrome and
 // chromium scenarios, which are in charge of implementing two abstract
-// methods: GetRegistryPath() and OnBeforeLaunch().
+// methods: OnBeforeLaunch() and OnBeforeExit().
 class MainDllLoader {
  public:
   MainDllLoader();
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 8cb8591..3af8f5c 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -187,6 +187,10 @@
     "browsing_data/local_data_container.h",
     "browsing_data/media_licenses_counter.cc",
     "browsing_data/media_licenses_counter.h",
+    "browsing_data/site_data_counter.cc",
+    "browsing_data/site_data_counter.h",
+    "browsing_data/site_data_counting_helper.cc",
+    "browsing_data/site_data_counting_helper.h",
     "browsing_data/site_data_size_collector.cc",
     "browsing_data/site_data_size_collector.h",
     "budget_service/budget_database.cc",
diff --git a/chrome/browser/android/offline_pages/background_loader_offliner.cc b/chrome/browser/android/offline_pages/background_loader_offliner.cc
index 0b5478e..bfc55e3 100644
--- a/chrome/browser/android/offline_pages/background_loader_offliner.cc
+++ b/chrome/browser/android/offline_pages/background_loader_offliner.cc
@@ -117,18 +117,24 @@
   return true;
 }
 
-void BackgroundLoaderOffliner::Cancel() {
+void BackgroundLoaderOffliner::Cancel(const CancelCallback& callback) {
   // TODO(chili): We are not able to cancel a pending
-  // OfflinePageModel::SavePage() operation. We just ignore the callback.
-  if (!pending_request_)
-    return;
-
-  if (save_state_ != NONE) {
-    save_state_ = DELETE_AFTER_SAVE;
+  // OfflinePageModel::SavePage() operation. We will notify caller that
+  // cancel completed once the SavePage operation returns.
+  if (!pending_request_) {
+    callback.Run(0LL);
     return;
   }
 
+  if (save_state_ != NONE) {
+    save_state_ = DELETE_AFTER_SAVE;
+    cancel_callback_ = callback;
+    return;
+  }
+
+  int64_t request_id = pending_request_->request_id();
   ResetState();
+  callback.Run(request_id);
 }
 
 bool BackgroundLoaderOffliner::HandleTimeout(const SavePageRequest& request) {
@@ -304,6 +310,7 @@
 
   if (save_state_ == DELETE_AFTER_SAVE) {
     save_state_ = NONE;
+    cancel_callback_.Run(request.request_id());
     return;
   }
 
@@ -338,9 +345,21 @@
           base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES) {
     DVLOG(1) << "App became active, canceling current offlining request";
     SavePageRequest* request = pending_request_.get();
-    Cancel();
-    completion_callback_.Run(*request, RequestStatus::FOREGROUND_CANCELED);
+    // This works because Bind will make a copy of request, and we
+    // should not have to worry about reset being called before cancel callback.
+    Cancel(base::Bind(
+        &BackgroundLoaderOffliner::HandleApplicationStateChangeCancel,
+        weak_ptr_factory_.GetWeakPtr(), *request));
   }
 }
 
+void BackgroundLoaderOffliner::HandleApplicationStateChangeCancel(
+    const SavePageRequest& request,
+    int64_t offline_id) {
+  // If for some reason the request was reset during while waiting for callback
+  // ignore the completion callback.
+  if (pending_request_ && pending_request_->request_id() != offline_id)
+    return;
+  completion_callback_.Run(request, RequestStatus::FOREGROUND_CANCELED);
+}
 }  // namespace offline_pages
diff --git a/chrome/browser/android/offline_pages/background_loader_offliner.h b/chrome/browser/android/offline_pages/background_loader_offliner.h
index 7be71548..04572de 100644
--- a/chrome/browser/android/offline_pages/background_loader_offliner.h
+++ b/chrome/browser/android/offline_pages/background_loader_offliner.h
@@ -37,7 +37,7 @@
   // Offliner implementation.
   bool LoadAndSave(const SavePageRequest& request,
                    const CompletionCallback& callback) override;
-  void Cancel() override;
+  void Cancel(const CancelCallback& callback) override;
   bool HandleTimeout(const SavePageRequest& request) override;
 
   // WebContentsObserver implementation.
@@ -68,6 +68,8 @@
   // Called when application state has changed.
   void OnApplicationStateChange(
       base::android::ApplicationState application_state);
+  void HandleApplicationStateChangeCancel(const SavePageRequest& request,
+                                          int64_t offline_id);
 
   std::unique_ptr<background_loader::BackgroundLoaderContents> loader_;
   // Not owned.
@@ -82,6 +84,7 @@
   std::unique_ptr<base::android::ApplicationStatusListener> app_listener_;
   // Whether we are on a low-end device.
   bool is_low_end_device_;
+
   // Save state.
   SaveState save_state_;
   // Page load state.
@@ -89,6 +92,9 @@
   // Seconds to delay before taking snapshot.
   long page_delay_ms_;
 
+  // Callback for cancel.
+  CancelCallback cancel_callback_;
+
   base::WeakPtrFactory<BackgroundLoaderOffliner> weak_ptr_factory_;
   DISALLOW_COPY_AND_ASSIGN(BackgroundLoaderOffliner);
 };
diff --git a/chrome/browser/android/offline_pages/background_loader_offliner_unittest.cc b/chrome/browser/android/offline_pages/background_loader_offliner_unittest.cc
index fdc2061..0b4e691 100644
--- a/chrome/browser/android/offline_pages/background_loader_offliner_unittest.cc
+++ b/chrome/browser/android/offline_pages/background_loader_offliner_unittest.cc
@@ -130,9 +130,14 @@
     return base::Bind(&BackgroundLoaderOfflinerTest::OnCompletion,
                       base::Unretained(this));
   }
+  Offliner::CancelCallback const cancel_callback() {
+    return base::Bind(&BackgroundLoaderOfflinerTest::OnCancel,
+                      base::Unretained(this));
+  }
   Profile* profile() { return &profile_; }
   bool completion_callback_called() { return completion_callback_called_; }
   Offliner::RequestStatus request_status() { return request_status_; }
+  bool cancel_callback_called() { return cancel_callback_called_; }
   bool SaveInProgress() const { return model_->mock_saving(); }
   MockOfflinePageModel* model() const { return model_; }
   const base::HistogramTester& histograms() const { return histogram_tester_; }
@@ -148,11 +153,13 @@
  private:
   void OnCompletion(const SavePageRequest& request,
                     Offliner::RequestStatus status);
+  void OnCancel(int64_t offline_id);
   content::TestBrowserThreadBundle thread_bundle_;
   TestingProfile profile_;
   std::unique_ptr<TestBackgroundLoaderOffliner> offliner_;
   MockOfflinePageModel* model_;
   bool completion_callback_called_;
+  bool cancel_callback_called_;
   Offliner::RequestStatus request_status_;
   base::HistogramTester histogram_tester_;
 
@@ -162,6 +169,7 @@
 BackgroundLoaderOfflinerTest::BackgroundLoaderOfflinerTest()
     : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
       completion_callback_called_(false),
+      cancel_callback_called_(false),
       request_status_(Offliner::RequestStatus::UNKNOWN) {}
 
 BackgroundLoaderOfflinerTest::~BackgroundLoaderOfflinerTest() {}
@@ -180,6 +188,11 @@
   request_status_ = status;
 }
 
+void BackgroundLoaderOfflinerTest::OnCancel(int64_t offline_id) {
+  DCHECK(!cancel_callback_called_);
+  cancel_callback_called_ = true;
+}
+
 TEST_F(BackgroundLoaderOfflinerTest,
        LoadAndSaveBlockThirdPartyCookiesForCustomTabs) {
   base::Time creation_time = base::Time::Now();
@@ -249,7 +262,9 @@
   SavePageRequest request(kRequestId, kHttpUrl, kClientId, creation_time,
                           kUserRequested);
   EXPECT_TRUE(offliner()->LoadAndSave(request, callback()));
-  offliner()->Cancel();
+  offliner()->Cancel(cancel_callback());
+  PumpLoop();
+  EXPECT_TRUE(cancel_callback_called());
   EXPECT_FALSE(offliner()->is_loading());  // Offliner reset.
 }
 
@@ -260,11 +275,13 @@
   EXPECT_TRUE(offliner()->LoadAndSave(request, callback()));
   CompleteLoading();
   PumpLoop();
-  offliner()->Cancel();
+  offliner()->Cancel(cancel_callback());
+  PumpLoop();
 
   // Subsequent save callback cause no crash.
   model()->CompleteSavingAsArchiveCreationFailed();
   PumpLoop();
+  EXPECT_TRUE(cancel_callback_called());
   EXPECT_FALSE(completion_callback_called());
   EXPECT_FALSE(SaveInProgress());
   EXPECT_FALSE(offliner()->is_loading());  // Offliner reset.
diff --git a/chrome/browser/android/offline_pages/prerendering_offliner.cc b/chrome/browser/android/offline_pages/prerendering_offliner.cc
index d85f3cbf..89707e1 100644
--- a/chrome/browser/android/offline_pages/prerendering_offliner.cc
+++ b/chrome/browser/android/offline_pages/prerendering_offliner.cc
@@ -210,13 +210,16 @@
   return accepted;
 }
 
-void PrerenderingOffliner::Cancel() {
+void PrerenderingOffliner::Cancel(const CancelCallback& callback) {
+  int64_t request_id = 0LL;
   if (pending_request_) {
+    request_id = pending_request_->request_id();
     pending_request_.reset(nullptr);
     app_listener_.reset(nullptr);
     GetOrCreateLoader()->StopLoading();
     // TODO(dougarnett): Consider ability to cancel SavePage request.
   }
+  callback.Run(request_id);
 }
 
 bool PrerenderingOffliner::HandleTimeout(const SavePageRequest& request) {
@@ -271,10 +274,20 @@
           base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES) {
     DVLOG(1) << "App became active, canceling current offlining request";
     SavePageRequest* request = pending_request_.get();
-    Cancel();
-    completion_callback_.Run(*request,
-                             Offliner::RequestStatus::FOREGROUND_CANCELED);
+    // This works because Bind will make a copy of request, and we
+    // should not have to worry about reset being called before cancel callback.
+    Cancel(base::Bind(&PrerenderingOffliner::HandleApplicationStateChangeCancel,
+                      weak_ptr_factory_.GetWeakPtr(), *request));
   }
 }
 
+void PrerenderingOffliner::HandleApplicationStateChangeCancel(
+    const SavePageRequest& request,
+    int64_t offline_id) {
+  // This shouldn't be immediate, but account for case where request was reset
+  // while waiting for callback.
+  if (pending_request_ && pending_request_->request_id() != offline_id)
+    return;
+  completion_callback_.Run(request, RequestStatus::FOREGROUND_CANCELED);
+}
 }  // namespace offline_pages
diff --git a/chrome/browser/android/offline_pages/prerendering_offliner.h b/chrome/browser/android/offline_pages/prerendering_offliner.h
index 9b1104c..935d3019 100644
--- a/chrome/browser/android/offline_pages/prerendering_offliner.h
+++ b/chrome/browser/android/offline_pages/prerendering_offliner.h
@@ -36,7 +36,7 @@
   // Offliner implementation.
   bool LoadAndSave(const SavePageRequest& request,
                    const CompletionCallback& callback) override;
-  void Cancel() override;
+  void Cancel(const CancelCallback& callback) override;
   bool HandleTimeout(const SavePageRequest& request) override;
 
   // Allows a loader to be injected for testing. This may only be done once
@@ -76,6 +76,8 @@
   // Listener function for changes to application background/foreground state.
   void OnApplicationStateChange(
       base::android::ApplicationState application_state);
+  void HandleApplicationStateChangeCancel(const SavePageRequest& request,
+                                          int64_t offline_id);
 
   // Not owned.
   content::BrowserContext* browser_context_;
diff --git a/chrome/browser/android/offline_pages/prerendering_offliner_unittest.cc b/chrome/browser/android/offline_pages/prerendering_offliner_unittest.cc
index 8cfd398d..2d0a21b 100644
--- a/chrome/browser/android/offline_pages/prerendering_offliner_unittest.cc
+++ b/chrome/browser/android/offline_pages/prerendering_offliner_unittest.cc
@@ -172,6 +172,10 @@
     return base::Bind(&PrerenderingOfflinerTest::OnCompletion,
                       base::Unretained(this));
   }
+  Offliner::CancelCallback const cancel_callback() {
+    return base::Bind(&PrerenderingOfflinerTest::OnCancel,
+                      base::Unretained(this));
+  }
 
   bool SaveInProgress() const { return model_->mock_saving(); }
   MockPrerenderingLoader* loader() { return loader_; }
@@ -179,10 +183,12 @@
   bool completion_callback_called() { return completion_callback_called_; }
   Offliner::RequestStatus request_status() { return request_status_; }
   OfflinerPolicy* policy() { return policy_; }
+  bool cancel_callback_called() { return cancel_callback_called_; }
 
  private:
   void OnCompletion(const SavePageRequest& request,
                     Offliner::RequestStatus status);
+  void OnCancel(int64_t offline_id);
 
   content::TestBrowserThreadBundle thread_bundle_;
   TestingProfile profile_;
@@ -191,6 +197,7 @@
   MockPrerenderingLoader* loader_;
   MockOfflinePageModel* model_;
   bool completion_callback_called_;
+  bool cancel_callback_called_;
   Offliner::RequestStatus request_status_;
   OfflinerPolicy* policy_;
 
@@ -200,6 +207,7 @@
 PrerenderingOfflinerTest::PrerenderingOfflinerTest()
     : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
       completion_callback_called_(false),
+      cancel_callback_called_(false),
       request_status_(Offliner::RequestStatus::UNKNOWN) {}
 
 PrerenderingOfflinerTest::~PrerenderingOfflinerTest() {}
@@ -221,6 +229,11 @@
   request_status_ = status;
 }
 
+void PrerenderingOfflinerTest::OnCancel(int64_t offline_id) {
+  DCHECK(!cancel_callback_called_);
+  cancel_callback_called_ = true;
+}
+
 TEST_F(PrerenderingOfflinerTest, LoadAndSaveBadUrl) {
   base::Time creation_time = base::Time::Now();
   SavePageRequest request(
@@ -285,7 +298,9 @@
   EXPECT_TRUE(offliner()->LoadAndSave(request, callback()));
   EXPECT_FALSE(loader()->IsIdle());
 
-  offliner()->Cancel();
+  offliner()->Cancel(cancel_callback());
+  PumpLoop();
+  EXPECT_TRUE(cancel_callback_called());
   EXPECT_TRUE(loader()->IsIdle());
 }
 
@@ -303,9 +318,10 @@
   EXPECT_TRUE(loader()->IsLoaded());
   EXPECT_TRUE(SaveInProgress());
 
-  offliner()->Cancel();
+  offliner()->Cancel(cancel_callback());
   PumpLoop();
   EXPECT_FALSE(completion_callback_called());
+  EXPECT_TRUE(cancel_callback_called());
   EXPECT_FALSE(loader()->IsLoaded());
   // Note: save still in progress since it does not support canceling.
   EXPECT_TRUE(SaveInProgress());
diff --git a/chrome/browser/android/shortcut_helper.cc b/chrome/browser/android/shortcut_helper.cc
index 81995e8..9a0674f4 100644
--- a/chrome/browser/android/shortcut_helper.cc
+++ b/chrome/browser/android/shortcut_helper.cc
@@ -338,11 +338,22 @@
 void OnWebApksRetrieved(JNIEnv* env,
                         const JavaParamRef<jclass>& clazz,
                         const jlong jcallback_pointer,
+                        const JavaParamRef<jobjectArray>& jnames,
                         const JavaParamRef<jobjectArray>& jshort_names,
                         const JavaParamRef<jobjectArray>& jpackage_names,
                         const JavaParamRef<jintArray>& jshell_apk_versions,
-                        const JavaParamRef<jintArray>& jversion_codes) {
+                        const JavaParamRef<jintArray>& jversion_codes,
+                        const JavaParamRef<jobjectArray>& juris,
+                        const JavaParamRef<jobjectArray>& jscopes,
+                        const JavaParamRef<jobjectArray>& jmanifest_urls,
+                        const JavaParamRef<jobjectArray>& jmanifest_start_urls,
+                        const JavaParamRef<jintArray>& jdisplay_modes,
+                        const JavaParamRef<jintArray>& jorientations,
+                        const JavaParamRef<jlongArray>& jtheme_colors,
+                        const JavaParamRef<jlongArray>& jbackground_colors) {
   DCHECK(jcallback_pointer);
+  std::vector<std::string> names;
+  base::android::AppendJavaStringArrayToStringVector(env, jnames, &names);
   std::vector<std::string> short_names;
   base::android::AppendJavaStringArrayToStringVector(env, jshort_names,
                                                      &short_names);
@@ -354,17 +365,50 @@
                                          &shell_apk_versions);
   std::vector<int> version_codes;
   base::android::JavaIntArrayToIntVector(env, jversion_codes, &version_codes);
+  std::vector<std::string> uris;
+  base::android::AppendJavaStringArrayToStringVector(env, juris, &uris);
+  std::vector<std::string> scopes;
+  base::android::AppendJavaStringArrayToStringVector(env, jscopes, &scopes);
+  std::vector<std::string> manifest_urls;
+  base::android::AppendJavaStringArrayToStringVector(env, jmanifest_urls,
+                                                     &manifest_urls);
+  std::vector<std::string> manifest_start_urls;
+  base::android::AppendJavaStringArrayToStringVector(env, jmanifest_start_urls,
+                                                     &manifest_start_urls);
+  std::vector<int> display_modes;
+  base::android::JavaIntArrayToIntVector(env, jdisplay_modes, &display_modes);
+  std::vector<int> orientations;
+  base::android::JavaIntArrayToIntVector(env, jorientations, &orientations);
+  std::vector<int64_t> theme_colors;
+  base::android::JavaLongArrayToInt64Vector(env, jtheme_colors, &theme_colors);
+  std::vector<int64_t> background_colors;
+  base::android::JavaLongArrayToInt64Vector(env, jbackground_colors,
+                                            &background_colors);
 
+  DCHECK(short_names.size() == names.size());
   DCHECK(short_names.size() == package_names.size());
   DCHECK(short_names.size() == shell_apk_versions.size());
   DCHECK(short_names.size() == version_codes.size());
+  DCHECK(short_names.size() == uris.size());
+  DCHECK(short_names.size() == scopes.size());
+  DCHECK(short_names.size() == manifest_urls.size());
+  DCHECK(short_names.size() == manifest_start_urls.size());
+  DCHECK(short_names.size() == display_modes.size());
+  DCHECK(short_names.size() == orientations.size());
+  DCHECK(short_names.size() == theme_colors.size());
+  DCHECK(short_names.size() == background_colors.size());
 
   std::vector<WebApkInfo> webapk_list;
   webapk_list.reserve(short_names.size());
   for (size_t i = 0; i < short_names.size(); ++i) {
-    webapk_list.push_back(WebApkInfo(std::move(short_names[i]),
-                                     std::move(package_names[i]),
-                                     shell_apk_versions[i], version_codes[i]));
+    webapk_list.push_back(WebApkInfo(
+        std::move(names[i]), std::move(short_names[i]),
+        std::move(package_names[i]), shell_apk_versions[i], version_codes[i],
+        std::move(uris[i]), std::move(scopes[i]), std::move(manifest_urls[i]),
+        std::move(manifest_start_urls[i]),
+        static_cast<blink::WebDisplayMode>(display_modes[i]),
+        static_cast<blink::WebScreenOrientationLockType>(orientations[i]),
+        theme_colors[i], background_colors[i]));
   }
 
   ShortcutHelper::WebApkInfoCallback* webapk_list_callback =
diff --git a/chrome/browser/android/webapk/webapk_info.cc b/chrome/browser/android/webapk/webapk_info.cc
index e6cd84d..2b4735c 100644
--- a/chrome/browser/android/webapk/webapk_info.cc
+++ b/chrome/browser/android/webapk/webapk_info.cc
@@ -2,15 +2,38 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <utility>
+
 #include "chrome/browser/android/webapk/webapk_info.h"
 
-WebApkInfo::WebApkInfo(std::string short_name,
+WebApkInfo::WebApkInfo(std::string name,
+                       std::string short_name,
                        std::string package_name,
                        int shell_apk_version,
-                       int version_code)
-    : short_name(std::move(short_name)),
+                       int version_code,
+                       std::string uri,
+                       std::string scope,
+                       std::string manifest_url,
+                       std::string manifest_start_url,
+                       blink::WebDisplayMode display,
+                       blink::WebScreenOrientationLockType orientation,
+                       int64_t theme_color,
+                       int64_t background_color)
+    : name(std::move(name)),
+      short_name(std::move(short_name)),
       package_name(std::move(package_name)),
       shell_apk_version(shell_apk_version),
-      version_code(version_code) {}
+      version_code(version_code),
+      uri(std::move(uri)),
+      scope(std::move(scope)),
+      manifest_url(std::move(manifest_url)),
+      manifest_start_url(std::move(manifest_start_url)),
+      display(display),
+      orientation(orientation),
+      theme_color(theme_color),
+      background_color(background_color) {}
 
 WebApkInfo::~WebApkInfo() {}
+
+WebApkInfo& WebApkInfo::operator=(WebApkInfo&& rhs) = default;
+WebApkInfo::WebApkInfo(WebApkInfo&& other) = default;
diff --git a/chrome/browser/android/webapk/webapk_info.h b/chrome/browser/android/webapk/webapk_info.h
index 746c5f51..be0edae4 100644
--- a/chrome/browser/android/webapk/webapk_info.h
+++ b/chrome/browser/android/webapk/webapk_info.h
@@ -8,6 +8,8 @@
 #include <string>
 
 #include "base/macros.h"
+#include "content/public/common/manifest.h"
+#include "third_party/WebKit/public/platform/modules/screen_orientation/WebScreenOrientationLockType.h"
 
 // Structure with information about a WebAPK.
 //
@@ -16,14 +18,26 @@
 // move-constructs its string arguments (which are copied from Java to C++ into
 // a temporary prior to construction).
 struct WebApkInfo {
-  WebApkInfo(std::string short_name,
+  WebApkInfo(std::string name,
+             std::string short_name,
              std::string package_name,
              int shell_apk_version,
-             int version_code);
+             int version_code,
+             std::string uri,
+             std::string scope,
+             std::string manifest_url,
+             std::string manifest_start_url,
+             blink::WebDisplayMode display,
+             blink::WebScreenOrientationLockType orientation,
+             int64_t theme_color,
+             int64_t background_color);
   ~WebApkInfo();
 
-  WebApkInfo& operator=(WebApkInfo&& other) = default;
-  WebApkInfo(WebApkInfo&& other) = default;
+  WebApkInfo& operator=(WebApkInfo&& other);
+  WebApkInfo(WebApkInfo&& other);
+
+  // Short name of the WebAPK.
+  std::string name;
 
   // Short name of the WebAPK.
   std::string short_name;
@@ -37,6 +51,15 @@
   // Version code of the WebAPK.
   int version_code;
 
+  std::string uri;
+  std::string scope;
+  std::string manifest_url;
+  std::string manifest_start_url;
+  blink::WebDisplayMode display;
+  blink::WebScreenOrientationLockType orientation;
+  int64_t theme_color;
+  int64_t background_color;
+
  private:
   DISALLOW_COPY_AND_ASSIGN(WebApkInfo);
 };
diff --git a/chrome/browser/android/webapk/webapk_installer.cc b/chrome/browser/android/webapk/webapk_installer.cc
index 7df48b2..de4e576 100644
--- a/chrome/browser/android/webapk/webapk_installer.cc
+++ b/chrome/browser/android/webapk/webapk_installer.cc
@@ -33,6 +33,7 @@
 #include "net/traffic_annotation/network_traffic_annotation.h"
 #include "net/url_request/url_fetcher.h"
 #include "ui/gfx/codec/png_codec.h"
+#include "ui/gfx/color_utils.h"
 #include "url/gurl.h"
 
 namespace {
@@ -78,13 +79,8 @@
 std::string ColorToString(int64_t color) {
   if (color == content::Manifest::kInvalidOrMissingColor)
     return "";
-
   SkColor sk_color = reinterpret_cast<uint32_t&>(color);
-  int r = SkColorGetR(sk_color);
-  int g = SkColorGetG(sk_color);
-  int b = SkColorGetB(sk_color);
-  double a = SkColorGetA(sk_color) / 255.0;
-  return base::StringPrintf("rgba(%d,%d,%d,%.2f)", r, g, b, a);
+  return color_utils::SkColorToRgbaString(sk_color);
 }
 
 // Get Chrome's current ABI. It depends on whether Chrome is running as a 32 bit
diff --git a/chrome/browser/autocomplete/search_provider_unittest.cc b/chrome/browser/autocomplete/search_provider_unittest.cc
index d15a0e98..275328f 100644
--- a/chrome/browser/autocomplete/search_provider_unittest.cc
+++ b/chrome/browser/autocomplete/search_provider_unittest.cc
@@ -3226,6 +3226,18 @@
       GURL("https://www.google.com/complete/search"), &google_template_url,
       metrics::OmniboxEventProto::OTHER, SearchTermsData(), &client));
 
+  // Non-HTTP page URL on different domain, yet with feature flag to allow
+  // this turned on.
+  {
+    base::test::ScopedFeatureList feature_list;
+    feature_list.InitAndEnableFeature(
+        omnibox::kSearchProviderContextAllowHttpsUrls);
+    EXPECT_TRUE(SearchProvider::CanSendURL(
+        GURL("https://www.notgoogle.com/search"),
+        GURL("https://www.google.com/complete/search"), &google_template_url,
+        metrics::OmniboxEventProto::OTHER, SearchTermsData(), &client));
+  }
+
   // Non-HTTPS provider.
   EXPECT_FALSE(SearchProvider::CanSendURL(
       GURL("http://www.google.com/search"),
diff --git a/chrome/browser/browsing_data/browsing_data_counter_factory.cc b/chrome/browser/browsing_data/browsing_data_counter_factory.cc
index 2cdc16c..accd07d 100644
--- a/chrome/browser/browsing_data/browsing_data_counter_factory.cc
+++ b/chrome/browser/browsing_data/browsing_data_counter_factory.cc
@@ -11,6 +11,7 @@
 #include "chrome/browser/browsing_data/cache_counter.h"
 #include "chrome/browser/browsing_data/downloads_counter.h"
 #include "chrome/browser/browsing_data/media_licenses_counter.h"
+#include "chrome/browser/browsing_data/site_data_counter.h"
 #include "chrome/browser/history/history_service_factory.h"
 #include "chrome/browser/history/web_history_service_factory.h"
 #include "chrome/browser/password_manager/password_store_factory.h"
@@ -57,8 +58,14 @@
   }
 
   if (pref_name == browsing_data::prefs::kDeleteCache ||
-      pref_name == browsing_data::prefs::kDeleteCacheBasic)
+      pref_name == browsing_data::prefs::kDeleteCacheBasic) {
     return base::MakeUnique<CacheCounter>(profile);
+  }
+
+  if (pref_name == browsing_data::prefs::kDeleteCookies &&
+      IsSiteDataCounterEnabled()) {
+    return base::MakeUnique<SiteDataCounter>(profile);
+  }
 
   if (pref_name == browsing_data::prefs::kDeletePasswords) {
     return base::MakeUnique<browsing_data::PasswordsCounter>(
diff --git a/chrome/browser/browsing_data/browsing_data_counter_utils.cc b/chrome/browser/browsing_data/browsing_data_counter_utils.cc
index 568b30e..277cf06 100644
--- a/chrome/browser/browsing_data/browsing_data_counter_utils.cc
+++ b/chrome/browser/browsing_data/browsing_data_counter_utils.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/browsing_data/browsing_data_counter_utils.h"
 
 #include "base/command_line.h"
+#include "base/feature_list.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/browsing_data/cache_counter.h"
 #include "chrome/browser/browsing_data/media_licenses_counter.h"
@@ -25,6 +26,10 @@
 #include "chrome/browser/browsing_data/hosted_apps_counter.h"
 #endif
 
+#if defined(OS_ANDROID)
+#include "chrome/browser/android/chrome_feature_list.h"
+#endif
+
 bool AreCountersEnabled() {
   if (base::CommandLine::ForCurrentProcess()->HasSwitch(
           switches::kEnableClearBrowsingDataCounters)) {
@@ -40,6 +45,16 @@
   return true;
 }
 
+bool IsSiteDataCounterEnabled() {
+#if defined(OS_ANDROID)
+  // Only use the site data counter for the new CBD ui.
+  return base::FeatureList::IsEnabled(chrome::android::kTabsInCBD);
+#else
+  // Don't use the counter on other platforms that don't yet have the new ui.
+  return false;
+#endif
+}
+
 // A helper function to display the size of cache in units of MB or higher.
 // We need this, as 1 MB is the lowest nonzero cache size displayed by the
 // counter.
@@ -82,6 +97,17 @@
     return l10n_util::GetStringUTF16(IDS_DEL_CACHE_COUNTER_ALMOST_EMPTY);
   }
 
+  if (pref_name == browsing_data::prefs::kDeleteCookies) {
+    // Site data counter.
+    DCHECK(IsSiteDataCounterEnabled());
+    browsing_data::BrowsingDataCounter::ResultInt origins =
+        static_cast<const browsing_data::BrowsingDataCounter::FinishedResult*>(
+            result)
+            ->Value();
+    return l10n_util::GetPluralStringFUTF16(IDS_DEL_COOKIES_COUNTER_ADVANCED,
+                                            origins);
+  }
+
   if (pref_name == browsing_data::prefs::kDeleteMediaLicenses) {
     const MediaLicensesCounter::MediaLicenseResult* media_license_result =
         static_cast<const MediaLicensesCounter::MediaLicenseResult*>(result);
diff --git a/chrome/browser/browsing_data/browsing_data_counter_utils.h b/chrome/browser/browsing_data/browsing_data_counter_utils.h
index da576dc..a6a417b 100644
--- a/chrome/browser/browsing_data/browsing_data_counter_utils.h
+++ b/chrome/browser/browsing_data/browsing_data_counter_utils.h
@@ -12,6 +12,9 @@
 // Whether the browsing data counters experiment is enabled.
 bool AreCountersEnabled();
 
+// Whether the site data counter is enabled.
+bool IsSiteDataCounterEnabled();
+
 // Constructs the text to be displayed by a counter from the given |result|.
 base::string16 GetChromeCounterTextFromResult(
     const browsing_data::BrowsingDataCounter::Result* result);
diff --git a/chrome/browser/browsing_data/site_data_counter.cc b/chrome/browser/browsing_data/site_data_counter.cc
new file mode 100644
index 0000000..36397fd
--- /dev/null
+++ b/chrome/browser/browsing_data/site_data_counter.cc
@@ -0,0 +1,35 @@
+// Copyright 2017 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 "chrome/browser/browsing_data/site_data_counter.h"
+
+#include "chrome/browser/browsing_data/site_data_counting_helper.h"
+#include "components/browsing_data/core/pref_names.h"
+#include "content/public/browser/browser_thread.h"
+
+using content::BrowserThread;
+
+SiteDataCounter::SiteDataCounter(Profile* profile)
+    : profile_(profile), weak_ptr_factory_(this) {}
+
+SiteDataCounter::~SiteDataCounter() {}
+
+const char* SiteDataCounter::GetPrefName() const {
+  return browsing_data::prefs::kDeleteCookies;
+}
+
+void SiteDataCounter::Count() {
+  base::Time begin = GetPeriodStart();
+  auto done_callback =
+      base::Bind(&SiteDataCounter::Done, weak_ptr_factory_.GetWeakPtr());
+  // Use a helper class that owns itself to avoid issues when SiteDataCounter is
+  // deleted before counting finished.
+  auto* helper = new SiteDataCountingHelper(profile_, begin, done_callback);
+  helper->CountAndDestroySelfWhenFinished();
+}
+
+void SiteDataCounter::Done(int origin_count) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  ReportResult(origin_count);
+}
diff --git a/chrome/browser/browsing_data/site_data_counter.h b/chrome/browser/browsing_data/site_data_counter.h
new file mode 100644
index 0000000..f6939db
--- /dev/null
+++ b/chrome/browser/browsing_data/site_data_counter.h
@@ -0,0 +1,28 @@
+// Copyright 2017 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 CHROME_BROWSER_BROWSING_DATA_SITE_DATA_COUNTER_H_
+#define CHROME_BROWSER_BROWSING_DATA_SITE_DATA_COUNTER_H_
+
+#include "base/memory/weak_ptr.h"
+#include "components/browsing_data/core/counters/browsing_data_counter.h"
+
+class Profile;
+
+class SiteDataCounter : public browsing_data::BrowsingDataCounter {
+ public:
+  explicit SiteDataCounter(Profile* profile);
+  ~SiteDataCounter() override;
+
+  const char* GetPrefName() const override;
+
+ private:
+  void Count() override;
+  void Done(int origin_count);
+
+  Profile* profile_;
+  base::WeakPtrFactory<SiteDataCounter> weak_ptr_factory_;
+};
+
+#endif  // CHROME_BROWSER_BROWSING_DATA_SITE_DATA_COUNTER_H_
diff --git a/chrome/browser/browsing_data/site_data_counting_helper.cc b/chrome/browser/browsing_data/site_data_counting_helper.cc
new file mode 100644
index 0000000..b2908c7
--- /dev/null
+++ b/chrome/browser/browsing_data/site_data_counting_helper.cc
@@ -0,0 +1,246 @@
+// Copyright 2017 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 "chrome/browser/browsing_data/site_data_counting_helper.h"
+
+#include "chrome/browser/browsing_data/browsing_data_flash_lso_helper.h"
+#include "chrome/browser/browsing_data/browsing_data_helper.h"
+#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
+#include "chrome/browser/profiles/profile.h"
+#include "components/content_settings/core/browser/host_content_settings_map.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/dom_storage_context.h"
+#include "content/public/browser/local_storage_usage_info.h"
+#include "content/public/browser/session_storage_usage_info.h"
+#include "content/public/browser/storage_partition.h"
+#include "net/cookies/cookie_store.h"
+#include "net/cookies/cookie_util.h"
+#include "net/ssl/channel_id_service.h"
+#include "net/ssl/channel_id_store.h"
+#include "net/url_request/url_request_context.h"
+#include "net/url_request/url_request_context_getter.h"
+#include "ppapi/features/features.h"
+#include "storage/browser/quota/quota_manager.h"
+
+using content::BrowserThread;
+
+SiteDataCountingHelper::SiteDataCountingHelper(
+    Profile* profile,
+    base::Time begin,
+    base::Callback<void(int)> completion_callback)
+    : profile_(profile),
+      begin_(begin),
+      completion_callback_(completion_callback),
+      tasks_(0) {}
+
+SiteDataCountingHelper::~SiteDataCountingHelper() {}
+
+void SiteDataCountingHelper::CountAndDestroySelfWhenFinished() {
+  content::StoragePartition* partition =
+      content::BrowserContext::GetDefaultStoragePartition(profile_);
+
+  scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy(
+      profile_->GetSpecialStoragePolicy());
+
+  net::URLRequestContextGetter* rq_context = partition->GetURLRequestContext();
+
+  tasks_ += 1;
+  // Count origins with cookies.
+  BrowserThread::PostTask(
+      BrowserThread::IO, FROM_HERE,
+      base::Bind(&SiteDataCountingHelper::GetCookiesOnIOThread,
+                 base::Unretained(this), make_scoped_refptr(rq_context)));
+
+  storage::QuotaManager* quota_manager = partition->GetQuotaManager();
+  if (quota_manager) {
+    // Count origins with filesystem, websql, appcache, indexeddb,
+    // serviceworkers and cachestorage using quota manager.
+    storage::GetOriginsCallback origins_callback =
+        base::Bind(&SiteDataCountingHelper::GetQuotaOriginsCallback,
+                   base::Unretained(this));
+    const storage::StorageType types[] = {storage::kStorageTypeTemporary,
+                                          storage::kStorageTypePersistent,
+                                          storage::kStorageTypeSyncable};
+    for (auto type : types) {
+      tasks_ += 1;
+      BrowserThread::PostTask(
+          BrowserThread::IO, FROM_HERE,
+          base::Bind(&storage::QuotaManager::GetOriginsModifiedSince,
+                     quota_manager, type, begin_, origins_callback));
+    }
+  }
+
+  // Count origins with local storage or session storage.
+  content::DOMStorageContext* dom_storage = partition->GetDOMStorageContext();
+  if (dom_storage) {
+    tasks_ += 1;
+    auto local_callback =
+        base::Bind(&SiteDataCountingHelper::GetLocalStorageUsageInfoCallback,
+                   base::Unretained(this), special_storage_policy);
+    dom_storage->GetLocalStorageUsage(local_callback);
+    tasks_ += 1;
+    auto session_callback =
+        base::Bind(&SiteDataCountingHelper::GetSessionStorageUsageInfoCallback,
+                   base::Unretained(this), special_storage_policy);
+    dom_storage->GetSessionStorageUsage(session_callback);
+  }
+
+#if BUILDFLAG(ENABLE_PLUGINS)
+  // Count origins with flash data.
+  flash_lso_helper_ = BrowsingDataFlashLSOHelper::Create(profile_);
+  if (flash_lso_helper_) {
+    tasks_ += 1;
+    flash_lso_helper_->StartFetching(
+        base::Bind(&SiteDataCountingHelper::SitesWithFlashDataCallback,
+                   base::Unretained(this)));
+  }
+#endif
+
+  // Counting site usage data and durable permissions.
+  auto* hcsm = HostContentSettingsMapFactory::GetForProfile(profile_);
+  const ContentSettingsType content_settings[] = {
+      CONTENT_SETTINGS_TYPE_DURABLE_STORAGE,
+      CONTENT_SETTINGS_TYPE_SITE_ENGAGEMENT, CONTENT_SETTINGS_TYPE_APP_BANNER};
+  for (auto type : content_settings) {
+    tasks_ += 1;
+    GetOriginsFromHostContentSettignsMap(hcsm, type);
+  }
+  // Count origins with channel ids.
+  tasks_ += 1;
+  BrowserThread::PostTask(
+      BrowserThread::IO, FROM_HERE,
+      base::Bind(&SiteDataCountingHelper::GetChannelIDsOnIOThread,
+                 base::Unretained(this), make_scoped_refptr(rq_context)));
+}
+
+void SiteDataCountingHelper::GetOriginsFromHostContentSettignsMap(
+    HostContentSettingsMap* hcsm,
+    ContentSettingsType type) {
+  std::set<GURL> origins;
+  ContentSettingsForOneType settings;
+  hcsm->GetSettingsForOneType(type, std::string(), &settings);
+  for (const ContentSettingPatternSource& rule : settings) {
+    GURL url(rule.primary_pattern.ToString());
+    if (!url.is_empty()) {
+      origins.insert(url);
+    }
+  }
+  Done(std::vector<GURL>(origins.begin(), origins.end()));
+}
+
+void SiteDataCountingHelper::GetCookiesOnIOThread(
+    const scoped_refptr<net::URLRequestContextGetter>& rq_context) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+  net::CookieStore* cookie_store =
+      rq_context->GetURLRequestContext()->cookie_store();
+
+  if (cookie_store) {
+    cookie_store->GetAllCookiesAsync(base::Bind(
+        &SiteDataCountingHelper::GetCookiesCallback, base::Unretained(this)));
+  } else {
+    BrowserThread::PostTask(
+        BrowserThread::UI, FROM_HERE,
+        base::Bind(&SiteDataCountingHelper::Done, base::Unretained(this),
+                   std::vector<GURL>()));
+  }
+}
+
+void SiteDataCountingHelper::GetCookiesCallback(
+    const net::CookieList& cookies) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  std::vector<GURL> origins;
+  for (const net::CanonicalCookie& cookie : cookies) {
+    if (cookie.CreationDate() >= begin_) {
+      GURL url = net::cookie_util::CookieOriginToURL(cookie.Domain(),
+                                                     cookie.IsSecure());
+      origins.push_back(url);
+    }
+  }
+  BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+                          base::Bind(&SiteDataCountingHelper::Done,
+                                     base::Unretained(this), origins));
+}
+
+void SiteDataCountingHelper::GetQuotaOriginsCallback(
+    const std::set<GURL>& origin_set,
+    storage::StorageType type) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  std::vector<GURL> origins(origin_set.begin(), origin_set.end());
+  BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+                          base::Bind(&SiteDataCountingHelper::Done,
+                                     base::Unretained(this), origins));
+}
+
+void SiteDataCountingHelper::GetLocalStorageUsageInfoCallback(
+    const scoped_refptr<storage::SpecialStoragePolicy>& policy,
+    const std::vector<content::LocalStorageUsageInfo>& infos) {
+  std::vector<GURL> origins;
+  for (const auto& info : infos) {
+    if (info.last_modified >= begin_ &&
+        (!policy || !policy->IsStorageProtected(info.origin))) {
+      origins.push_back(info.origin);
+    }
+  }
+  Done(origins);
+}
+
+void SiteDataCountingHelper::GetSessionStorageUsageInfoCallback(
+    const scoped_refptr<storage::SpecialStoragePolicy>& policy,
+    const std::vector<content::SessionStorageUsageInfo>& infos) {
+  std::vector<GURL> origins;
+  for (const auto& info : infos) {
+    // Session storage doesn't know about creation time.
+    if (!policy || !policy->IsStorageProtected(info.origin)) {
+      origins.push_back(info.origin);
+    }
+  }
+  Done(origins);
+}
+
+void SiteDataCountingHelper::SitesWithFlashDataCallback(
+    const std::vector<std::string>& sites) {
+  std::vector<GURL> origins;
+  for (const std::string& site : sites) {
+    origins.push_back(GURL(site));
+  }
+  Done(origins);
+}
+
+void SiteDataCountingHelper::GetChannelIDsOnIOThread(
+    const scoped_refptr<net::URLRequestContextGetter>& rq_context) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  net::ChannelIDService* channel_id_service =
+      rq_context->GetURLRequestContext()->channel_id_service();
+  channel_id_service->GetChannelIDStore()->GetAllChannelIDs(base::Bind(
+      &SiteDataCountingHelper::GetChannelIDsCallback, base::Unretained(this)));
+}
+
+void SiteDataCountingHelper::GetChannelIDsCallback(
+    const net::ChannelIDStore::ChannelIDList& channel_ids) {
+  std::vector<GURL> origins;
+  for (const net::ChannelIDStore::ChannelID& channel_id : channel_ids) {
+    if (channel_id.creation_time() >= begin_) {
+      // Assume url is https://<server_identifier> on default port because
+      // channel ids don't know about their scheme or port.
+      origins.push_back(GURL("https://" + channel_id.server_identifier()));
+    }
+  }
+  BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+                          base::Bind(&SiteDataCountingHelper::Done,
+                                     base::Unretained(this), origins));
+}
+
+void SiteDataCountingHelper::Done(const std::vector<GURL>& origins) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  DCHECK(tasks_ > 0);
+  for (const GURL& origin : origins) {
+    unique_origins_.insert(origin);
+  }
+  if (--tasks_ > 0)
+    return;
+  base::ThreadTaskRunnerHandle::Get()->PostTask(
+      FROM_HERE, base::Bind(completion_callback_, unique_origins_.size()));
+  base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
+}
diff --git a/chrome/browser/browsing_data/site_data_counting_helper.h b/chrome/browser/browsing_data/site_data_counting_helper.h
new file mode 100644
index 0000000..2d83dd3
--- /dev/null
+++ b/chrome/browser/browsing_data/site_data_counting_helper.h
@@ -0,0 +1,75 @@
+// Copyright 2017 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 CHROME_BROWSER_BROWSING_DATA_SITE_DATA_COUNTING_HELPER_H_
+#define CHROME_BROWSER_BROWSING_DATA_SITE_DATA_COUNTING_HELPER_H_
+
+#include <set>
+#include "components/content_settings/core/common/content_settings_types.h"
+#include "net/cookies/canonical_cookie.h"
+#include "net/ssl/channel_id_store.h"
+#include "storage/common/quota/quota_types.h"
+
+class Profile;
+class BrowsingDataFlashLSOHelper;
+class HostContentSettingsMap;
+
+namespace net {
+class URLRequestContextGetter;
+}
+
+namespace content {
+struct LocalStorageUsageInfo;
+struct SessionStorageUsageInfo;
+}
+
+namespace storage {
+class SpecialStoragePolicy;
+}
+
+// Helper class that counts the number of unique origins, that are affected by
+// deleting "cookies and site data" in the CBD dialog.
+class SiteDataCountingHelper {
+ public:
+  explicit SiteDataCountingHelper(
+      Profile* profile,
+      base::Time begin,
+      base::Callback<void(int)> completion_callback);
+  ~SiteDataCountingHelper();
+
+  void CountAndDestroySelfWhenFinished();
+
+ private:
+  void GetOriginsFromHostContentSettignsMap(HostContentSettingsMap* hcsm,
+                                            ContentSettingsType type);
+  void GetCookiesOnIOThread(
+      const scoped_refptr<net::URLRequestContextGetter>& rq_context);
+  void GetCookiesCallback(const net::CookieList& cookies);
+  void GetSessionStorageUsageInfoCallback(
+      const scoped_refptr<storage::SpecialStoragePolicy>&
+          special_storage_policy,
+      const std::vector<content::SessionStorageUsageInfo>& infos);
+  void GetLocalStorageUsageInfoCallback(
+      const scoped_refptr<storage::SpecialStoragePolicy>&
+          special_storage_policy,
+      const std::vector<content::LocalStorageUsageInfo>& infos);
+  void GetQuotaOriginsCallback(const std::set<GURL>& origin_set,
+                               storage::StorageType type);
+  void SitesWithFlashDataCallback(const std::vector<std::string>& sites);
+  void GetChannelIDsOnIOThread(
+      const scoped_refptr<net::URLRequestContextGetter>& rq_context);
+  void GetChannelIDsCallback(
+      const net::ChannelIDStore::ChannelIDList& channel_ids);
+
+  void Done(const std::vector<GURL>& origins);
+
+  Profile* profile_;
+  base::Time begin_;
+  base::Callback<void(int)> completion_callback_;
+  int tasks_;
+  std::set<GURL> unique_origins_;
+  scoped_refptr<BrowsingDataFlashLSOHelper> flash_lso_helper_;
+};
+
+#endif  // CHROME_BROWSER_BROWSING_DATA_SITE_DATA_COUNTING_HELPER_H_
diff --git a/chrome/browser/browsing_data/site_data_counting_helper_unittest.cc b/chrome/browser/browsing_data/site_data_counting_helper_unittest.cc
new file mode 100644
index 0000000..b7edb053
--- /dev/null
+++ b/chrome/browser/browsing_data/site_data_counting_helper_unittest.cc
@@ -0,0 +1,212 @@
+// Copyright 2017 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 <algorithm>
+#include <memory>
+#include <set>
+#include <string>
+
+#include "base/files/file_path.h"
+#include "base/files/file_util.h"
+#include "base/run_loop.h"
+#include "chrome/browser/browsing_data/site_data_counting_helper.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/test/base/testing_profile.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/storage_partition.h"
+#include "content/public/test/test_browser_thread_bundle.h"
+#include "net/cookies/cookie_store.h"
+#include "net/url_request/url_request_context.h"
+#include "net/url_request/url_request_context_getter.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using content::BrowserThread;
+
+class SiteDataCountingHelperTest : public testing::Test {
+ public:
+  const int64_t kTimeoutMs = 10;
+
+  void SetUp() override {
+    profile_.reset(new TestingProfile());
+    tasks_ = 0;
+    cookie_callback_ = base::Bind(&SiteDataCountingHelperTest::CookieCallback,
+                                  base::Unretained(this));
+  }
+
+  void TearDown() override {
+    profile_.reset();
+    base::RunLoop().RunUntilIdle();
+  }
+
+  void CookieCallback(int count) {
+    // Negative values represent an unexpected error.
+    DCHECK(count >= 0);
+    DCHECK_CURRENTLY_ON(BrowserThread::UI);
+    last_count_ = count;
+
+    if (run_loop_)
+      run_loop_->Quit();
+  }
+
+  void DoneOnIOThread(bool success) {
+    DCHECK(success);
+    if (--tasks_ > 0)
+      return;
+    BrowserThread::PostTask(
+        BrowserThread::UI, FROM_HERE,
+        base::Bind(&SiteDataCountingHelperTest::DoneCallback,
+                   base::Unretained(this)));
+  }
+
+  void DoneCallback() {
+    DCHECK_CURRENTLY_ON(BrowserThread::UI);
+    if (run_loop_)
+      run_loop_->Quit();
+  }
+
+  void WaitForTasksOnIOThread() {
+    DCHECK_CURRENTLY_ON(BrowserThread::UI);
+    run_loop_.reset(new base::RunLoop());
+    run_loop_->Run();
+  }
+
+  void CreateCookies(base::Time creation_time,
+                     const std::vector<std::string>& urls) {
+    content::StoragePartition* partition =
+        content::BrowserContext::GetDefaultStoragePartition(profile());
+    net::URLRequestContextGetter* rq_context =
+        partition->GetURLRequestContext();
+    BrowserThread::PostTask(
+        BrowserThread::IO, FROM_HERE,
+        base::Bind(&SiteDataCountingHelperTest::CreateCookiesOnIOThread,
+                   base::Unretained(this), make_scoped_refptr(rq_context),
+                   creation_time, urls));
+  }
+
+  void CreateLocalStorage(
+      base::Time creation_time,
+      const std::vector<base::FilePath::StringPieceType>& storage_origins) {
+    // Note: This test depends on details of how the dom_storage library
+    // stores data in the host file system.
+    base::FilePath storage_path =
+        profile()->GetPath().AppendASCII("Local Storage");
+    base::CreateDirectory(storage_path);
+
+    // Write some files.
+    for (const auto& origin : storage_origins) {
+      base::WriteFile(storage_path.Append(origin), NULL, 0);
+      base::TouchFile(storage_path.Append(origin), creation_time,
+                      creation_time);
+    }
+  }
+
+  void CreateCookiesOnIOThread(
+      const scoped_refptr<net::URLRequestContextGetter>& rq_context,
+      base::Time creation_time,
+      std::vector<std::string> urls) {
+    DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+    net::CookieStore* cookie_store =
+        rq_context->GetURLRequestContext()->cookie_store();
+
+    tasks_ = urls.size();
+    int i = 0;
+    for (const std::string& url_string : urls) {
+      GURL url(url_string);
+      // Cookies need a unique creation time.
+      base::Time time = creation_time + base::TimeDelta::FromMilliseconds(i++);
+      cookie_store->SetCookieWithDetailsAsync(
+          url, "name", "A=1", url.host(), url.path(), time, base::Time(), time,
+          true, false, net::CookieSameSite::DEFAULT_MODE,
+          net::COOKIE_PRIORITY_DEFAULT,
+          base::Bind(&SiteDataCountingHelperTest::DoneOnIOThread,
+                     base::Unretained(this)));
+    }
+  }
+
+  void CountEntries(base::Time begin_time) {
+    DCHECK_CURRENTLY_ON(BrowserThread::UI);
+    last_count_ = -1;
+    auto* helper =
+        new SiteDataCountingHelper(profile(), begin_time, cookie_callback_);
+    helper->CountAndDestroySelfWhenFinished();
+  }
+
+  int64_t GetResult() {
+    DCHECK_GE(last_count_, 0);
+    return last_count_;
+  }
+
+  Profile* profile() { return profile_.get(); }
+
+ private:
+  base::Callback<void(int)> cookie_callback_;
+  std::unique_ptr<base::RunLoop> run_loop_;
+  content::TestBrowserThreadBundle thread_bundle_;
+  std::unique_ptr<TestingProfile> profile_;
+
+  int tasks_;
+  int64_t last_count_;
+};
+
+TEST_F(SiteDataCountingHelperTest, CheckEmptyResult) {
+  CountEntries(base::Time());
+  WaitForTasksOnIOThread();
+
+  DCHECK_EQ(0, GetResult());
+}
+
+TEST_F(SiteDataCountingHelperTest, CountCookies) {
+  base::Time now = base::Time::Now();
+  base::Time last_hour = now - base::TimeDelta::FromHours(1);
+  base::Time yesterday = now - base::TimeDelta::FromDays(1);
+
+  CreateCookies(last_hour, {"https://example.com"});
+  WaitForTasksOnIOThread();
+
+  CreateCookies(yesterday, {"https://google.com", "https://bing.com"});
+  WaitForTasksOnIOThread();
+
+  CountEntries(base::Time());
+  WaitForTasksOnIOThread();
+  DCHECK_EQ(3, GetResult());
+
+  CountEntries(yesterday);
+  WaitForTasksOnIOThread();
+  DCHECK_EQ(3, GetResult());
+
+  CountEntries(last_hour);
+  WaitForTasksOnIOThread();
+  DCHECK_EQ(1, GetResult());
+
+  CountEntries(now);
+  WaitForTasksOnIOThread();
+  DCHECK_EQ(0, GetResult());
+}
+
+TEST_F(SiteDataCountingHelperTest, LocalStorage) {
+  base::Time now = base::Time::Now();
+  CreateLocalStorage(now,
+                     {FILE_PATH_LITERAL("https_example.com_443.localstorage"),
+                      FILE_PATH_LITERAL("https_bing.com_443.localstorage")});
+
+  CountEntries(base::Time());
+  WaitForTasksOnIOThread();
+  DCHECK_EQ(2, GetResult());
+}
+
+TEST_F(SiteDataCountingHelperTest, CookiesAndLocalStorage) {
+  base::Time now = base::Time::Now();
+  CreateCookies(now, {"https://example.com", "https://google.com"});
+  CreateLocalStorage(now,
+                     {FILE_PATH_LITERAL("https_example.com_443.localstorage"),
+                      FILE_PATH_LITERAL("https_bing.com_443.localstorage")});
+  WaitForTasksOnIOThread();
+
+  CountEntries(base::Time());
+  WaitForTasksOnIOThread();
+  DCHECK_EQ(3, GetResult());
+}
diff --git a/chrome/browser/chrome_browser_main_win.cc b/chrome/browser/chrome_browser_main_win.cc
index ff6c5f1..cd155a0b 100644
--- a/chrome/browser/chrome_browser_main_win.cc
+++ b/chrome/browser/chrome_browser_main_win.cc
@@ -494,7 +494,7 @@
     base::FilePath exe_path;
     PathService::Get(base::DIR_EXE, &exe_path);
     std::wstring exe = exe_path.value();
-    base::FilePath user_exe_path(installer::GetChromeInstallPath(false, dist));
+    base::FilePath user_exe_path(installer::GetChromeInstallPath(false));
     if (base::FilePath::CompareEqualIgnoreCase(exe, user_exe_path.value())) {
       base::CommandLine uninstall_cmd(
           InstallUtil::GetChromeUninstallCmd(false));
diff --git a/chrome/browser/chromeos/app_mode/arc/arc_kiosk_app_manager.cc b/chrome/browser/chromeos/app_mode/arc/arc_kiosk_app_manager.cc
index 48568e76..a2b593f 100644
--- a/chrome/browser/chromeos/app_mode/arc/arc_kiosk_app_manager.cc
+++ b/chrome/browser/chromeos/app_mode/arc/arc_kiosk_app_manager.cc
@@ -47,7 +47,7 @@
 void CancelDelayedCryptohomeRemoval(const cryptohome::Identification& id) {
   PrefService* const local_state = g_browser_process->local_state();
   ListPrefUpdate list_update(local_state, kArcKioskUsersToRemove);
-  list_update->Remove(base::StringValue(id.id()), nullptr);
+  list_update->Remove(base::Value(id.id()), nullptr);
   local_state->CommitPendingWrite();
 }
 
diff --git a/chrome/browser/chromeos/arc/intent_helper/arc_settings_service_browsertest.cc b/chrome/browser/chromeos/arc/intent_helper/arc_settings_service_browsertest.cc
index b6af8900..99c50f7f 100644
--- a/chrome/browser/chromeos/arc/intent_helper/arc_settings_service_browsertest.cc
+++ b/chrome/browser/chromeos/arc/intent_helper/arc_settings_service_browsertest.cc
@@ -256,7 +256,7 @@
         chromeos::DBusThreadManager::Get()
             ->GetShillServiceClient()
             ->GetTestInterface();
-    base::StringValue value(shill::kStateIdle);
+    base::Value value(shill::kStateIdle);
     service_test->SetServiceProperty(service_path, shill::kStateProperty,
                                      value);
     RunUntilIdle();
@@ -274,7 +274,7 @@
                              shill::kStateOnline, true /* add_to_visible */);
 
     service_test->SetServiceProperty(service_path, shill::kProfileProperty,
-                                     base::StringValue(kUserProfilePath));
+                                     base::Value(kUserProfilePath));
     RunUntilIdle();
   }
 
@@ -312,7 +312,7 @@
                              true /* add_to_visible */);
     service_test->SetServiceProperty(kDefaultServicePath,
                                      shill::kProfileProperty,
-                                     base::StringValue(kUserProfilePath));
+                                     base::Value(kUserProfilePath));
   }
 
   policy::MockConfigurationPolicyProvider provider_;
@@ -456,7 +456,7 @@
   policy.Set(
       policy::key::kProxyMode, policy::POLICY_LEVEL_MANDATORY,
       policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD,
-      base::MakeUnique<base::StringValue>(ProxyPrefs::kAutoDetectProxyModeName),
+      base::MakeUnique<base::Value>(ProxyPrefs::kAutoDetectProxyModeName),
       nullptr);
   UpdatePolicy(policy);
 
@@ -477,7 +477,7 @@
   policy.Set(policy::key::kOpenNetworkConfiguration,
              policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER,
              policy::POLICY_SOURCE_CLOUD,
-             base::MakeUnique<base::StringValue>(kONCPolicy), nullptr);
+             base::MakeUnique<base::Value>(kONCPolicy), nullptr);
   UpdatePolicy(policy);
 
   std::unique_ptr<base::DictionaryValue> expected_proxy_config(
@@ -496,14 +496,14 @@
 
   policy::PolicyMap policy;
   // Proxy policy.
-  policy.Set(policy::key::kProxyMode, policy::POLICY_LEVEL_MANDATORY,
-             policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD,
-             base::MakeUnique<base::StringValue>(
-                 ProxyPrefs::kFixedServersProxyModeName),
-             nullptr);
+  policy.Set(
+      policy::key::kProxyMode, policy::POLICY_LEVEL_MANDATORY,
+      policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD,
+      base::MakeUnique<base::Value>(ProxyPrefs::kFixedServersProxyModeName),
+      nullptr);
   policy.Set(policy::key::kProxyServer, policy::POLICY_LEVEL_MANDATORY,
              policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD,
-             base::MakeUnique<base::StringValue>("proxy:8888"), nullptr);
+             base::MakeUnique<base::Value>("proxy:8888"), nullptr);
   UpdatePolicy(policy);
 
   std::unique_ptr<base::DictionaryValue> proxy_config(
@@ -641,11 +641,11 @@
   policy.Set(policy::key::kOpenNetworkConfiguration,
              policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER,
              policy::POLICY_SOURCE_CLOUD,
-             base::MakeUnique<base::StringValue>(kUserONCPolicy), nullptr);
+             base::MakeUnique<base::Value>(kUserONCPolicy), nullptr);
   policy.Set(policy::key::kDeviceOpenNetworkConfiguration,
              policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_MACHINE,
              policy::POLICY_SOURCE_CLOUD,
-             base::MakeUnique<base::StringValue>(kDeviceONCPolicy), nullptr);
+             base::MakeUnique<base::Value>(kDeviceONCPolicy), nullptr);
   UpdatePolicy(policy);
 
   std::unique_ptr<base::DictionaryValue> expected_proxy_config(
diff --git a/chrome/browser/chromeos/arc/policy/arc_policy_bridge_unittest.cc b/chrome/browser/chromeos/arc/policy/arc_policy_bridge_unittest.cc
index b4b40f7..253a24ea 100644
--- a/chrome/browser/chromeos/arc/policy/arc_policy_bridge_unittest.cc
+++ b/chrome/browser/chromeos/arc/policy/arc_policy_bridge_unittest.cc
@@ -186,7 +186,7 @@
   policy_map().Set(
       policy::key::kArcPolicy, policy::POLICY_LEVEL_MANDATORY,
       policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD,
-      base::MakeUnique<base::StringValue>(
+      base::MakeUnique<base::Value>(
           "{\"applications\":"
           "[{\"packageName\":\"com.google.android.apps.youtube.kids\","
           "\"installType\":\"REQUIRED\","
@@ -212,7 +212,7 @@
   policy_map().Set(
       policy::key::kHomepageLocation, policy::POLICY_LEVEL_MANDATORY,
       policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD,
-      base::MakeUnique<base::StringValue>("http://chromium.org"), nullptr);
+      base::MakeUnique<base::Value>("http://chromium.org"), nullptr);
   policy_bridge()->GetPolicies(PolicyStringCallback("{}"));
 }
 
@@ -333,7 +333,7 @@
   policy_map().Set(policy::key::kOpenNetworkConfiguration,
                    policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER,
                    policy::POLICY_SOURCE_CLOUD,
-                   base::MakeUnique<base::StringValue>(kFakeONC), nullptr);
+                   base::MakeUnique<base::Value>(kFakeONC), nullptr);
   policy_bridge()->GetPolicies(PolicyStringCallback(
       "{\"caCerts\":"
       "[{\"X509\":\"TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24"
@@ -365,7 +365,7 @@
   policy_map().Set(
       policy::key::kArcPolicy, policy::POLICY_LEVEL_MANDATORY,
       policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD,
-      base::MakeUnique<base::StringValue>(
+      base::MakeUnique<base::Value>(
           "{\"applications\":"
           "[{\"packageName\":\"com.google.android.apps.youtube.kids\","
           "\"installType\":\"REQUIRED\","
@@ -377,7 +377,7 @@
   policy_map().Set(
       policy::key::kHomepageLocation, policy::POLICY_LEVEL_MANDATORY,
       policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD,
-      base::MakeUnique<base::StringValue>("http://chromium.org"), nullptr);
+      base::MakeUnique<base::Value>("http://chromium.org"), nullptr);
   policy_map().Set(policy::key::kVideoCaptureAllowed,
                    policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER,
                    policy::POLICY_SOURCE_CLOUD,
diff --git a/chrome/browser/chromeos/display/display_preferences_unittest.cc b/chrome/browser/chromeos/display/display_preferences_unittest.cc
index d9b080d..7ac6f7bc 100644
--- a/chrome/browser/chromeos/display/display_preferences_unittest.cc
+++ b/chrome/browser/chromeos/display/display_preferences_unittest.cc
@@ -1078,7 +1078,7 @@
   StoreDisplayBoolPropertyForList(list, "default_unified", true);
   StoreDisplayPropertyForList(
       list, "primary-id",
-      base::MakeUnique<base::StringValue>(base::Int64ToString(id1)));
+      base::MakeUnique<base::Value>(base::Int64ToString(id1)));
   LoadDisplayPreferences(false);
 
   // Should not restore to unified unless unified desktop is enabled.
diff --git a/chrome/browser/chromeos/extensions/device_local_account_external_policy_loader_unittest.cc b/chrome/browser/chromeos/extensions/device_local_account_external_policy_loader_unittest.cc
index 01008ae..259f34f 100644
--- a/chrome/browser/chromeos/extensions/device_local_account_external_policy_loader_unittest.cc
+++ b/chrome/browser/chromeos/extensions/device_local_account_external_policy_loader_unittest.cc
@@ -265,6 +265,12 @@
   content::WindowedNotificationObserver(
       extensions::NOTIFICATION_EXTENSION_UPDATE_FOUND,
       content::NotificationService::AllSources()).Wait();
+  // Temporary solution to mimic the old behavior of
+  // WindowedNotificationObserver.
+  // TODO(https://crbug.com/695073): Likely this has to be removed, and the
+  // IsIdleForTesting check at the end of this test has to be either changed to
+  // a more specific check or removed.
+  content::RunAllPendingInMessageLoop();
 
   // Verify that the downloader is attempting to download a CRX file.
   fetcher = factory.GetFetcherByID(
diff --git a/chrome/browser/chromeos/extensions/file_manager/file_manager_private_apitest.cc b/chrome/browser/chromeos/extensions/file_manager/file_manager_private_apitest.cc
index 8e15742..9db262e 100644
--- a/chrome/browser/chromeos/extensions/file_manager/file_manager_private_apitest.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/file_manager_private_apitest.cc
@@ -324,9 +324,8 @@
       extensions::SOURCE_NETWORK);
 
   file_manager::VolumeManager::Get(browser()->profile())
-      ->AddVolumeForTesting(
-          make_linked_ptr(file_manager::Volume::CreateForProvidedFileSystem(
-              info, file_manager::MOUNT_CONTEXT_AUTO)));
+      ->AddVolumeForTesting(file_manager::Volume::CreateForProvidedFileSystem(
+          info, file_manager::MOUNT_CONTEXT_AUTO));
 
   // We will call fileManagerPrivate.unmountVolume once. To test that method, we
   // check that UnmountPath is really called with the same value.
diff --git a/chrome/browser/chromeos/extensions/file_manager/job_event_router.cc b/chrome/browser/chromeos/extensions/file_manager/job_event_router.cc
index daf2fb3..529bc17 100644
--- a/chrome/browser/chromeos/extensions/file_manager/job_event_router.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/job_event_router.cc
@@ -48,7 +48,7 @@
 
   // Add new job info.
   UpdateBytes(job_info);
-  drive_jobs_[job_info.job_id] = make_linked_ptr(new drive::JobInfo(job_info));
+  drive_jobs_[job_info.job_id] = base::MakeUnique<drive::JobInfo>(job_info);
 
   ScheduleDriveFileTransferEvent(
       job_info, file_manager_private::TRANSFER_STATE_IN_PROGRESS,
diff --git a/chrome/browser/chromeos/extensions/file_manager/job_event_router.h b/chrome/browser/chromeos/extensions/file_manager/job_event_router.h
index 85e4dc5..ea787a67 100644
--- a/chrome/browser/chromeos/extensions/file_manager/job_event_router.h
+++ b/chrome/browser/chromeos/extensions/file_manager/job_event_router.h
@@ -13,7 +13,6 @@
 #include <string>
 
 #include "base/macros.h"
-#include "base/memory/linked_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/threading/thread_checker.h"
 #include "base/time/time.h"
@@ -82,7 +81,7 @@
   base::TimeDelta event_delay_;
 
   // Set of job that are in the job schedular.
-  std::map<drive::JobID, linked_ptr<drive::JobInfo>> drive_jobs_;
+  std::map<drive::JobID, std::unique_ptr<drive::JobInfo>> drive_jobs_;
 
   // Job info of pending event. |ScheduleDriveFileTransferEvent| registers
   // timeout callback to dispatch this.
diff --git a/chrome/browser/chromeos/extensions/file_manager/job_event_router_unittest.cc b/chrome/browser/chromeos/extensions/file_manager/job_event_router_unittest.cc
index 8b84ea50..13f220e 100644
--- a/chrome/browser/chromeos/extensions/file_manager/job_event_router_unittest.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/job_event_router_unittest.cc
@@ -8,6 +8,7 @@
 #include <stdint.h>
 
 #include "base/macros.h"
+#include "base/memory/ptr_util.h"
 #include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -20,7 +21,7 @@
   JobEventRouterImpl() : JobEventRouter(base::TimeDelta::FromMilliseconds(0)) {
     listener_extension_ids_.insert("extension_a");
   }
-  std::vector<linked_ptr<base::DictionaryValue>> events;
+  std::vector<std::unique_ptr<base::DictionaryValue>> events;
 
   void SetListenerExtensionIds(std::set<std::string> extension_ids) {
     listener_extension_ids_ = extension_ids;
@@ -49,7 +50,7 @@
       std::unique_ptr<base::ListValue> event_args) override {
     const base::DictionaryValue* event;
     event_args->GetDictionary(0, &event);
-    events.push_back(make_linked_ptr(event->DeepCopy()));
+    events.push_back(base::WrapUnique(event->DeepCopy()));
   }
 
  private:
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_drive.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_drive.cc
index 90111f1..b20157e 100644
--- a/chrome/browser/chromeos/extensions/file_manager/private_api_drive.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/private_api_drive.cc
@@ -941,7 +941,7 @@
 
   if (!drive_service) {
     // DriveService is not available.
-    SetResult(base::MakeUnique<base::StringValue>(std::string()));
+    SetResult(base::MakeUnique<base::Value>(std::string()));
     SendResponse(true);
     return true;
   }
@@ -961,7 +961,7 @@
 void FileManagerPrivateRequestAccessTokenFunction::OnAccessTokenFetched(
     google_apis::DriveApiErrorCode code,
     const std::string& access_token) {
-  SetResult(base::MakeUnique<base::StringValue>(access_token));
+  SetResult(base::MakeUnique<base::Value>(access_token));
   SendResponse(true);
 }
 
@@ -1000,7 +1000,7 @@
     return;
   }
 
-  SetResult(base::MakeUnique<base::StringValue>(share_url.spec()));
+  SetResult(base::MakeUnique<base::Value>(share_url.spec()));
   SendResponse(true);
 }
 
@@ -1078,7 +1078,7 @@
     // |file_system| is NULL if Drive is disabled or not mounted.
     SetError("Drive is disabled or not mounted.");
     // Intentionally returns a blank.
-    SetResult(base::MakeUnique<base::StringValue>(std::string()));
+    SetResult(base::MakeUnique<base::Value>(std::string()));
     return false;
   }
 
@@ -1087,7 +1087,7 @@
   if (!drive::util::IsUnderDriveMountPoint(path)) {
     SetError("The given file is not in Drive.");
     // Intentionally returns a blank.
-    SetResult(base::MakeUnique<base::StringValue>(std::string()));
+    SetResult(base::MakeUnique<base::Value>(std::string()));
     return false;
   }
   base::FilePath file_path = drive::util::ExtractDrivePath(path);
@@ -1108,7 +1108,7 @@
   if (error != drive::FILE_ERROR_OK) {
     SetError("Download Url for this item is not available.");
     // Intentionally returns a blank.
-    SetResult(base::MakeUnique<base::StringValue>(std::string()));
+    SetResult(base::MakeUnique<base::Value>(std::string()));
     SendResponse(false);
     return;
   }
@@ -1143,14 +1143,14 @@
   if (code != google_apis::HTTP_SUCCESS) {
     SetError("Not able to fetch the token.");
     // Intentionally returns a blank.
-    SetResult(base::MakeUnique<base::StringValue>(std::string()));
+    SetResult(base::MakeUnique<base::Value>(std::string()));
     SendResponse(false);
     return;
   }
 
   const std::string url =
       download_url_.Resolve("?alt=media&access_token=" + access_token).spec();
-  SetResult(base::MakeUnique<base::StringValue>(url));
+  SetResult(base::MakeUnique<base::Value>(url));
 
   SendResponse(true);
 }
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc
index 753857b..3e62ca44 100644
--- a/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/private_api_file_system.cc
@@ -886,7 +886,7 @@
 void FileManagerPrivateInternalComputeChecksumFunction::Respond(
     const std::string& hash) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  SetResult(base::MakeUnique<base::StringValue>(hash));
+  SetResult(base::MakeUnique<base::Value>(hash));
   SendResponse(true);
 }
 
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_misc.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_misc.cc
index 35e2332..40b22ead 100644
--- a/chrome/browser/chromeos/extensions/file_manager/private_api_misc.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/private_api_misc.cc
@@ -365,7 +365,7 @@
     DCHECK(access_token == auth_service_->access_token());
     if (logger)
       logger->Log(logging::LOG_INFO, "CWS OAuth token fetch succeeded.");
-    SetResult(base::MakeUnique<base::StringValue>(access_token));
+    SetResult(base::MakeUnique<base::Value>(access_token));
     SendResponse(true);
   } else {
     if (logger) {
@@ -466,7 +466,7 @@
 
 void FileManagerPrivateInternalGetMimeTypeFunction::OnGetMimeType(
     const std::string& mimeType) {
-  SetResult(base::MakeUnique<base::StringValue>(mimeType));
+  SetResult(base::MakeUnique<base::Value>(mimeType));
   SendResponse(true);
 }
 
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_mount.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_mount.cc
index 550715d..c165bda 100644
--- a/chrome/browser/chromeos/extensions/file_manager/private_api_mount.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/private_api_mount.cc
@@ -155,7 +155,7 @@
   }
 
   // Pass back the actual source path of the mount point.
-  SetResult(base::MakeUnique<base::StringValue>(file_path.AsUTF8Unsafe()));
+  SetResult(base::MakeUnique<base::Value>(file_path.AsUTF8Unsafe()));
   SendResponse(true);
 
   // MountPath() takes a std::string.
diff --git a/chrome/browser/chromeos/extensions/info_private_api.cc b/chrome/browser/chromeos/extensions/info_private_api.cc
index 0f32d49..66041e7b 100644
--- a/chrome/browser/chromeos/extensions/info_private_api.cc
+++ b/chrome/browser/chromeos/extensions/info_private_api.cc
@@ -225,7 +225,7 @@
     chromeos::system::StatisticsProvider* provider =
         chromeos::system::StatisticsProvider::GetInstance();
     provider->GetMachineStatistic(chromeos::system::kHardwareClassKey, &hwid);
-    return new base::StringValue(hwid);
+    return new base::Value(hwid);
   }
 
   if (property_name == kPropertyCustomizationID) {
@@ -234,7 +234,7 @@
         chromeos::system::StatisticsProvider::GetInstance();
     provider->GetMachineStatistic(chromeos::system::kCustomizationIdKey,
                                   &customization_id);
-    return new base::StringValue(customization_id);
+    return new base::Value(customization_id);
   }
 
   if (property_name == kPropertyHomeProvider) {
@@ -244,16 +244,15 @@
     std::string home_provider_id;
     if (cellular_device)
       home_provider_id = cellular_device->home_provider_id();
-    return new base::StringValue(home_provider_id);
+    return new base::Value(home_provider_id);
   }
 
   if (property_name == kPropertyInitialLocale) {
-    return new base::StringValue(
-        chromeos::StartupUtils::GetInitialLocale());
+    return new base::Value(chromeos::StartupUtils::GetInitialLocale());
   }
 
   if (property_name == kPropertyBoard) {
-    return new base::StringValue(base::SysInfo::GetLsbReleaseBoard());
+    return new base::Value(base::SysInfo::GetLsbReleaseBoard());
   }
 
   if (property_name == kPropertyOwner) {
@@ -263,31 +262,31 @@
 
   if (property_name == kPropertySessionType) {
     if (ExtensionsBrowserClient::Get()->IsRunningInForcedAppMode())
-      return new base::StringValue(kSessionTypeKiosk);
+      return new base::Value(kSessionTypeKiosk);
     if (ExtensionsBrowserClient::Get()->IsLoggedInAsPublicAccount())
-      return new base::StringValue(kSessionTypePublicSession);
-    return new base::StringValue(kSessionTypeNormal);
+      return new base::Value(kSessionTypePublicSession);
+    return new base::Value(kSessionTypeNormal);
   }
 
   if (property_name == kPropertyPlayStoreStatus) {
     if (arc::IsArcAllowedForProfile(Profile::FromBrowserContext(context_)))
-      return new base::StringValue(kPlayStoreStatusEnabled);
+      return new base::Value(kPlayStoreStatusEnabled);
     if (arc::IsArcAvailable())
-      return new base::StringValue(kPlayStoreStatusAvailable);
-    return new base::StringValue(kPlayStoreStatusNotAvailable);
+      return new base::Value(kPlayStoreStatusAvailable);
+    return new base::Value(kPlayStoreStatusNotAvailable);
   }
 
   if (property_name == kPropertyManagedDeviceStatus) {
     policy::BrowserPolicyConnectorChromeOS* connector =
         g_browser_process->platform_part()->browser_policy_connector_chromeos();
     if (connector->IsEnterpriseManaged()) {
-      return new base::StringValue(kManagedDeviceStatusManaged);
+      return new base::Value(kManagedDeviceStatusManaged);
     }
-    return new base::StringValue(kManagedDeviceStatusNotManaged);
+    return new base::Value(kManagedDeviceStatusNotManaged);
   }
 
   if (property_name == kPropertyClientId) {
-    return new base::StringValue(GetClientId());
+    return new base::Value(GetClientId());
   }
 
   if (property_name == kPropertyTimezone) {
@@ -325,7 +324,7 @@
     std::string param_value;
     EXTENSION_FUNCTION_VALIDATE(args_->GetString(1, &param_value));
     chromeos::CrosSettings::Get()->Set(chromeos::kSystemTimezone,
-                                       base::StringValue(param_value));
+                                       base::Value(param_value));
   } else {
     const char* pref_name = GetBoolPrefNameForApiProperty(param_name.c_str());
     if (pref_name) {
diff --git a/chrome/browser/chromeos/extensions/info_private_apitest.cc b/chrome/browser/chromeos/extensions/info_private_apitest.cc
index 7036c32..0296446b 100644
--- a/chrome/browser/chromeos/extensions/info_private_apitest.cc
+++ b/chrome/browser/chromeos/extensions/info_private_apitest.cc
@@ -37,7 +37,7 @@
 IN_PROC_BROWSER_TEST_F(ChromeOSInfoPrivateTest, TestGetAndSet) {
   // Set the initial timezone different from what JS function
   // timezoneSetTest() will attempt to set.
-  base::StringValue initial_timezone("America/Los_Angeles");
+  base::Value initial_timezone("America/Los_Angeles");
   chromeos::CrosSettings::Get()->Set(chromeos::kSystemTimezone,
                                      initial_timezone);
 
diff --git a/chrome/browser/chromeos/extensions/input_method_api.cc b/chrome/browser/chromeos/extensions/input_method_api.cc
index 567a2717..610a0ca713 100644
--- a/chrome/browser/chromeos/extensions/input_method_api.cc
+++ b/chrome/browser/chromeos/extensions/input_method_api.cc
@@ -98,7 +98,7 @@
 #else
   chromeos::input_method::InputMethodManager* manager =
       chromeos::input_method::InputMethodManager::Get();
-  return RespondNow(OneArgument(base::MakeUnique<base::StringValue>(
+  return RespondNow(OneArgument(base::MakeUnique<base::Value>(
       manager->GetActiveIMEState()->GetCurrentInputMethod().id())));
 #endif
 }
diff --git a/chrome/browser/chromeos/extensions/users_private/users_private_api.cc b/chrome/browser/chromeos/extensions/users_private/users_private_api.cc
index ca37053f..4026e98 100644
--- a/chrome/browser/chromeos/extensions/users_private/users_private_api.cc
+++ b/chrome/browser/chromeos/extensions/users_private/users_private_api.cc
@@ -85,8 +85,8 @@
   user_manager::UserManager* user_manager = user_manager::UserManager::Get();
   const user_manager::UserList& users = user_manager->GetUsers();
   for (const auto* user : users) {
-    email_list->AppendIfNotPresent(base::MakeUnique<base::StringValue>(
-        user->GetAccountId().GetUserEmail()));
+    email_list->AppendIfNotPresent(
+        base::MakeUnique<base::Value>(user->GetAccountId().GetUserEmail()));
   }
 
   if (chromeos::OwnerSettingsServiceChromeOS* service =
@@ -137,7 +137,7 @@
     return RespondNow(OneArgument(base::MakeUnique<base::Value>(false)));
   }
 
-  base::StringValue username_value(username);
+  base::Value username_value(username);
 
   UsersPrivateDelegate* delegate =
       UsersPrivateDelegateFactory::GetForBrowserContext(browser_context());
@@ -171,7 +171,7 @@
     return RespondNow(OneArgument(base::MakeUnique<base::Value>(false)));
   }
 
-  base::StringValue canonical_email(gaia::CanonicalizeEmail(parameters->email));
+  base::Value canonical_email(gaia::CanonicalizeEmail(parameters->email));
 
   UsersPrivateDelegate* delegate =
       UsersPrivateDelegateFactory::GetForBrowserContext(browser_context());
diff --git a/chrome/browser/chromeos/file_manager/file_tasks.cc b/chrome/browser/chromeos/file_manager/file_tasks.cc
index fe086cd0..10ce4d3 100644
--- a/chrome/browser/chromeos/file_manager/file_tasks.cc
+++ b/chrome/browser/chromeos/file_manager/file_tasks.cc
@@ -198,7 +198,7 @@
                                         prefs::kDefaultTasksByMimeType);
     for (std::set<std::string>::const_iterator iter = mime_types.begin();
         iter != mime_types.end(); ++iter) {
-      base::StringValue* value = new base::StringValue(task_id);
+      base::Value* value = new base::Value(task_id);
       mime_type_pref->SetWithoutPathExpansion(*iter, value);
     }
   }
@@ -208,7 +208,7 @@
                                         prefs::kDefaultTasksBySuffix);
     for (std::set<std::string>::const_iterator iter = suffixes.begin();
         iter != suffixes.end(); ++iter) {
-      base::StringValue* value = new base::StringValue(task_id);
+      base::Value* value = new base::Value(task_id);
       // Suffixes are case insensitive.
       std::string lower_suffix = base::ToLowerASCII(*iter);
       mime_type_pref->SetWithoutPathExpansion(lower_suffix, value);
diff --git a/chrome/browser/chromeos/file_manager/volume_manager.cc b/chrome/browser/chromeos/file_manager/volume_manager.cc
index 76f4a5ed..a780ec4 100644
--- a/chrome/browser/chromeos/file_manager/volume_manager.cc
+++ b/chrome/browser/chromeos/file_manager/volume_manager.cc
@@ -167,10 +167,10 @@
 }
 
 // static
-Volume* Volume::CreateForDrive(Profile* profile) {
+std::unique_ptr<Volume> Volume::CreateForDrive(Profile* profile) {
   const base::FilePath& drive_path =
       drive::util::GetDriveMountPointPath(profile);
-  Volume* const volume = new Volume;
+  std::unique_ptr<Volume> volume(new Volume());
   volume->type_ = VOLUME_TYPE_GOOGLE_DRIVE;
   volume->device_type_ = chromeos::DEVICE_TYPE_UNKNOWN;
   volume->source_path_ = drive_path;
@@ -183,8 +183,9 @@
 }
 
 // static
-Volume* Volume::CreateForDownloads(const base::FilePath& downloads_path) {
-  Volume* const volume = new Volume;
+std::unique_ptr<Volume> Volume::CreateForDownloads(
+    const base::FilePath& downloads_path) {
+  std::unique_ptr<Volume> volume(new Volume());
   volume->type_ = VOLUME_TYPE_DOWNLOADS_DIRECTORY;
   volume->device_type_ = chromeos::DEVICE_TYPE_UNKNOWN;
   // Keep source_path empty.
@@ -197,10 +198,10 @@
 }
 
 // static
-Volume* Volume::CreateForRemovable(
+std::unique_ptr<Volume> Volume::CreateForRemovable(
     const chromeos::disks::DiskMountManager::MountPointInfo& mount_point,
     const chromeos::disks::DiskMountManager::Disk* disk) {
-  Volume* const volume = new Volume;
+  std::unique_ptr<Volume> volume(new Volume());
   volume->type_ = MountTypeToVolumeType(mount_point.mount_type);
   volume->source_path_ = base::FilePath(mount_point.source_path);
   volume->source_ = mount_point.mount_type == chromeos::MOUNT_TYPE_ARCHIVE
@@ -227,11 +228,11 @@
 }
 
 // static
-Volume* Volume::CreateForProvidedFileSystem(
+std::unique_ptr<Volume> Volume::CreateForProvidedFileSystem(
     const chromeos::file_system_provider::ProvidedFileSystemInfo&
         file_system_info,
     MountContext mount_context) {
-  Volume* const volume = new Volume;
+  std::unique_ptr<Volume> volume(new Volume());
   volume->file_system_id_ = file_system_info.file_system_id();
   volume->extension_id_ = file_system_info.extension_id();
   switch (file_system_info.source()) {
@@ -259,10 +260,10 @@
 }
 
 // static
-Volume* Volume::CreateForMTP(const base::FilePath& mount_path,
-                             const std::string& label,
-                             bool read_only) {
-  Volume* const volume = new Volume;
+std::unique_ptr<Volume> Volume::CreateForMTP(const base::FilePath& mount_path,
+                                             const std::string& label,
+                                             bool read_only) {
+  std::unique_ptr<Volume> volume(new Volume());
   volume->type_ = VOLUME_TYPE_MTP;
   volume->mount_path_ = mount_path;
   volume->mount_condition_ = chromeos::disks::MOUNT_CONDITION_NONE;
@@ -277,8 +278,9 @@
 }
 
 // static
-Volume* Volume::CreateForMediaView(const std::string& root_document_id) {
-  Volume* const volume = new Volume;
+std::unique_ptr<Volume> Volume::CreateForMediaView(
+    const std::string& root_document_id) {
+  std::unique_ptr<Volume> volume(new Volume());
   volume->type_ = VOLUME_TYPE_MEDIA_VIEW;
   volume->device_type_ = chromeos::DEVICE_TYPE_UNKNOWN;
   volume->source_ = SOURCE_SYSTEM;
@@ -293,11 +295,12 @@
 }
 
 // static
-Volume* Volume::CreateForTesting(const base::FilePath& path,
-                                 VolumeType volume_type,
-                                 chromeos::DeviceType device_type,
-                                 bool read_only) {
-  Volume* const volume = new Volume;
+std::unique_ptr<Volume> Volume::CreateForTesting(
+    const base::FilePath& path,
+    VolumeType volume_type,
+    chromeos::DeviceType device_type,
+    bool read_only) {
+  std::unique_ptr<Volume> volume(new Volume());
   volume->type_ = volume_type;
   volume->device_type_ = device_type;
   // Keep source_path empty.
@@ -310,9 +313,10 @@
 }
 
 // static
-Volume* Volume::CreateForTesting(const base::FilePath& device_path,
-                                 const base::FilePath& mount_path) {
-  Volume* const volume = new Volume;
+std::unique_ptr<Volume> Volume::CreateForTesting(
+    const base::FilePath& device_path,
+    const base::FilePath& mount_path) {
+  std::unique_ptr<Volume> volume(new Volume());
   volume->system_path_prefix_ = device_path;
   volume->mount_path_ = mount_path;
   return volume;
@@ -354,14 +358,14 @@
   DCHECK(success);
 
   DoMountEvent(chromeos::MOUNT_ERROR_NONE,
-               make_linked_ptr(Volume::CreateForDownloads(downloads)));
+               Volume::CreateForDownloads(downloads));
 
   // Subscribe to DriveIntegrationService.
   if (drive_integration_service_) {
     drive_integration_service_->AddObserver(this);
     if (drive_integration_service_->IsMounted()) {
       DoMountEvent(chromeos::MOUNT_ERROR_NONE,
-                   make_linked_ptr(Volume::CreateForDrive(profile_)));
+                   Volume::CreateForDrive(profile_));
     }
   }
 
@@ -381,9 +385,9 @@
     std::vector<ProvidedFileSystemInfo> file_system_info_list =
         file_system_provider_service_->GetProvidedFileSystemInfoList();
     for (size_t i = 0; i < file_system_info_list.size(); ++i) {
-      linked_ptr<Volume> volume(Volume::CreateForProvidedFileSystem(
-          file_system_info_list[i], MOUNT_CONTEXT_AUTO));
-      DoMountEvent(chromeos::MOUNT_ERROR_NONE, volume);
+      std::unique_ptr<Volume> volume = Volume::CreateForProvidedFileSystem(
+          file_system_info_list[i], MOUNT_CONTEXT_AUTO);
+      DoMountEvent(chromeos::MOUNT_ERROR_NONE, std::move(volume));
     }
   }
 
@@ -456,6 +460,7 @@
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
   std::vector<base::WeakPtr<Volume>> result;
+  result.reserve(mounted_volumes_.size());
   for (const auto& pair : mounted_volumes_) {
     result.push_back(pair.second->AsWeakPtr());
   }
@@ -479,13 +484,13 @@
   base::FilePath old_path;
   if (FindDownloadsMountPointPath(profile_, &old_path)) {
     DoUnmountEvent(chromeos::MOUNT_ERROR_NONE,
-                   make_linked_ptr(Volume::CreateForDownloads(old_path)));
+                   *Volume::CreateForDownloads(old_path));
   }
 
   bool success = RegisterDownloadsMountPoint(profile_, path);
   DoMountEvent(
       success ? chromeos::MOUNT_ERROR_NONE : chromeos::MOUNT_ERROR_INVALID_PATH,
-      make_linked_ptr(Volume::CreateForDownloads(path)));
+      Volume::CreateForDownloads(path));
   return success;
 }
 
@@ -494,14 +499,14 @@
                                         chromeos::DeviceType device_type,
                                         bool read_only) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  DoMountEvent(chromeos::MOUNT_ERROR_NONE,
-               make_linked_ptr(Volume::CreateForTesting(
-                   path, volume_type, device_type, read_only)));
+  DoMountEvent(
+      chromeos::MOUNT_ERROR_NONE,
+      Volume::CreateForTesting(path, volume_type, device_type, read_only));
 }
 
-void VolumeManager::AddVolumeForTesting(const linked_ptr<Volume>& volume) {
+void VolumeManager::AddVolumeForTesting(std::unique_ptr<Volume> volume) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  DoMountEvent(chromeos::MOUNT_ERROR_NONE, volume);
+  DoMountEvent(chromeos::MOUNT_ERROR_NONE, std::move(volume));
 }
 
 void VolumeManager::OnFileSystemMounted() {
@@ -510,15 +515,13 @@
   // Raise mount event.
   // We can pass chromeos::MOUNT_ERROR_NONE even when authentication is failed
   // or network is unreachable. These two errors will be handled later.
-  linked_ptr<Volume> volume(Volume::CreateForDrive(profile_));
-  DoMountEvent(chromeos::MOUNT_ERROR_NONE, volume);
+  DoMountEvent(chromeos::MOUNT_ERROR_NONE, Volume::CreateForDrive(profile_));
 }
 
 void VolumeManager::OnFileSystemBeingUnmounted() {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
-  linked_ptr<Volume> volume(Volume::CreateForDrive(profile_));
-  DoUnmountEvent(chromeos::MOUNT_ERROR_NONE, volume);
+  DoUnmountEvent(chromeos::MOUNT_ERROR_NONE, *Volume::CreateForDrive(profile_));
 }
 
 void VolumeManager::OnDiskEvent(
@@ -628,14 +631,14 @@
   // Notify a mounting/unmounting event to observers.
   const chromeos::disks::DiskMountManager::Disk* const disk =
       disk_mount_manager_->FindDiskBySourcePath(mount_info.source_path);
-  linked_ptr<Volume> volume(Volume::CreateForRemovable(mount_info, disk));
+  std::unique_ptr<Volume> volume = Volume::CreateForRemovable(mount_info, disk);
   switch (event) {
     case chromeos::disks::DiskMountManager::MOUNTING: {
-      DoMountEvent(error_code, volume);
+      DoMountEvent(error_code, std::move(volume));
       return;
     }
     case chromeos::disks::DiskMountManager::UNMOUNTING:
-      DoUnmountEvent(error_code, volume);
+      DoUnmountEvent(error_code, *volume);
       return;
   }
   NOTREACHED();
@@ -693,8 +696,8 @@
       break;
   }
 
-  linked_ptr<Volume> volume(
-      Volume::CreateForProvidedFileSystem(file_system_info, volume_context));
+  std::unique_ptr<Volume> volume =
+      Volume::CreateForProvidedFileSystem(file_system_info, volume_context);
 
   // TODO(mtomasz): Introduce own type, and avoid using MountError internally,
   // since it is related to cros disks only.
@@ -711,7 +714,7 @@
       break;
   }
 
-  DoMountEvent(mount_error, volume);
+  DoMountEvent(mount_error, std::move(volume));
 }
 
 void VolumeManager::OnProvidedFileSystemUnmount(
@@ -723,9 +726,9 @@
   const chromeos::MountError mount_error = error == base::File::FILE_OK
                                                ? chromeos::MOUNT_ERROR_NONE
                                                : chromeos::MOUNT_ERROR_UNKNOWN;
-  linked_ptr<Volume> volume(Volume::CreateForProvidedFileSystem(
-      file_system_info, MOUNT_CONTEXT_UNKNOWN));
-  DoUnmountEvent(mount_error, volume);
+  std::unique_ptr<Volume> volume = Volume::CreateForProvidedFileSystem(
+      file_system_info, MOUNT_CONTEXT_UNKNOWN);
+  DoUnmountEvent(mount_error, *volume);
 }
 
 void VolumeManager::OnExternalStorageDisabledChangedUnmountCallback(
@@ -752,24 +755,18 @@
 
   if (enabled) {
     DoMountEvent(chromeos::MOUNT_ERROR_NONE,
-                 linked_ptr<Volume>(
-                     Volume::CreateForMediaView(arc::kImagesRootDocumentId)));
+                 Volume::CreateForMediaView(arc::kImagesRootDocumentId));
     DoMountEvent(chromeos::MOUNT_ERROR_NONE,
-                 linked_ptr<Volume>(
-                     Volume::CreateForMediaView(arc::kVideosRootDocumentId)));
+                 Volume::CreateForMediaView(arc::kVideosRootDocumentId));
     DoMountEvent(chromeos::MOUNT_ERROR_NONE,
-                 linked_ptr<Volume>(
-                     Volume::CreateForMediaView(arc::kAudioRootDocumentId)));
+                 Volume::CreateForMediaView(arc::kAudioRootDocumentId));
   } else {
     DoUnmountEvent(chromeos::MOUNT_ERROR_NONE,
-                   linked_ptr<Volume>(
-                       Volume::CreateForMediaView(arc::kImagesRootDocumentId)));
+                   *Volume::CreateForMediaView(arc::kImagesRootDocumentId));
     DoUnmountEvent(chromeos::MOUNT_ERROR_NONE,
-                   linked_ptr<Volume>(
-                       Volume::CreateForMediaView(arc::kVideosRootDocumentId)));
+                   *Volume::CreateForMediaView(arc::kVideosRootDocumentId));
     DoUnmountEvent(chromeos::MOUNT_ERROR_NONE,
-                   linked_ptr<Volume>(
-                       Volume::CreateForMediaView(arc::kAudioRootDocumentId)));
+                   *Volume::CreateForMediaView(arc::kAudioRootDocumentId));
   }
 
   arc_volumes_mounted_ = enabled;
@@ -857,8 +854,8 @@
                  base::Unretained(MTPDeviceMapService::GetInstance()),
                  info.location(), fsid, read_only));
 
-  linked_ptr<Volume> volume(Volume::CreateForMTP(path, label, read_only));
-  DoMountEvent(chromeos::MOUNT_ERROR_NONE, volume);
+  std::unique_ptr<Volume> volume = Volume::CreateForMTP(path, label, read_only);
+  DoMountEvent(chromeos::MOUNT_ERROR_NONE, std::move(volume));
 }
 
 void VolumeManager::OnRemovableStorageDetached(
@@ -866,9 +863,9 @@
   if (!storage_monitor::StorageInfo::IsMTPDevice(info.device_id()))
     return;
 
-  for (const auto mounted_volume : mounted_volumes_) {
+  for (const auto& mounted_volume : mounted_volumes_) {
     if (mounted_volume.second->source_path().value() == info.location()) {
-      DoUnmountEvent(chromeos::MOUNT_ERROR_NONE, mounted_volume.second);
+      DoUnmountEvent(chromeos::MOUNT_ERROR_NONE, *mounted_volume.second.get());
 
       const std::string fsid = GetMountPointNameForMediaStorage(info);
       storage::ExternalMountPoints::GetSystemInstance()->RevokeFileSystem(fsid);
@@ -888,7 +885,7 @@
     return;
   }
 
-  std::vector<linked_ptr<Volume>> archives;
+  std::vector<std::unique_ptr<Volume>> archives;
 
   const chromeos::disks::DiskMountManager::MountPointMap& mount_points =
       disk_mount_manager_->mount_points();
@@ -898,14 +895,13 @@
        ++it) {
     if (it->second.mount_type == chromeos::MOUNT_TYPE_ARCHIVE) {
       // Archives are mounted after other types of volume. See below.
-      archives.push_back(
-          make_linked_ptr(Volume::CreateForRemovable(it->second, NULL)));
+      archives.push_back(Volume::CreateForRemovable(it->second, nullptr));
       continue;
     }
     DoMountEvent(chromeos::MOUNT_ERROR_NONE,
-                 make_linked_ptr(Volume::CreateForRemovable(
+                 Volume::CreateForRemovable(
                      it->second, disk_mount_manager_->FindDiskBySourcePath(
-                                     it->second.source_path))));
+                                     it->second.source_path)));
   }
 
   // We mount archives only if they are opened from currently mounted volumes.
@@ -915,24 +911,26 @@
     if (done[i])
       continue;
 
-    std::vector<linked_ptr<Volume>> chain;
+    std::vector<std::unique_ptr<Volume>> chain;
+    // done[x] = true means archives[x] is null and that volume is in |chain|.
     done[i] = true;
-    chain.push_back(archives[i]);
+    chain.push_back(std::move(archives[i]));
 
     // If archives[i]'s source_path is in another archive, mount it first.
     for (size_t parent = i + 1; parent < archives.size(); ++parent) {
       if (!done[parent] &&
           archives[parent]->mount_path().IsParent(
               chain.back()->source_path())) {
+        // done[parent] started false, so archives[parent] is non-null.
         done[parent] = true;
-        chain.push_back(archives[parent]);
+        chain.push_back(std::move(archives[parent]));
         parent = i + 1;  // Search archives[parent]'s parent from the beginning.
       }
     }
 
     // Mount from the tail of chain.
     for (size_t i = chain.size(); i > 0; --i) {
-      DoMountEvent(chromeos::MOUNT_ERROR_NONE, chain[i - 1]);
+      DoMountEvent(chromeos::MOUNT_ERROR_NONE, std::move(chain[i - 1]));
     }
   }
 }
@@ -946,7 +944,7 @@
 }
 
 void VolumeManager::DoMountEvent(chromeos::MountError error_code,
-                                 const linked_ptr<Volume>& volume) {
+                                 std::unique_ptr<Volume> volume) {
   // Archive files are mounted globally in system. We however don't want to show
   // archives from profile-specific folders (Drive/Downloads) of other users in
   // multi-profile session. To this end, we filter out archives not on the
@@ -971,25 +969,32 @@
     return;
   }
 
+  Volume* raw_volume = volume.get();
   if (error_code == chromeos::MOUNT_ERROR_NONE || volume->mount_condition()) {
-    mounted_volumes_[volume->volume_id()] = volume;
-    UMA_HISTOGRAM_ENUMERATION("FileBrowser.VolumeType", volume->type(),
+    mounted_volumes_[volume->volume_id()] = std::move(volume);
+    UMA_HISTOGRAM_ENUMERATION("FileBrowser.VolumeType", raw_volume->type(),
                               NUM_VOLUME_TYPE);
   }
 
   for (auto& observer : observers_)
-    observer.OnVolumeMounted(error_code, *volume);
+    observer.OnVolumeMounted(error_code, *raw_volume);
 }
 
 void VolumeManager::DoUnmountEvent(chromeos::MountError error_code,
-                                   const linked_ptr<Volume>& volume) {
-  if (mounted_volumes_.find(volume->volume_id()) == mounted_volumes_.end())
+                                   const Volume& volume) {
+  auto iter = mounted_volumes_.find(volume.volume_id());
+  if (iter == mounted_volumes_.end())
     return;
-  if (error_code == chromeos::MOUNT_ERROR_NONE)
-    mounted_volumes_.erase(volume->volume_id());
+  std::unique_ptr<Volume> volume_ref;
+  if (error_code == chromeos::MOUNT_ERROR_NONE) {
+    // It is important to hold a reference to the removed Volume from
+    // |mounted_volumes_|, because OnVolumeMounted() will access it.
+    volume_ref = std::move(iter->second);
+    mounted_volumes_.erase(iter);
+  }
 
   for (auto& observer : observers_)
-    observer.OnVolumeUnmounted(error_code, *volume.get());
+    observer.OnVolumeUnmounted(error_code, volume);
 }
 
 }  // namespace file_manager
diff --git a/chrome/browser/chromeos/file_manager/volume_manager.h b/chrome/browser/chromeos/file_manager/volume_manager.h
index 46014daf..1658d149 100644
--- a/chrome/browser/chromeos/file_manager/volume_manager.h
+++ b/chrome/browser/chromeos/file_manager/volume_manager.h
@@ -14,7 +14,6 @@
 #include "base/files/file.h"
 #include "base/files/file_path.h"
 #include "base/macros.h"
-#include "base/memory/linked_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/observer_list.h"
 #include "chrome/browser/chromeos/arc/arc_session_manager.h"
@@ -80,25 +79,29 @@
   ~Volume();
 
   // Factory static methods for different volume types.
-  static Volume* CreateForDrive(Profile* profile);
-  static Volume* CreateForDownloads(const base::FilePath& downloads_path);
-  static Volume* CreateForRemovable(
+  static std::unique_ptr<Volume> CreateForDrive(Profile* profile);
+  static std::unique_ptr<Volume> CreateForDownloads(
+      const base::FilePath& downloads_path);
+  static std::unique_ptr<Volume> CreateForRemovable(
       const chromeos::disks::DiskMountManager::MountPointInfo& mount_point,
       const chromeos::disks::DiskMountManager::Disk* disk);
-  static Volume* CreateForProvidedFileSystem(
+  static std::unique_ptr<Volume> CreateForProvidedFileSystem(
       const chromeos::file_system_provider::ProvidedFileSystemInfo&
           file_system_info,
       MountContext mount_context);
-  static Volume* CreateForMTP(const base::FilePath& mount_path,
-                              const std::string& label,
-                              bool read_only);
-  static Volume* CreateForMediaView(const std::string& root_document_id);
-  static Volume* CreateForTesting(const base::FilePath& path,
-                                  VolumeType volume_type,
-                                  chromeos::DeviceType device_type,
-                                  bool read_only);
-  static Volume* CreateForTesting(const base::FilePath& device_path,
-                                  const base::FilePath& mount_path);
+  static std::unique_ptr<Volume> CreateForMTP(const base::FilePath& mount_path,
+                                              const std::string& label,
+                                              bool read_only);
+  static std::unique_ptr<Volume> CreateForMediaView(
+      const std::string& root_document_id);
+  static std::unique_ptr<Volume> CreateForTesting(
+      const base::FilePath& path,
+      VolumeType volume_type,
+      chromeos::DeviceType device_type,
+      bool read_only);
+  static std::unique_ptr<Volume> CreateForTesting(
+      const base::FilePath& device_path,
+      const base::FilePath& mount_path);
 
   // Getters for all members. See below for details.
   const std::string& volume_id() const { return volume_id_; }
@@ -270,7 +273,7 @@
                            bool read_only);
 
   // For testing purpose, adds the volume info to the volume manager.
-  void AddVolumeForTesting(const linked_ptr<Volume>& volume);
+  void AddVolumeForTesting(std::unique_ptr<Volume> volume);
 
   // drive::DriveIntegrationServiceObserver overrides.
   void OnFileSystemMounted() override;
@@ -322,9 +325,8 @@
   void OnDiskMountManagerRefreshed(bool success);
   void OnStorageMonitorInitialized();
   void DoMountEvent(chromeos::MountError error_code,
-                    const linked_ptr<Volume>& volume);
-  void DoUnmountEvent(chromeos::MountError error_code,
-                      const linked_ptr<Volume>& volume);
+                    std::unique_ptr<Volume> volume);
+  void DoUnmountEvent(chromeos::MountError error_code, const Volume& volume);
   void OnExternalStorageDisabledChangedUnmountCallback(
       chromeos::MountError error_code);
 
@@ -336,7 +338,7 @@
   chromeos::file_system_provider::Service*
       file_system_provider_service_;  // Not owned by this class.
   GetMtpStorageInfoCallback get_mtp_storage_info_callback_;
-  std::map<std::string, linked_ptr<Volume>> mounted_volumes_;
+  std::map<std::string, std::unique_ptr<Volume>> mounted_volumes_;
   std::unique_ptr<SnapshotManager> snapshot_manager_;
   bool arc_volumes_mounted_ = false;
 
diff --git a/chrome/browser/chromeos/file_system_provider/operations/read_file_unittest.cc b/chrome/browser/chromeos/file_system_provider/operations/read_file_unittest.cc
index 7ef9e41..4578cc69 100644
--- a/chrome/browser/chromeos/file_system_provider/operations/read_file_unittest.cc
+++ b/chrome/browser/chromeos/file_system_provider/operations/read_file_unittest.cc
@@ -175,7 +175,7 @@
   const int execution_time = 0;
 
   base::ListValue value_as_list;
-  value_as_list.Set(0, new base::StringValue(kFileSystemId));
+  value_as_list.Set(0, new base::Value(kFileSystemId));
   value_as_list.Set(1, new base::Value(kRequestId));
   value_as_list.Set(
       2, base::BinaryValue::CreateWithCopiedBuffer(data.c_str(), data.size()));
diff --git a/chrome/browser/chromeos/file_system_provider/provided_file_system_unittest.cc b/chrome/browser/chromeos/file_system_provider/provided_file_system_unittest.cc
index 5724b11..6594219 100644
--- a/chrome/browser/chromeos/file_system_provider/provided_file_system_unittest.cc
+++ b/chrome/browser/chromeos/file_system_provider/provided_file_system_unittest.cc
@@ -84,7 +84,7 @@
 
     if (reply_result_ == base::File::FILE_OK) {
       base::ListValue value_as_list;
-      value_as_list.Set(0, new base::StringValue(kFileSystemId));
+      value_as_list.Set(0, new base::Value(kFileSystemId));
       value_as_list.Set(1, new base::Value(request_id));
       value_as_list.Set(2, new base::Value(0) /* execution_time */);
 
diff --git a/chrome/browser/chromeos/login/enrollment/auto_enrollment_check_screen_view.h b/chrome/browser/chromeos/login/enrollment/auto_enrollment_check_screen_view.h
index 3259790..72b475e1 100644
--- a/chrome/browser/chromeos/login/enrollment/auto_enrollment_check_screen_view.h
+++ b/chrome/browser/chromeos/login/enrollment/auto_enrollment_check_screen_view.h
@@ -5,6 +5,8 @@
 #ifndef CHROME_BROWSER_CHROMEOS_LOGIN_ENROLLMENT_AUTO_ENROLLMENT_CHECK_SCREEN_VIEW_H_
 #define CHROME_BROWSER_CHROMEOS_LOGIN_ENROLLMENT_AUTO_ENROLLMENT_CHECK_SCREEN_VIEW_H_
 
+#include "chrome/browser/chromeos/login/oobe_screen.h"
+
 namespace chromeos {
 
 // Interface between auto-enrollment check screen and its representation.
@@ -21,6 +23,9 @@
     virtual void OnViewDestroyed(AutoEnrollmentCheckScreenView* view) = 0;
   };
 
+  constexpr static OobeScreen kScreenId =
+      OobeScreen::SCREEN_AUTO_ENROLLMENT_CHECK;
+
   virtual ~AutoEnrollmentCheckScreenView() {}
 
   virtual void Show() = 0;
diff --git a/chrome/browser/chromeos/login/enrollment/enrollment_screen_view.h b/chrome/browser/chromeos/login/enrollment/enrollment_screen_view.h
index 9b43849..cebbbc34 100644
--- a/chrome/browser/chromeos/login/enrollment/enrollment_screen_view.h
+++ b/chrome/browser/chromeos/login/enrollment/enrollment_screen_view.h
@@ -8,6 +8,7 @@
 #include <string>
 
 #include "chrome/browser/chromeos/login/enrollment/enterprise_enrollment_helper.h"
+#include "chrome/browser/chromeos/login/oobe_screen.h"
 
 class GoogleServiceAuthError;
 
@@ -37,6 +38,8 @@
                                            const std::string& location) = 0;
   };
 
+  constexpr static OobeScreen kScreenId = OobeScreen::SCREEN_OOBE_ENROLLMENT;
+
   virtual ~EnrollmentScreenView() {}
 
   // Initializes the view with parameters.
diff --git a/chrome/browser/chromeos/login/existing_user_controller_browsertest.cc b/chrome/browser/chromeos/login/existing_user_controller_browsertest.cc
index 1dd4d53..9566108f 100644
--- a/chrome/browser/chromeos/login/existing_user_controller_browsertest.cc
+++ b/chrome/browser/chromeos/login/existing_user_controller_browsertest.cc
@@ -200,8 +200,7 @@
   void RegisterUser(const std::string& user_id) {
     ListPrefUpdate users_pref(g_browser_process->local_state(),
                               "LoggedInUsers");
-    users_pref->AppendIfNotPresent(
-        base::MakeUnique<base::StringValue>(user_id));
+    users_pref->AppendIfNotPresent(base::MakeUnique<base::Value>(user_id));
   }
 
   // ExistingUserController private member accessors.
diff --git a/chrome/browser/chromeos/login/helper.cc b/chrome/browser/chromeos/login/helper.cc
index 1b7e3a2..d8d5a60a 100644
--- a/chrome/browser/chromeos/login/helper.cc
+++ b/chrome/browser/chromeos/login/helper.cc
@@ -170,11 +170,11 @@
   std::unique_ptr<base::DictionaryValue> copied_onc(
       new base::DictionaryValue());
   copied_onc->Set(onc::toplevel_config::kType,
-                  new base::StringValue(onc::network_type::kWiFi));
+                  new base::Value(onc::network_type::kWiFi));
   copied_onc->Set(onc::network_config::WifiProperty(onc::wifi::kHexSSID),
-                  new base::StringValue(hex_ssid));
+                  new base::Value(hex_ssid));
   copied_onc->Set(onc::network_config::WifiProperty(onc::wifi::kSecurity),
-                  new base::StringValue(security));
+                  new base::Value(security));
   base::JSONWriter::Write(*copied_onc.get(), out_onc_spec);
 }
 
diff --git a/chrome/browser/chromeos/login/kiosk_browsertest.cc b/chrome/browser/chromeos/login/kiosk_browsertest.cc
index c340e46..6db4b38 100644
--- a/chrome/browser/chromeos/login/kiosk_browsertest.cc
+++ b/chrome/browser/chromeos/login/kiosk_browsertest.cc
@@ -551,7 +551,7 @@
     bool new_kiosk_ui = KioskAppMenuHandler::EnableNewKioskUI();
     GetLoginUI()->CallJavascriptFunctionUnsafe(
         new_kiosk_ui ? kLaunchAppForTestNewAPI : kLaunchAppForTestOldAPI,
-        base::StringValue(app_id), base::Value(diagnostic_mode));
+        base::Value(app_id), base::Value(diagnostic_mode));
   }
 
   void ReloadKioskApps() {
@@ -954,8 +954,7 @@
   OobeScreenWaiter error_screen_waiter(OobeScreen::SCREEN_ERROR_MESSAGE);
   // Simulate Ctrl+Alt+N accelerator.
   GetLoginUI()->CallJavascriptFunctionUnsafe(
-      "cr.ui.Oobe.handleAccelerator",
-      base::StringValue("app_launch_network_config"));
+      "cr.ui.Oobe.handleAccelerator", base::Value("app_launch_network_config"));
   error_screen_waiter.Wait();
   ASSERT_TRUE(GetAppLaunchController()->showing_network_dialog());
 
@@ -1026,8 +1025,8 @@
   content::WindowedNotificationObserver signal(
       chrome::NOTIFICATION_APP_TERMINATING,
       content::NotificationService::AllSources());
-  GetLoginUI()->CallJavascriptFunctionUnsafe(
-      "cr.ui.Oobe.handleAccelerator", base::StringValue("app_launch_bailout"));
+  GetLoginUI()->CallJavascriptFunctionUnsafe("cr.ui.Oobe.handleAccelerator",
+                                             base::Value("app_launch_bailout"));
   signal.Wait();
   EXPECT_EQ(chromeos::KioskAppLaunchError::USER_CANCEL,
             chromeos::KioskAppLaunchError::Get());
@@ -1143,7 +1142,7 @@
   wizard_controller->SkipToLoginForTesting(LoginScreenContext());
   OobeScreenWaiter(OobeScreen::SCREEN_GAIA_SIGNIN).Wait();
   GetLoginUI()->CallJavascriptFunctionUnsafe("cr.ui.Oobe.handleAccelerator",
-                                             base::StringValue("kiosk_enable"));
+                                             base::Value("kiosk_enable"));
 
   // Wait for the kiosk_enable screen to show and cancel the screen.
   content::WindowedNotificationObserver(
@@ -1177,7 +1176,7 @@
   wizard_controller->SkipToLoginForTesting(LoginScreenContext());
   OobeScreenWaiter(OobeScreen::SCREEN_GAIA_SIGNIN).Wait();
   GetLoginUI()->CallJavascriptFunctionUnsafe("cr.ui.Oobe.handleAccelerator",
-                                             base::StringValue("kiosk_enable"));
+                                             base::Value("kiosk_enable"));
 
   // Wait for the kiosk_enable screen to show and cancel the screen.
   content::WindowedNotificationObserver(
@@ -1208,7 +1207,7 @@
   wizard_controller->SkipToLoginForTesting(LoginScreenContext());
   OobeScreenWaiter(OobeScreen::SCREEN_GAIA_SIGNIN).Wait();
   GetLoginUI()->CallJavascriptFunctionUnsafe("cr.ui.Oobe.handleAccelerator",
-                                             base::StringValue("kiosk_enable"));
+                                             base::Value("kiosk_enable"));
 
   // Wait for the kiosk_enable screen to show and cancel the screen.
   content::WindowedNotificationObserver(
@@ -1228,7 +1227,7 @@
 
   // Show kiosk enable screen again.
   GetLoginUI()->CallJavascriptFunctionUnsafe("cr.ui.Oobe.handleAccelerator",
-                                             base::StringValue("kiosk_enable"));
+                                             base::Value("kiosk_enable"));
 
   // And it should show up.
   content::WindowedNotificationObserver(
diff --git a/chrome/browser/chromeos/login/login_manager_test.cc b/chrome/browser/chromeos/login/login_manager_test.cc
index 354f2dc..cc76175 100644
--- a/chrome/browser/chromeos/login/login_manager_test.cc
+++ b/chrome/browser/chromeos/login/login_manager_test.cc
@@ -156,7 +156,7 @@
 
 void LoginManagerTest::RegisterUser(const std::string& user_id) {
   ListPrefUpdate users_pref(g_browser_process->local_state(), "LoggedInUsers");
-  users_pref->AppendIfNotPresent(base::MakeUnique<base::StringValue>(user_id));
+  users_pref->AppendIfNotPresent(base::MakeUnique<base::Value>(user_id));
 }
 
 void LoginManagerTest::SetExpectedCredentials(const UserContext& user_context) {
@@ -201,6 +201,8 @@
   const UserContext user_context = CreateUserContext(user_id);
   SetExpectedCredentials(user_context);
   EXPECT_TRUE(TryToLogin(user_context));
+  // Let LoginDisplayHostImpl delete itself.
+  content::RunAllPendingInMessageLoop();
 }
 
 void LoginManagerTest::AddUser(const std::string& user_id) {
diff --git a/chrome/browser/chromeos/login/quick_unlock/quick_unlock_utils.cc b/chrome/browser/chromeos/login/quick_unlock/quick_unlock_utils.cc
index 269bbf7..a70a11a 100644
--- a/chrome/browser/chromeos/login/quick_unlock/quick_unlock_utils.cc
+++ b/chrome/browser/chromeos/login/quick_unlock/quick_unlock_utils.cc
@@ -68,8 +68,8 @@
   // Check if policy allows PIN.
   const base::ListValue* quick_unlock_whitelist =
       pref_service->GetList(prefs::kQuickUnlockModeWhitelist);
-  base::StringValue all_value(kQuickUnlockWhitelistOptionAll);
-  base::StringValue pin_value(kQuickUnlockWhitelistOptionPin);
+  base::Value all_value(kQuickUnlockWhitelistOptionAll);
+  base::Value pin_value(kQuickUnlockWhitelistOptionPin);
   if (quick_unlock_whitelist->Find(all_value) ==
           quick_unlock_whitelist->end() &&
       quick_unlock_whitelist->Find(pin_value) ==
diff --git a/chrome/browser/chromeos/login/screens/app_launch_splash_screen_view.h b/chrome/browser/chromeos/login/screens/app_launch_splash_screen_view.h
index d7dcfe8..9f8b104 100644
--- a/chrome/browser/chromeos/login/screens/app_launch_splash_screen_view.h
+++ b/chrome/browser/chromeos/login/screens/app_launch_splash_screen_view.h
@@ -6,6 +6,7 @@
 #define CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_APP_LAUNCH_SPLASH_SCREEN_VIEW_H_
 
 #include "base/strings/string16.h"
+#include "chrome/browser/chromeos/login/oobe_screen.h"
 
 namespace chromeos {
 
@@ -41,6 +42,8 @@
     virtual ~Delegate() {}
   };
 
+  constexpr static OobeScreen kScreenId = OobeScreen::SCREEN_APP_LAUNCH_SPLASH;
+
   virtual ~AppLaunchSplashScreenView() {}
 
   // Sets screen this view belongs to.
diff --git a/chrome/browser/chromeos/login/screens/arc_kiosk_splash_screen_view.h b/chrome/browser/chromeos/login/screens/arc_kiosk_splash_screen_view.h
index 3e96825..e3fc63f 100644
--- a/chrome/browser/chromeos/login/screens/arc_kiosk_splash_screen_view.h
+++ b/chrome/browser/chromeos/login/screens/arc_kiosk_splash_screen_view.h
@@ -5,6 +5,8 @@
 #ifndef CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_ARC_KIOSK_SPLASH_SCREEN_VIEW_H_
 #define CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_ARC_KIOSK_SPLASH_SCREEN_VIEW_H_
 
+#include "chrome/browser/chromeos/login/oobe_screen.h"
+
 namespace chromeos {
 
 // Interface for UI implemenations of the ArcKioskSplashScreen.
@@ -29,6 +31,8 @@
     DISALLOW_COPY_AND_ASSIGN(Delegate);
   };
 
+  constexpr static OobeScreen kScreenId = OobeScreen::SCREEN_ARC_KIOSK_SPLASH;
+
   ArcKioskSplashScreenView() = default;
 
   virtual ~ArcKioskSplashScreenView() = default;
diff --git a/chrome/browser/chromeos/login/screens/arc_terms_of_service_screen_view.h b/chrome/browser/chromeos/login/screens/arc_terms_of_service_screen_view.h
index 7b75f78..68be57c 100644
--- a/chrome/browser/chromeos/login/screens/arc_terms_of_service_screen_view.h
+++ b/chrome/browser/chromeos/login/screens/arc_terms_of_service_screen_view.h
@@ -8,6 +8,7 @@
 #include <string>
 
 #include "base/macros.h"
+#include "chrome/browser/chromeos/login/oobe_screen.h"
 
 namespace chromeos {
 
@@ -17,6 +18,9 @@
 // WebUI representation.
 class ArcTermsOfServiceScreenView {
  public:
+  constexpr static OobeScreen kScreenId =
+      OobeScreen::SCREEN_ARC_TERMS_OF_SERVICE;
+
   virtual ~ArcTermsOfServiceScreenView() = default;
 
   // Adds/Removes observer for view.
diff --git a/chrome/browser/chromeos/login/screens/base_screen.h b/chrome/browser/chromeos/login/screens/base_screen.h
index 8b69691..633021a 100644
--- a/chrome/browser/chromeos/login/screens/base_screen.h
+++ b/chrome/browser/chromeos/login/screens/base_screen.h
@@ -131,7 +131,7 @@
   FRIEND_TEST_ALL_PREFIXES(HandsOffNetworkScreenTest, RequiresNoInput);
   FRIEND_TEST_ALL_PREFIXES(HandsOffNetworkScreenTest, ContinueClickedOnlyOnce);
 
-  friend class BaseScreenHandler;
+  friend class BaseWebUIHandler;
   friend class NetworkScreenTest;
   friend class ScreenEditor;
   friend class ScreenManager;
diff --git a/chrome/browser/chromeos/login/screens/controller_pairing_screen_view.h b/chrome/browser/chromeos/login/screens/controller_pairing_screen_view.h
index 739d4a6..df482a6b 100644
--- a/chrome/browser/chromeos/login/screens/controller_pairing_screen_view.h
+++ b/chrome/browser/chromeos/login/screens/controller_pairing_screen_view.h
@@ -8,6 +8,7 @@
 #include <string>
 
 #include "base/macros.h"
+#include "chrome/browser/chromeos/login/oobe_screen.h"
 
 namespace base {
 class DictionaryValue;
@@ -69,6 +70,9 @@
     virtual void OnUserActed(const std::string& action) = 0;
   };
 
+  constexpr static OobeScreen kScreenId =
+      OobeScreen::SCREEN_OOBE_CONTROLLER_PAIRING;
+
   ControllerPairingScreenView();
   virtual ~ControllerPairingScreenView();
 
diff --git a/chrome/browser/chromeos/login/screens/device_disabled_screen_view.h b/chrome/browser/chromeos/login/screens/device_disabled_screen_view.h
index bd063d7..5a1260d 100644
--- a/chrome/browser/chromeos/login/screens/device_disabled_screen_view.h
+++ b/chrome/browser/chromeos/login/screens/device_disabled_screen_view.h
@@ -6,6 +6,7 @@
 #define CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_DEVICE_DISABLED_SCREEN_VIEW_H_
 
 #include <string>
+#include "chrome/browser/chromeos/login/oobe_screen.h"
 
 namespace chromeos {
 
@@ -28,6 +29,8 @@
     virtual const std::string& GetMessage() const = 0;
   };
 
+  constexpr static OobeScreen kScreenId = OobeScreen::SCREEN_DEVICE_DISABLED;
+
   virtual ~DeviceDisabledScreenView() {}
 
   virtual void Show() = 0;
diff --git a/chrome/browser/chromeos/login/screens/enable_debugging_screen_view.h b/chrome/browser/chromeos/login/screens/enable_debugging_screen_view.h
index 664fbae..821c33ee 100644
--- a/chrome/browser/chromeos/login/screens/enable_debugging_screen_view.h
+++ b/chrome/browser/chromeos/login/screens/enable_debugging_screen_view.h
@@ -6,6 +6,7 @@
 #define CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_ENABLE_DEBUGGING_SCREEN_VIEW_H_
 
 #include <string>
+#include "chrome/browser/chromeos/login/oobe_screen.h"
 
 namespace chromeos {
 
@@ -26,6 +27,9 @@
     virtual void OnViewDestroyed(EnableDebuggingScreenView* view) = 0;
   };
 
+  constexpr static OobeScreen kScreenId =
+      OobeScreen::SCREEN_OOBE_ENABLE_DEBUGGING;
+
   virtual ~EnableDebuggingScreenView() {}
 
   virtual void Show() = 0;
diff --git a/chrome/browser/chromeos/login/screens/eula_view.h b/chrome/browser/chromeos/login/screens/eula_view.h
index 08c0da0f..383f5de8 100644
--- a/chrome/browser/chromeos/login/screens/eula_view.h
+++ b/chrome/browser/chromeos/login/screens/eula_view.h
@@ -6,6 +6,7 @@
 #define CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_EULA_VIEW_H_
 
 #include <string>
+#include "chrome/browser/chromeos/login/oobe_screen.h"
 
 namespace chromeos {
 
@@ -16,6 +17,8 @@
 // dtor.
 class EulaView {
  public:
+  constexpr static OobeScreen kScreenId = OobeScreen::SCREEN_OOBE_EULA;
+
   virtual ~EulaView() {}
 
   virtual void Show() = 0;
diff --git a/chrome/browser/chromeos/login/screens/gaia_view.h b/chrome/browser/chromeos/login/screens/gaia_view.h
index 04af20e..28532c2 100644
--- a/chrome/browser/chromeos/login/screens/gaia_view.h
+++ b/chrome/browser/chromeos/login/screens/gaia_view.h
@@ -10,11 +10,14 @@
 #include "base/bind.h"
 #include "base/compiler_specific.h"
 #include "base/macros.h"
+#include "chrome/browser/chromeos/login/oobe_screen.h"
 
 namespace chromeos {
 
 class GaiaView {
  public:
+  constexpr static OobeScreen kScreenId = OobeScreen::SCREEN_GAIA_SIGNIN;
+
   GaiaView() = default;
   virtual ~GaiaView() = default;
 
diff --git a/chrome/browser/chromeos/login/screens/hid_detection_view.h b/chrome/browser/chromeos/login/screens/hid_detection_view.h
index 34a19c8..03fa090 100644
--- a/chrome/browser/chromeos/login/screens/hid_detection_view.h
+++ b/chrome/browser/chromeos/login/screens/hid_detection_view.h
@@ -8,6 +8,7 @@
 #include <string>
 
 #include "base/callback.h"
+#include "chrome/browser/chromeos/login/oobe_screen.h"
 
 namespace chromeos {
 
@@ -18,6 +19,8 @@
 // dtor.
 class HIDDetectionView {
  public:
+  constexpr static OobeScreen kScreenId = OobeScreen::SCREEN_OOBE_HID_DETECTION;
+
   virtual ~HIDDetectionView() {}
 
   virtual void Show() = 0;
diff --git a/chrome/browser/chromeos/login/screens/host_pairing_screen_view.h b/chrome/browser/chromeos/login/screens/host_pairing_screen_view.h
index 64ded65..2958bba 100644
--- a/chrome/browser/chromeos/login/screens/host_pairing_screen_view.h
+++ b/chrome/browser/chromeos/login/screens/host_pairing_screen_view.h
@@ -6,6 +6,7 @@
 #define CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_HOST_PAIRING_SCREEN_VIEW_H_
 
 #include "base/macros.h"
+#include "chrome/browser/chromeos/login/oobe_screen.h"
 
 namespace base {
 class DictionaryValue;
@@ -47,6 +48,8 @@
     virtual void OnViewDestroyed(HostPairingScreenView* view) = 0;
   };
 
+  constexpr static OobeScreen kScreenId = OobeScreen::SCREEN_OOBE_HOST_PAIRING;
+
   HostPairingScreenView();
   virtual ~HostPairingScreenView();
 
diff --git a/chrome/browser/chromeos/login/screens/kiosk_autolaunch_screen_view.h b/chrome/browser/chromeos/login/screens/kiosk_autolaunch_screen_view.h
index c45487d..58a07b2 100644
--- a/chrome/browser/chromeos/login/screens/kiosk_autolaunch_screen_view.h
+++ b/chrome/browser/chromeos/login/screens/kiosk_autolaunch_screen_view.h
@@ -6,6 +6,7 @@
 #define CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_KIOSK_AUTOLAUNCH_SCREEN_VIEW_H_
 
 #include <string>
+#include "chrome/browser/chromeos/login/oobe_screen.h"
 
 namespace chromeos {
 
@@ -26,6 +27,8 @@
     virtual void OnViewDestroyed(KioskAutolaunchScreenView* view) = 0;
   };
 
+  constexpr static OobeScreen kScreenId = OobeScreen::SCREEN_KIOSK_AUTOLAUNCH;
+
   virtual ~KioskAutolaunchScreenView() {}
 
   virtual void Show() = 0;
diff --git a/chrome/browser/chromeos/login/screens/kiosk_enable_screen_view.h b/chrome/browser/chromeos/login/screens/kiosk_enable_screen_view.h
index f4304dd..2dbaad3 100644
--- a/chrome/browser/chromeos/login/screens/kiosk_enable_screen_view.h
+++ b/chrome/browser/chromeos/login/screens/kiosk_enable_screen_view.h
@@ -6,6 +6,7 @@
 #define CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_KIOSK_ENABLE_SCREEN_VIEW_H_
 
 #include <string>
+#include "chrome/browser/chromeos/login/oobe_screen.h"
 
 namespace chromeos {
 
@@ -26,6 +27,8 @@
     virtual void OnViewDestroyed(KioskEnableScreenView* view) = 0;
   };
 
+  constexpr static OobeScreen kScreenId = OobeScreen::SCREEN_KIOSK_ENABLE;
+
   virtual ~KioskEnableScreenView() {}
 
   virtual void Show() = 0;
diff --git a/chrome/browser/chromeos/login/screens/network_error_view.h b/chrome/browser/chromeos/login/screens/network_error_view.h
index b58e3e3..d81175b 100644
--- a/chrome/browser/chromeos/login/screens/network_error_view.h
+++ b/chrome/browser/chromeos/login/screens/network_error_view.h
@@ -16,6 +16,8 @@
 // representation. Owned by ErrorScreen.
 class NetworkErrorView {
  public:
+  constexpr static OobeScreen kScreenId = OobeScreen::SCREEN_ERROR_MESSAGE;
+
   virtual ~NetworkErrorView() {}
 
   // Shows the contents of the screen.
diff --git a/chrome/browser/chromeos/login/screens/network_view.h b/chrome/browser/chromeos/login/screens/network_view.h
index a27c969b5..6742989 100644
--- a/chrome/browser/chromeos/login/screens/network_view.h
+++ b/chrome/browser/chromeos/login/screens/network_view.h
@@ -6,6 +6,7 @@
 #define CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_NETWORK_VIEW_H_
 
 #include "base/strings/string16.h"
+#include "chrome/browser/chromeos/login/oobe_screen.h"
 
 namespace chromeos {
 
@@ -15,6 +16,8 @@
 // representation, either views based or WebUI. Owned by NetworkScreen.
 class NetworkView {
  public:
+  constexpr static OobeScreen kScreenId = OobeScreen::SCREEN_OOBE_NETWORK;
+
   virtual ~NetworkView() {}
 
   // Shows the contents of the screen.
diff --git a/chrome/browser/chromeos/login/screens/reset_view.h b/chrome/browser/chromeos/login/screens/reset_view.h
index 7570c04..22c3dcc 100644
--- a/chrome/browser/chromeos/login/screens/reset_view.h
+++ b/chrome/browser/chromeos/login/screens/reset_view.h
@@ -5,6 +5,8 @@
 #ifndef CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_RESET_VIEW_H_
 #define CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_RESET_VIEW_H_
 
+#include "chrome/browser/chromeos/login/oobe_screen.h"
+
 namespace chromeos {
 
 class ResetScreen;
@@ -13,6 +15,8 @@
 // representation, either views based or WebUI.
 class ResetView {
  public:
+  constexpr static OobeScreen kScreenId = OobeScreen::SCREEN_OOBE_RESET;
+
   virtual ~ResetView() {}
 
   virtual void Bind(ResetScreen* screen) = 0;
diff --git a/chrome/browser/chromeos/login/screens/terms_of_service_screen_view.h b/chrome/browser/chromeos/login/screens/terms_of_service_screen_view.h
index dcd3ee4..fce5dc97 100644
--- a/chrome/browser/chromeos/login/screens/terms_of_service_screen_view.h
+++ b/chrome/browser/chromeos/login/screens/terms_of_service_screen_view.h
@@ -6,6 +6,7 @@
 #define CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_TERMS_OF_SERVICE_SCREEN_VIEW_H_
 
 #include <string>
+#include "chrome/browser/chromeos/login/oobe_screen.h"
 
 namespace chromeos {
 
@@ -27,6 +28,8 @@
     virtual void OnViewDestroyed(TermsOfServiceScreenView* view) = 0;
   };
 
+  constexpr static OobeScreen kScreenId = OobeScreen::SCREEN_TERMS_OF_SERVICE;
+
   virtual ~TermsOfServiceScreenView() {}
 
   // Sets screen this view belongs to.
diff --git a/chrome/browser/chromeos/login/screens/update_view.h b/chrome/browser/chromeos/login/screens/update_view.h
index 17de164..3d273f6 100644
--- a/chrome/browser/chromeos/login/screens/update_view.h
+++ b/chrome/browser/chromeos/login/screens/update_view.h
@@ -6,6 +6,7 @@
 #define CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_UPDATE_VIEW_H_
 
 #include "base/strings/string16.h"
+#include "chrome/browser/chromeos/login/oobe_screen.h"
 
 namespace chromeos {
 
@@ -15,6 +16,8 @@
 // representation. Owned by UpdateScreen.
 class UpdateView {
  public:
+  constexpr static OobeScreen kScreenId = OobeScreen::SCREEN_OOBE_UPDATE;
+
   virtual ~UpdateView() {}
 
   // Shows the contents of the screen.
diff --git a/chrome/browser/chromeos/login/screens/user_image_view.h b/chrome/browser/chromeos/login/screens/user_image_view.h
index d14ce6b..3464a10 100644
--- a/chrome/browser/chromeos/login/screens/user_image_view.h
+++ b/chrome/browser/chromeos/login/screens/user_image_view.h
@@ -5,6 +5,8 @@
 #ifndef CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_USER_IMAGE_VIEW_H_
 #define CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_USER_IMAGE_VIEW_H_
 
+#include "chrome/browser/chromeos/login/oobe_screen.h"
+
 namespace chromeos {
 
 class UserImageScreen;
@@ -13,6 +15,8 @@
 // representation, either views based or WebUI.
 class UserImageView {
  public:
+  constexpr static OobeScreen kScreenId = OobeScreen::SCREEN_USER_IMAGE_PICKER;
+
   virtual ~UserImageView() {}
 
   virtual void Bind(UserImageScreen* screen) = 0;
diff --git a/chrome/browser/chromeos/login/screens/wrong_hwid_screen_view.h b/chrome/browser/chromeos/login/screens/wrong_hwid_screen_view.h
index 9576e66c..38c8881 100644
--- a/chrome/browser/chromeos/login/screens/wrong_hwid_screen_view.h
+++ b/chrome/browser/chromeos/login/screens/wrong_hwid_screen_view.h
@@ -6,6 +6,7 @@
 #define CHROME_BROWSER_CHROMEOS_LOGIN_SCREENS_WRONG_HWID_SCREEN_VIEW_H_
 
 #include <string>
+#include "chrome/browser/chromeos/login/oobe_screen.h"
 
 namespace chromeos {
 
@@ -26,6 +27,8 @@
     virtual void OnViewDestroyed(WrongHWIDScreenView* view) = 0;
   };
 
+  constexpr static OobeScreen kScreenId = OobeScreen::SCREEN_WRONG_HWID;
+
   virtual ~WrongHWIDScreenView() {}
 
   virtual void Show() = 0;
diff --git a/chrome/browser/chromeos/login/supervised/supervised_user_creation_browsertest.cc b/chrome/browser/chromeos/login/supervised/supervised_user_creation_browsertest.cc
index 6fa45d35..8a5827d 100644
--- a/chrome/browser/chromeos/login/supervised/supervised_user_creation_browsertest.cc
+++ b/chrome/browser/chromeos/login/supervised/supervised_user_creation_browsertest.cc
@@ -77,7 +77,7 @@
   void SetUpInProcessBrowserTestFixture() override {
     SupervisedUserTestBase::SetUpInProcessBrowserTestFixture();
     cros_settings_provider_.reset(new StubCrosSettingsProvider());
-    cros_settings_provider_->Set(kDeviceOwner, base::StringValue(kTestManager));
+    cros_settings_provider_->Set(kDeviceOwner, base::Value(kTestManager));
   }
 
  private:
diff --git a/chrome/browser/chromeos/login/test/https_forwarder.py b/chrome/browser/chromeos/login/test/https_forwarder.py
index e68bcca..6578871 100644
--- a/chrome/browser/chromeos/login/test/https_forwarder.py
+++ b/chrome/browser/chromeos/login/test/https_forwarder.py
@@ -9,6 +9,7 @@
 import BaseHTTPServer
 import minica
 import re
+import socket
 import SocketServer
 import sys
 import urllib2
@@ -161,9 +162,32 @@
     host = self.options.host
     ssl_host = self.options.ssl_host
 
+    # Allow |ssl_host| to be an IP address or a domain name, and ensure
+    # it gets added as the appropriate subjectAltName of the generated
+    # certificate.
+    dns_sans = None
+    ip_sans = None
+    ip = None
+    if ip is None:
+      try:
+        ip = socket.inet_pton(socket.AF_INET, ssl_host)
+        ip_sans = [ip]
+      except socket.error:
+        pass
+    if ip is None:
+      try:
+        ip = socket.inet_pton(socket.AF_INET6, ssl_host)
+        ip_sans = [ip]
+      except socket.error:
+        pass
+    if ip is None:
+      dns_sans = [ssl_host]
+
     (pem_cert_and_key, ocsp_der) = minica.GenerateCertKeyAndOCSP(
         subject = self.options.ssl_host,
-        ocsp_url = None)
+        ocsp_url = None,
+        ip_sans = ip_sans,
+        dns_sans = dns_sans)
 
     server = MultiThreadedHTTPSServer((host, port),
                                       RequestForwarder,
diff --git a/chrome/browser/chromeos/login/ui/views/user_board_view.h b/chrome/browser/chromeos/login/ui/views/user_board_view.h
index 5577da9..cdf5054e 100644
--- a/chrome/browser/chromeos/login/ui/views/user_board_view.h
+++ b/chrome/browser/chromeos/login/ui/views/user_board_view.h
@@ -11,6 +11,7 @@
 #include "base/memory/weak_ptr.h"
 #include "base/strings/string16.h"
 #include "base/values.h"
+#include "chrome/browser/chromeos/login/oobe_screen.h"
 #include "components/proximity_auth/screenlock_bridge.h"
 
 class AccountId;
@@ -26,6 +27,8 @@
 // or Views one.
 class UserBoardView {
  public:
+  constexpr static OobeScreen kScreenId = OobeScreen::SCREEN_USER_SELECTION;
+
   virtual ~UserBoardView() {}
 
   virtual void Bind(UserSelectionScreen* screen) = 0;
diff --git a/chrome/browser/chromeos/login/ui/webui_login_view.cc b/chrome/browser/chromeos/login/ui/webui_login_view.cc
index 1c69151..b350699 100644
--- a/chrome/browser/chromeos/login/ui/webui_login_view.cc
+++ b/chrome/browser/chromeos/login/ui/webui_login_view.cc
@@ -305,7 +305,7 @@
 
   content::WebUI* web_ui = GetWebUI();
   if (web_ui) {
-    base::StringValue accel_name(entry->second);
+    base::Value accel_name(entry->second);
     web_ui->CallJavascriptFunctionUnsafe("cr.ui.Oobe.handleAccelerator",
                                          accel_name);
   }
diff --git a/chrome/browser/chromeos/login/users/avatar/user_image_manager_impl.cc b/chrome/browser/chromeos/login/users/avatar/user_image_manager_impl.cc
index d3bd921..e5e4cd2 100644
--- a/chrome/browser/chromeos/login/users/avatar/user_image_manager_impl.cc
+++ b/chrome/browser/chromeos/login/users/avatar/user_image_manager_impl.cc
@@ -544,10 +544,10 @@
     return;
 
   std::unique_ptr<base::DictionaryValue> entry(new base::DictionaryValue);
-  entry->Set(kImagePathNodeName, new base::StringValue(image_path_.value()));
+  entry->Set(kImagePathNodeName, new base::Value(image_path_.value()));
   entry->Set(kImageIndexNodeName, new base::Value(image_index_));
   if (!image_url_.is_empty())
-    entry->Set(kImageURLNodeName, new base::StringValue(image_url_.spec()));
+    entry->Set(kImageURLNodeName, new base::Value(image_url_.spec()));
   DictionaryPrefUpdate update(g_browser_process->local_state(),
                               kUserImageProperties);
   update->SetWithoutPathExpansion(user_id(), entry.release());
diff --git a/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc b/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc
index 1811306..6216650 100644
--- a/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc
+++ b/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc
@@ -802,7 +802,7 @@
   // Add the user to the front of the user list.
   ListPrefUpdate prefs_users_update(GetLocalState(), kRegularUsers);
   prefs_users_update->Insert(
-      0, base::MakeUnique<base::StringValue>(account_id.GetUserEmail()));
+      0, base::MakeUnique<base::Value>(account_id.GetUserEmail()));
   users_.insert(users_.begin(), active_user_);
 
   // Now that user is in the list, save display name.
@@ -1260,20 +1260,20 @@
 bool ChromeUserManagerImpl::ShouldReportUser(const std::string& user_id) const {
   const base::ListValue& reporting_users =
       *(GetLocalState()->GetList(kReportingUsers));
-  base::StringValue user_id_value(FullyCanonicalize(user_id));
+  base::Value user_id_value(FullyCanonicalize(user_id));
   return !(reporting_users.Find(user_id_value) == reporting_users.end());
 }
 
 void ChromeUserManagerImpl::AddReportingUser(const AccountId& account_id) {
   ListPrefUpdate users_update(GetLocalState(), kReportingUsers);
   users_update->AppendIfNotPresent(
-      base::MakeUnique<base::StringValue>(account_id.GetUserEmail()));
+      base::MakeUnique<base::Value>(account_id.GetUserEmail()));
 }
 
 void ChromeUserManagerImpl::RemoveReportingUser(const AccountId& account_id) {
   ListPrefUpdate users_update(GetLocalState(), kReportingUsers);
   users_update->Remove(
-      base::StringValue(FullyCanonicalize(account_id.GetUserEmail())), NULL);
+      base::Value(FullyCanonicalize(account_id.GetUserEmail())), NULL);
 }
 
 void ChromeUserManagerImpl::UpdateLoginState(
diff --git a/chrome/browser/chromeos/login/users/supervised_user_manager_impl.cc b/chrome/browser/chromeos/login/users/supervised_user_manager_impl.cc
index c8419153..90ef449 100644
--- a/chrome/browser/chromeos/login/users/supervised_user_manager_impl.cc
+++ b/chrome/browser/chromeos/login/users/supervised_user_manager_impl.cc
@@ -208,18 +208,17 @@
       local_state,
       kSupervisedUserManagerDisplayEmails);
 
-  prefs_new_users_update->Insert(
-      0, base::MakeUnique<base::StringValue>(local_user_id));
+  prefs_new_users_update->Insert(0,
+                                 base::MakeUnique<base::Value>(local_user_id));
 
   sync_id_update->SetWithoutPathExpansion(local_user_id,
-      new base::StringValue(sync_user_id));
+                                          new base::Value(sync_user_id));
   manager_update->SetWithoutPathExpansion(
-      local_user_id,
-      new base::StringValue(manager->GetAccountId().GetUserEmail()));
-  manager_name_update->SetWithoutPathExpansion(local_user_id,
-      new base::StringValue(manager->GetDisplayName()));
-  manager_email_update->SetWithoutPathExpansion(local_user_id,
-      new base::StringValue(manager->display_email()));
+      local_user_id, new base::Value(manager->GetAccountId().GetUserEmail()));
+  manager_name_update->SetWithoutPathExpansion(
+      local_user_id, new base::Value(manager->GetDisplayName()));
+  manager_email_update->SetWithoutPathExpansion(
+      local_user_id, new base::Value(manager->display_email()));
 
   owner_->SaveUserDisplayName(AccountId::FromUserEmail(local_user_id),
                               display_name);
@@ -458,7 +457,7 @@
     const std::string& user_id) {
   PrefService* prefs = g_browser_process->local_state();
   ListPrefUpdate prefs_new_users_update(prefs, kSupervisedUsersFirstRun);
-  prefs_new_users_update->Remove(base::StringValue(user_id), NULL);
+  prefs_new_users_update->Remove(base::Value(user_id), NULL);
 
   CleanPref(user_id, kSupervisedUserSyncId);
   CleanPref(user_id, kSupervisedUserManagers);
@@ -481,7 +480,7 @@
 bool SupervisedUserManagerImpl::CheckForFirstRun(const std::string& user_id) {
   ListPrefUpdate prefs_new_users_update(g_browser_process->local_state(),
                                         kSupervisedUsersFirstRun);
-  return prefs_new_users_update->Remove(base::StringValue(user_id), NULL);
+  return prefs_new_users_update->Remove(base::Value(user_id), NULL);
 }
 
 void SupervisedUserManagerImpl::UpdateManagerName(const std::string& manager_id,
@@ -500,8 +499,7 @@
     DCHECK(has_manager_id);
     if (user_id == manager_id) {
       manager_name_update->SetWithoutPathExpansion(
-          it.key(),
-          new base::StringValue(new_display_name));
+          it.key(), new base::Value(new_display_name));
     }
   }
 }
diff --git a/chrome/browser/chromeos/mobile/mobile_activator_unittest.cc b/chrome/browser/chromeos/mobile/mobile_activator_unittest.cc
index 2fda6d3..d13941f 100644
--- a/chrome/browser/chromeos/mobile/mobile_activator_unittest.cc
+++ b/chrome/browser/chromeos/mobile/mobile_activator_unittest.cc
@@ -112,7 +112,7 @@
       : cellular_network_(string(kTestServicePath)),
         mobile_activator_(&cellular_network_) {
     cellular_network_.PropertyChanged(shill::kTypeProperty,
-                                      base::StringValue(shill::kTypeCellular));
+                                      base::Value(shill::kTypeCellular));
   }
   ~MobileActivatorTest() override {}
 
diff --git a/chrome/browser/chromeos/net/network_portal_detector_impl_browsertest.cc b/chrome/browser/chromeos/net/network_portal_detector_impl_browsertest.cc
index 04085d5..f9948acc 100644
--- a/chrome/browser/chromeos/net/network_portal_detector_impl_browsertest.cc
+++ b/chrome/browser/chromeos/net/network_portal_detector_impl_browsertest.cc
@@ -126,10 +126,8 @@
                              shill::kStateIdle,
                              true /* add_to_visible */);
     DBusThreadManager::Get()->GetShillServiceClient()->SetProperty(
-        dbus::ObjectPath(kWifiServicePath),
-        shill::kStateProperty,
-        base::StringValue(shill::kStatePortal),
-        base::Bind(&base::DoNothing),
+        dbus::ObjectPath(kWifiServicePath), shill::kStateProperty,
+        base::Value(shill::kStatePortal), base::Bind(&base::DoNothing),
         base::Bind(&ErrorCallbackFunction));
 
     network_portal_detector_ = new NetworkPortalDetectorImpl(
diff --git a/chrome/browser/chromeos/net/network_portal_detector_impl_unittest.cc b/chrome/browser/chromeos/net/network_portal_detector_impl_unittest.cc
index 9cc0a242..daba966 100644
--- a/chrome/browser/chromeos/net/network_portal_detector_impl_unittest.cc
+++ b/chrome/browser/chromeos/net/network_portal_detector_impl_unittest.cc
@@ -233,10 +233,8 @@
 
   void SetBehindPortal(const std::string& service_path) {
     DBusThreadManager::Get()->GetShillServiceClient()->SetProperty(
-        dbus::ObjectPath(service_path),
-        shill::kStateProperty,
-        base::StringValue(shill::kStatePortal),
-        base::Bind(&base::DoNothing),
+        dbus::ObjectPath(service_path), shill::kStateProperty,
+        base::Value(shill::kStatePortal), base::Bind(&base::DoNothing),
         base::Bind(&ErrorCallbackFunction));
     base::RunLoop().RunUntilIdle();
   }
diff --git a/chrome/browser/chromeos/net/network_state_notifier_unittest.cc b/chrome/browser/chromeos/net/network_state_notifier_unittest.cc
index e2950ced..3b9bfb38 100644
--- a/chrome/browser/chromeos/net/network_state_notifier_unittest.cc
+++ b/chrome/browser/chromeos/net/network_state_notifier_unittest.cc
@@ -103,12 +103,11 @@
                              add_to_visible);
     service_test->SetServiceProperty(kWiFi1ServicePath,
                                      shill::kSecurityClassProperty,
-                                     base::StringValue(shill::kSecurityWep));
+                                     base::Value(shill::kSecurityWep));
     service_test->SetServiceProperty(
         kWiFi1ServicePath, shill::kConnectableProperty, base::Value(true));
-    service_test->SetServiceProperty(kWiFi1ServicePath,
-                                     shill::kPassphraseProperty,
-                                     base::StringValue("failure"));
+    service_test->SetServiceProperty(
+        kWiFi1ServicePath, shill::kPassphraseProperty, base::Value("failure"));
     base::RunLoop().RunUntilIdle();
   }
 
diff --git a/chrome/browser/chromeos/net/wake_on_wifi_manager.cc b/chrome/browser/chromeos/net/wake_on_wifi_manager.cc
index b982663..f5f2945 100644
--- a/chrome/browser/chromeos/net/wake_on_wifi_manager.cc
+++ b/chrome/browser/chromeos/net/wake_on_wifi_manager.cc
@@ -180,10 +180,8 @@
   DCHECK(!feature_string.empty());
 
   NetworkHandler::Get()->network_device_handler()->SetDeviceProperty(
-      device->path(),
-      shill::kWakeOnWiFiFeaturesEnabledProperty,
-      base::StringValue(feature_string),
-      base::Bind(&base::DoNothing),
+      device->path(), shill::kWakeOnWiFiFeaturesEnabledProperty,
+      base::Value(feature_string), base::Bind(&base::DoNothing),
       network_handler::ErrorCallback());
 
   bool wake_on_packet_enabled = IsWakeOnPacketEnabled(current_feature_);
diff --git a/chrome/browser/chromeos/options/network_property_ui_data_unittest.cc b/chrome/browser/chromeos/options/network_property_ui_data_unittest.cc
index 5c6f6e56..adb18852 100644
--- a/chrome/browser/chromeos/options/network_property_ui_data_unittest.cc
+++ b/chrome/browser/chromeos/options/network_property_ui_data_unittest.cc
@@ -41,10 +41,10 @@
 TEST_F(NetworkPropertyUIDataTest, ParseOncProperty) {
   base::DictionaryValue onc;
 
-  base::StringValue val_a("a");
-  base::StringValue val_b("b");
-  base::StringValue val_a_a("a_a");
-  base::StringValue val_a_b("a_b");
+  base::Value val_a("a");
+  base::Value val_b("b");
+  base::Value val_a_a("a_a");
+  base::Value val_a_b("a_b");
 
   onc.Set("a", val_a.DeepCopy());
   onc.Set("b", val_b.DeepCopy());
diff --git a/chrome/browser/chromeos/ownership/owner_settings_service_chromeos.cc b/chrome/browser/chromeos/ownership/owner_settings_service_chromeos.cc
index 3d9977d..29b91ff 100644
--- a/chrome/browser/chromeos/ownership/owner_settings_service_chromeos.cc
+++ b/chrome/browser/chromeos/ownership/owner_settings_service_chromeos.cc
@@ -62,7 +62,7 @@
   const base::Value* value = CrosSettings::Get()->GetPref(kDeviceOwner);
   if (!value || value->GetType() != base::Value::Type::STRING)
     return false;
-  return static_cast<const base::StringValue*>(value)->GetString() == user_id;
+  return static_cast<const base::Value*>(value)->GetString() == user_id;
 }
 
 void LoadPrivateKeyByPublicKey(
diff --git a/chrome/browser/chromeos/ownership/owner_settings_service_chromeos_unittest.cc b/chrome/browser/chromeos/ownership/owner_settings_service_chromeos_unittest.cc
index f26bf46d..dbb622c 100644
--- a/chrome/browser/chromeos/ownership/owner_settings_service_chromeos_unittest.cc
+++ b/chrome/browser/chromeos/ownership/owner_settings_service_chromeos_unittest.cc
@@ -83,7 +83,7 @@
   const base::ListValue* list;
   if (!haystack->GetAsList(&list))
     return false;
-  return list->end() != list->Find(base::StringValue(needle));
+  return list->end() != list->Find(base::Value(needle));
 }
 
 }  // namespace
@@ -144,14 +144,14 @@
 };
 
 TEST_F(OwnerSettingsServiceChromeOSTest, SingleSetTest) {
-  TestSingleSet(service_, kReleaseChannel, base::StringValue("dev-channel"));
-  TestSingleSet(service_, kReleaseChannel, base::StringValue("beta-channel"));
-  TestSingleSet(service_, kReleaseChannel, base::StringValue("stable-channel"));
+  TestSingleSet(service_, kReleaseChannel, base::Value("dev-channel"));
+  TestSingleSet(service_, kReleaseChannel, base::Value("beta-channel"));
+  TestSingleSet(service_, kReleaseChannel, base::Value("stable-channel"));
 }
 
 TEST_F(OwnerSettingsServiceChromeOSTest, MultipleSetTest) {
   base::Value allow_guest(false);
-  base::StringValue release_channel("stable-channel");
+  base::Value release_channel("stable-channel");
   base::Value show_user_names(true);
 
   PrefsChecker checker(service_, provider_.get());
@@ -172,7 +172,7 @@
 
   // Check that DeviceSettingsProvider's cache is updated.
   PrefsChecker checker(service_, provider_.get());
-  checker.Set(kReleaseChannel, base::StringValue("stable-channel"));
+  checker.Set(kReleaseChannel, base::Value("stable-channel"));
   FlushDeviceSettings();
   checker.Wait();
 
@@ -186,7 +186,7 @@
   EXPECT_FALSE(FindInListValue(device_policy_.policy_data().username(),
                                provider_->Get(kAccountsPrefUsers)));
   // Force a settings write.
-  TestSingleSet(service_, kReleaseChannel, base::StringValue("dev-channel"));
+  TestSingleSet(service_, kReleaseChannel, base::Value("dev-channel"));
   EXPECT_TRUE(FindInListValue(device_policy_.policy_data().username(),
                               provider_->Get(kAccountsPrefUsers)));
 }
diff --git a/chrome/browser/chromeos/policy/affiliation_test_helper.cc b/chrome/browser/chromeos/policy/affiliation_test_helper.cc
index 13310b5..27b051a 100644
--- a/chrome/browser/chromeos/policy/affiliation_test_helper.cc
+++ b/chrome/browser/chromeos/policy/affiliation_test_helper.cc
@@ -99,7 +99,7 @@
 
 void PreLoginUser(const std::string& user_id) {
   ListPrefUpdate users_pref(g_browser_process->local_state(), "LoggedInUsers");
-  users_pref->AppendIfNotPresent(base::MakeUnique<base::StringValue>(user_id));
+  users_pref->AppendIfNotPresent(base::MakeUnique<base::Value>(user_id));
   chromeos::StartupUtils::MarkOobeCompleted();
 }
 
diff --git a/chrome/browser/chromeos/policy/auto_enrollment_client.cc b/chrome/browser/chromeos/policy/auto_enrollment_client.cc
index 974922ae..2a54a10f 100644
--- a/chrome/browser/chromeos/policy/auto_enrollment_client.cc
+++ b/chrome/browser/chromeos/policy/auto_enrollment_client.cc
@@ -376,23 +376,18 @@
         response.device_state_retrieval_response();
     {
       DictionaryPrefUpdate dict(local_state_, prefs::kServerBackedDeviceState);
-      UpdateDict(dict.Get(),
-                 kDeviceStateManagementDomain,
+      UpdateDict(dict.Get(), kDeviceStateManagementDomain,
                  state_response.has_management_domain(),
-                 new base::StringValue(state_response.management_domain()));
+                 new base::Value(state_response.management_domain()));
 
       std::string restore_mode =
           ConvertRestoreMode(state_response.restore_mode());
-      UpdateDict(dict.Get(),
-                 kDeviceStateRestoreMode,
-                 !restore_mode.empty(),
-                 new base::StringValue(restore_mode));
+      UpdateDict(dict.Get(), kDeviceStateRestoreMode, !restore_mode.empty(),
+                 new base::Value(restore_mode));
 
-      UpdateDict(dict.Get(),
-                 kDeviceStateDisabledMessage,
+      UpdateDict(dict.Get(), kDeviceStateDisabledMessage,
                  state_response.has_disabled_state(),
-                 new base::StringValue(
-                     state_response.disabled_state().message()));
+                 new base::Value(state_response.disabled_state().message()));
 
       // Logging as "WARNING" to make sure it's preserved in the logs.
       LOG(WARNING) << "Restore mode: " << restore_mode;
diff --git a/chrome/browser/chromeos/policy/cloud_external_data_manager_base_unittest.cc b/chrome/browser/chromeos/policy/cloud_external_data_manager_base_unittest.cc
index 725ffc9..6478a21 100644
--- a/chrome/browser/chromeos/policy/cloud_external_data_manager_base_unittest.cc
+++ b/chrome/browser/chromeos/policy/cloud_external_data_manager_base_unittest.cc
@@ -158,7 +158,7 @@
   // Set |kStringPolicy| to a string value.
   cloud_policy_store_.policy_map_.Set(
       kStringPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-      POLICY_SOURCE_CLOUD, base::MakeUnique<base::StringValue>(std::string()),
+      POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>(std::string()),
       nullptr);
   // Make |k10BytePolicy| reference 10 bytes of external data.
   SetExternalDataReference(
diff --git a/chrome/browser/chromeos/policy/cloud_external_data_policy_observer_unittest.cc b/chrome/browser/chromeos/policy/cloud_external_data_policy_observer_unittest.cc
index c53a170..de3f990 100644
--- a/chrome/browser/chromeos/policy/cloud_external_data_policy_observer_unittest.cc
+++ b/chrome/browser/chromeos/policy/cloud_external_data_policy_observer_unittest.cc
@@ -354,7 +354,7 @@
   if (!value.empty()) {
     policy_map.Set(key::kUserAvatarImage, POLICY_LEVEL_MANDATORY,
                    POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-                   base::MakeUnique<base::StringValue>(value),
+                   base::MakeUnique<base::Value>(value),
                    external_data_manager_.CreateExternalDataFetcher(
                        key::kUserAvatarImage));
   }
diff --git a/chrome/browser/chromeos/policy/configuration_policy_handler_chromeos.cc b/chrome/browser/chromeos/policy/configuration_policy_handler_chromeos.cc
index 6970f55a..ded0f9f 100644
--- a/chrome/browser/chromeos/policy/configuration_policy_handler_chromeos.cc
+++ b/chrome/browser/chromeos/policy/configuration_policy_handler_chromeos.cc
@@ -303,7 +303,7 @@
 
   base::JSONWriter::WriteWithOptions(
       *toplevel_dict, base::JSONWriter::OPTIONS_PRETTY_PRINT, &json_string);
-  return base::MakeUnique<base::StringValue>(json_string);
+  return base::MakeUnique<base::Value>(json_string);
 }
 
 PinnedLauncherAppsPolicyHandler::PinnedLauncherAppsPolicyHandler()
diff --git a/chrome/browser/chromeos/policy/configuration_policy_handler_chromeos_unittest.cc b/chrome/browser/chromeos/policy/configuration_policy_handler_chromeos_unittest.cc
index 7cdf667..3639151 100644
--- a/chrome/browser/chromeos/policy/configuration_policy_handler_chromeos_unittest.cc
+++ b/chrome/browser/chromeos/policy/configuration_policy_handler_chromeos_unittest.cc
@@ -237,7 +237,7 @@
   PolicyMap policy_map;
   policy_map.Set(key::kOpenNetworkConfiguration, POLICY_LEVEL_MANDATORY,
                  POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-                 base::MakeUnique<base::StringValue>(kTestONC), nullptr);
+                 base::MakeUnique<base::Value>(kTestONC), nullptr);
   std::unique_ptr<NetworkConfigurationPolicyHandler> handler(
       NetworkConfigurationPolicyHandler::CreateForUserPolicy());
   PolicyErrorMap errors;
@@ -262,7 +262,7 @@
   PolicyMap policy_map;
   policy_map.Set(key::kOpenNetworkConfiguration, POLICY_LEVEL_MANDATORY,
                  POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-                 base::MakeUnique<base::StringValue>(kTestONC), nullptr);
+                 base::MakeUnique<base::Value>(kTestONC), nullptr);
   std::unique_ptr<NetworkConfigurationPolicyHandler> handler(
       NetworkConfigurationPolicyHandler::CreateForUserPolicy());
   PolicyErrorMap errors;
@@ -288,7 +288,7 @@
   PolicyMap policy_map;
   policy_map.Set(key::kOpenNetworkConfiguration, POLICY_LEVEL_MANDATORY,
                  POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-                 base::MakeUnique<base::StringValue>(kTestONC), nullptr);
+                 base::MakeUnique<base::Value>(kTestONC), nullptr);
   std::unique_ptr<NetworkConfigurationPolicyHandler> handler(
       NetworkConfigurationPolicyHandler::CreateForUserPolicy());
   PolicyErrorMap errors;
@@ -317,7 +317,7 @@
   EXPECT_TRUE(prefs.GetValue(prefs::kPolicyPinnedLauncherApps, &value));
   EXPECT_TRUE(base::Value::Equals(&expected_pinned_apps, value));
 
-  base::StringValue entry1("abcdefghijklmnopabcdefghijklmnop");
+  base::Value entry1("abcdefghijklmnopabcdefghijklmnop");
   auto entry1_dict = base::MakeUnique<base::DictionaryValue>();
   entry1_dict->Set(ash::launcher::kPinnedAppsPrefAppIDPath, entry1.DeepCopy());
   expected_pinned_apps.Append(std::move(entry1_dict));
diff --git a/chrome/browser/chromeos/policy/device_local_account_browsertest.cc b/chrome/browser/chromeos/policy/device_local_account_browsertest.cc
index 1d48467f..064ac83 100644
--- a/chrome/browser/chromeos/policy/device_local_account_browsertest.cc
+++ b/chrome/browser/chromeos/policy/device_local_account_browsertest.cc
@@ -2292,7 +2292,7 @@
   }
 
   // Verify that the app policy was set.
-  base::StringValue expected_value("policy test value one");
+  base::Value expected_value("policy test value one");
   EXPECT_TRUE(base::Value::Equals(
       &expected_value,
       policy_service->GetPolicies(ns).GetValue("string")));
@@ -2317,7 +2317,7 @@
   }
 
   // Verify that the app policy was updated.
-  base::StringValue expected_new_value("policy test value two");
+  base::Value expected_new_value("policy test value two");
   EXPECT_TRUE(base::Value::Equals(
       &expected_new_value,
       policy_service->GetPolicies(ns).GetValue("string")));
diff --git a/chrome/browser/chromeos/policy/device_local_account_policy_provider.cc b/chrome/browser/chromeos/policy/device_local_account_policy_provider.cc
index 692b1f9b..3e24c53 100644
--- a/chrome/browser/chromeos/policy/device_local_account_policy_provider.cc
+++ b/chrome/browser/chromeos/policy/device_local_account_policy_provider.cc
@@ -71,7 +71,7 @@
     chrome_policy_overrides->Set(
         key::kShelfAutoHideBehavior, POLICY_LEVEL_MANDATORY,
         POLICY_SCOPE_MACHINE, POLICY_SOURCE_PUBLIC_SESSION_OVERRIDE,
-        base::MakeUnique<base::StringValue>("Never"), nullptr);
+        base::MakeUnique<base::Value>("Never"), nullptr);
     // Force the |ShowLogoutButtonInTray| policy to |true|, ensuring that a big,
     // red logout button is shown in the ash system tray.
     chrome_policy_overrides->Set(key::kShowLogoutButtonInTray,
diff --git a/chrome/browser/chromeos/policy/device_local_account_policy_service_unittest.cc b/chrome/browser/chromeos/policy/device_local_account_policy_service_unittest.cc
index 17687133..7caf7618 100644
--- a/chrome/browser/chromeos/policy/device_local_account_policy_service_unittest.cc
+++ b/chrome/browser/chromeos/policy/device_local_account_policy_service_unittest.cc
@@ -811,10 +811,10 @@
       base::MakeUnique<base::Value>(
           chromeos::PowerPolicyController::ACTION_STOP_SESSION),
       nullptr);
-  expected_policy_map_.Set(
-      key::kShelfAutoHideBehavior, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
-      POLICY_SOURCE_PUBLIC_SESSION_OVERRIDE,
-      base::MakeUnique<base::StringValue>("Never"), nullptr);
+  expected_policy_map_.Set(key::kShelfAutoHideBehavior, POLICY_LEVEL_MANDATORY,
+                           POLICY_SCOPE_MACHINE,
+                           POLICY_SOURCE_PUBLIC_SESSION_OVERRIDE,
+                           base::MakeUnique<base::Value>("Never"), nullptr);
   expected_policy_map_.Set(key::kShowLogoutButtonInTray, POLICY_LEVEL_MANDATORY,
                            POLICY_SCOPE_MACHINE,
                            POLICY_SOURCE_PUBLIC_SESSION_OVERRIDE,
diff --git a/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc b/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc
index 05e89be..6d92f46a 100644
--- a/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc
+++ b/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc
@@ -107,7 +107,7 @@
   if (value < 0 || value >= static_cast<int>(arraysize(kConnectionTypes)))
     return nullptr;
 
-  return base::MakeUnique<base::StringValue>(kConnectionTypes[value]);
+  return base::MakeUnique<base::Value>(kConnectionTypes[value]);
 }
 
 void DecodeLoginPolicies(const em::ChromeDeviceSettingsProto& policy,
@@ -238,11 +238,10 @@
                   POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD,
                   std::move(account_list), nullptr);
     if (container.has_auto_login_id()) {
-      policies->Set(
-          key::kDeviceLocalAccountAutoLoginId, POLICY_LEVEL_MANDATORY,
-          POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD,
-          base::MakeUnique<base::StringValue>(container.auto_login_id()),
-          nullptr);
+      policies->Set(key::kDeviceLocalAccountAutoLoginId, POLICY_LEVEL_MANDATORY,
+                    POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD,
+                    base::MakeUnique<base::Value>(container.auto_login_id()),
+                    nullptr);
     }
     if (container.has_auto_login_delay()) {
       policies->Set(key::kDeviceLocalAccountAutoLoginDelay,
@@ -357,7 +356,7 @@
     policies->Set(key::kDeviceLoginScreenDomainAutoComplete,
                   POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
                   POLICY_SOURCE_CLOUD,
-                  base::MakeUnique<base::StringValue>(
+                  base::MakeUnique<base::Value>(
                       container.login_screen_domain_auto_complete()),
                   nullptr);
   }
@@ -425,7 +424,7 @@
         policy.open_network_configuration().open_network_configuration());
     policies->Set(key::kDeviceOpenNetworkConfiguration, POLICY_LEVEL_MANDATORY,
                   POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD,
-                  base::MakeUnique<base::StringValue>(config), nullptr);
+                  base::MakeUnique<base::Value>(config), nullptr);
   }
 }
 
@@ -533,7 +532,7 @@
       std::string channel(container.release_channel());
       policies->Set(key::kChromeOsReleaseChannel, POLICY_LEVEL_MANDATORY,
                     POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD,
-                    base::MakeUnique<base::StringValue>(channel), nullptr);
+                    base::MakeUnique<base::Value>(channel), nullptr);
       // TODO(dubroy): Once http://crosbug.com/17015 is implemented, we won't
       // have to pass the channel in here, only ping the update engine to tell
       // it to fetch the channel from the policy.
@@ -559,11 +558,11 @@
     }
 
     if (container.has_target_version_prefix()) {
-      policies->Set(key::kDeviceTargetVersionPrefix, POLICY_LEVEL_MANDATORY,
-                    POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD,
-                    base::MakeUnique<base::StringValue>(
-                        container.target_version_prefix()),
-                    nullptr);
+      policies->Set(
+          key::kDeviceTargetVersionPrefix, POLICY_LEVEL_MANDATORY,
+          POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD,
+          base::MakeUnique<base::Value>(container.target_version_prefix()),
+          nullptr);
     }
 
     // target_version_display_name is not actually a policy, but a display
@@ -708,11 +707,11 @@
 
   if (policy.has_system_timezone()) {
     if (policy.system_timezone().has_timezone()) {
-      policies->Set(key::kSystemTimezone, POLICY_LEVEL_MANDATORY,
-                    POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD,
-                    base::MakeUnique<base::StringValue>(
-                        policy.system_timezone().timezone()),
-                    nullptr);
+      policies->Set(
+          key::kSystemTimezone, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
+          POLICY_SOURCE_CLOUD,
+          base::MakeUnique<base::Value>(policy.system_timezone().timezone()),
+          nullptr);
     }
 
     if (policy.system_timezone().has_timezone_detection_type()) {
@@ -761,7 +760,7 @@
     const em::StartUpFlagsProto& container(policy.start_up_flags());
     std::unique_ptr<base::ListValue> flags(new base::ListValue());
     for (const auto& entry : container.flags())
-      flags->Append(base::MakeUnique<base::StringValue>(entry));
+      flags->Append(base::MakeUnique<base::Value>(entry));
     policies->Set(key::kDeviceStartUpFlags, POLICY_LEVEL_MANDATORY,
                   POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, std::move(flags),
                   nullptr);
@@ -772,7 +771,7 @@
       policies->Set(key::kDeviceVariationsRestrictParameter,
                     POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
                     POLICY_SOURCE_CLOUD,
-                    base::MakeUnique<base::StringValue>(
+                    base::MakeUnique<base::Value>(
                         policy.variations_parameter().parameter()),
                     nullptr);
     }
diff --git a/chrome/browser/chromeos/policy/device_status_collector_browsertest.cc b/chrome/browser/chromeos/policy/device_status_collector_browsertest.cc
index b5c33399..20278f2 100644
--- a/chrome/browser/chromeos/policy/device_status_collector_browsertest.cc
+++ b/chrome/browser/chromeos/policy/device_status_collector_browsertest.cc
@@ -1395,19 +1395,17 @@
       test_device_client->AddDevice(dev.device_path, dev.type,
                                     dev.object_path);
       if (*dev.mac_address) {
-        test_device_client->SetDeviceProperty(
-            dev.device_path, shill::kAddressProperty,
-            base::StringValue(dev.mac_address));
+        test_device_client->SetDeviceProperty(dev.device_path,
+                                              shill::kAddressProperty,
+                                              base::Value(dev.mac_address));
       }
       if (*dev.meid) {
         test_device_client->SetDeviceProperty(
-            dev.device_path, shill::kMeidProperty,
-            base::StringValue(dev.meid));
+            dev.device_path, shill::kMeidProperty, base::Value(dev.meid));
       }
       if (*dev.imei) {
         test_device_client->SetDeviceProperty(
-            dev.device_path, shill::kImeiProperty,
-            base::StringValue(dev.imei));
+            dev.device_path, shill::kImeiProperty, base::Value(dev.imei));
       }
     }
 
@@ -1431,13 +1429,13 @@
       service_client->SetServiceProperty(
           fake_network.name, shill::kSignalStrengthProperty,
           base::Value(fake_network.signal_strength));
-      service_client->SetServiceProperty(
-          fake_network.name, shill::kDeviceProperty,
-          base::StringValue(fake_network.device_path));
+      service_client->SetServiceProperty(fake_network.name,
+                                         shill::kDeviceProperty,
+                                         base::Value(fake_network.device_path));
       // Set the profile so this shows up as a configured network.
-      service_client->SetServiceProperty(
-          fake_network.name, shill::kProfileProperty,
-          base::StringValue(fake_network.name));
+      service_client->SetServiceProperty(fake_network.name,
+                                         shill::kProfileProperty,
+                                         base::Value(fake_network.name));
       if (strlen(fake_network.address) > 0) {
         // Set the IP config.
         base::DictionaryValue ip_config_properties;
@@ -1450,9 +1448,9 @@
             GetTestInterface();
         const std::string kIPConfigPath = "test_ip_config";
         ip_config_test->AddIPConfig(kIPConfigPath, ip_config_properties);
-        service_client->SetServiceProperty(
-            fake_network.name, shill::kIPConfigProperty,
-            base::StringValue(kIPConfigPath));
+        service_client->SetServiceProperty(fake_network.name,
+                                           shill::kIPConfigProperty,
+                                           base::Value(kIPConfigPath));
       }
     }
 
@@ -1470,7 +1468,7 @@
         base::Value(kUnconfiguredNetwork.signal_strength));
     service_client->SetServiceProperty(
         kUnconfiguredNetwork.name, shill::kDeviceProperty,
-        base::StringValue(kUnconfiguredNetwork.device_path));
+        base::Value(kUnconfiguredNetwork.device_path));
 
     // Flush out pending state updates.
     base::RunLoop().RunUntilIdle();
diff --git a/chrome/browser/chromeos/policy/network_configuration_updater_unittest.cc b/chrome/browser/chromeos/policy/network_configuration_updater_unittest.cc
index a1bde68..e6123b8 100644
--- a/chrome/browser/chromeos/policy/network_configuration_updater_unittest.cc
+++ b/chrome/browser/chromeos/policy/network_configuration_updater_unittest.cc
@@ -358,7 +358,7 @@
   PolicyMap policy;
   policy.Set(key::kOpenNetworkConfiguration, POLICY_LEVEL_MANDATORY,
              POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-             base::MakeUnique<base::StringValue>(onc_policy), nullptr);
+             base::MakeUnique<base::Value>(onc_policy), nullptr);
   UpdateProviderPolicy(policy);
 
   EXPECT_CALL(network_config_handler_,
@@ -479,7 +479,7 @@
   PolicyMap policy;
   policy.Set(key::kOpenNetworkConfiguration, POLICY_LEVEL_MANDATORY,
              POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-             base::MakeUnique<base::StringValue>(kFakeONC), nullptr);
+             base::MakeUnique<base::Value>(kFakeONC), nullptr);
   UpdateProviderPolicy(policy);
   base::RunLoop().RunUntilIdle();
 
@@ -500,7 +500,7 @@
   PolicyMap policy;
   policy.Set(key::kOpenNetworkConfiguration, POLICY_LEVEL_MANDATORY,
              POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-             base::MakeUnique<base::StringValue>(kFakeONC), nullptr);
+             base::MakeUnique<base::Value>(kFakeONC), nullptr);
   UpdateProviderPolicy(policy);
 
   EXPECT_CALL(network_config_handler_,
@@ -567,7 +567,7 @@
 TEST_P(NetworkConfigurationUpdaterTestWithParam, InitialUpdates) {
   PolicyMap policy;
   policy.Set(GetParam(), POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             POLICY_SOURCE_CLOUD, base::MakeUnique<base::StringValue>(kFakeONC),
+             POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>(kFakeONC),
              nullptr);
   UpdateProviderPolicy(policy);
 
@@ -589,7 +589,7 @@
        PolicyNotSetBeforePolicyProviderInitialized) {
   PolicyMap policy;
   policy.Set(GetParam(), POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             POLICY_SOURCE_CLOUD, base::MakeUnique<base::StringValue>(kFakeONC),
+             POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>(kFakeONC),
              nullptr);
   UpdateProviderPolicy(policy);
 
@@ -617,7 +617,7 @@
 
   PolicyMap policy;
   policy.Set(GetParam(), POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             POLICY_SOURCE_CLOUD, base::MakeUnique<base::StringValue>(kFakeONC),
+             POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>(kFakeONC),
              nullptr);
   UpdateProviderPolicy(policy);
 
@@ -657,7 +657,7 @@
 
   PolicyMap policy;
   policy.Set(GetParam(), POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             POLICY_SOURCE_CLOUD, base::MakeUnique<base::StringValue>(kFakeONC),
+             POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>(kFakeONC),
              nullptr);
   UpdateProviderPolicy(policy);
   Mock::VerifyAndClearExpectations(&network_config_handler_);
diff --git a/chrome/browser/chromeos/policy/policy_cert_service_factory.cc b/chrome/browser/chromeos/policy/policy_cert_service_factory.cc
index 3d8aeb82..246c8ea 100644
--- a/chrome/browser/chromeos/policy/policy_cert_service_factory.cc
+++ b/chrome/browser/chromeos/policy/policy_cert_service_factory.cc
@@ -60,13 +60,13 @@
     const std::string& user_id) {
   ListPrefUpdate update(g_browser_process->local_state(),
                         prefs::kUsedPolicyCertificates);
-  update->Remove(base::StringValue(user_id), NULL);
+  update->Remove(base::Value(user_id), NULL);
 }
 
 // static
 bool PolicyCertServiceFactory::UsedPolicyCertificates(
     const std::string& user_id) {
-  base::StringValue value(user_id);
+  base::Value value(user_id);
   const base::ListValue* list =
       g_browser_process->local_state()->GetList(prefs::kUsedPolicyCertificates);
   if (!list) {
diff --git a/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos_unittest.cc b/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos_unittest.cc
index 1850222..d8f7558 100644
--- a/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos_unittest.cc
+++ b/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos_unittest.cc
@@ -140,7 +140,7 @@
     GetExpectedDefaultPolicy(&policy_map_);
     policy_map_.Set(key::kHomepageLocation, POLICY_LEVEL_MANDATORY,
                     POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-                    base::MakeUnique<base::StringValue>("http://chromium.org"),
+                    base::MakeUnique<base::Value>("http://chromium.org"),
                     nullptr);
     expected_bundle_.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
         .CopyFrom(policy_map_);
diff --git a/chrome/browser/chromeos/policy/user_cloud_policy_store_chromeos_unittest.cc b/chrome/browser/chromeos/policy/user_cloud_policy_store_chromeos_unittest.cc
index 637bc2b..e031a8d 100644
--- a/chrome/browser/chromeos/policy/user_cloud_policy_store_chromeos_unittest.cc
+++ b/chrome/browser/chromeos/policy/user_cloud_policy_store_chromeos_unittest.cc
@@ -122,7 +122,7 @@
     const PolicyMap::Entry* entry =
         store_->policy_map().Get(key::kHomepageLocation);
     ASSERT_TRUE(entry);
-    EXPECT_TRUE(base::StringValue(expected_value).Equals(entry->value.get()));
+    EXPECT_TRUE(base::Value(expected_value).Equals(entry->value.get()));
   }
 
   void StoreUserPolicyKey(const std::string& public_key) {
@@ -158,7 +158,7 @@
     if (previous_value) {
       previous_policy.Set(key::kHomepageLocation, POLICY_LEVEL_MANDATORY,
                           POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-                          base::MakeUnique<base::StringValue>(previous_value),
+                          base::MakeUnique<base::Value>(previous_value),
                           nullptr);
     }
     EXPECT_TRUE(previous_policy.Equals(store_->policy_map()));
diff --git a/chrome/browser/chromeos/preferences_unittest.cc b/chrome/browser/chromeos/preferences_unittest.cc
index 5ab6440..03168441 100644
--- a/chrome/browser/chromeos/preferences_unittest.cc
+++ b/chrome/browser/chromeos/preferences_unittest.cc
@@ -372,13 +372,12 @@
   // Create some values to come from the server.
   syncer::SyncDataList sync_data_list;
   sync_data_list.push_back(CreatePrefSyncData(
-      prefs::kLanguagePreferredLanguagesSyncable, base::StringValue("ru,fi")));
+      prefs::kLanguagePreferredLanguagesSyncable, base::Value("ru,fi")));
   sync_data_list.push_back(CreatePrefSyncData(
-      prefs::kLanguagePreloadEnginesSyncable,
-      base::StringValue("xkb:se::swe")));
-  sync_data_list.push_back(CreatePrefSyncData(
-      prefs::kLanguageEnabledExtensionImesSyncable,
-      base::StringValue(kIdentityIMEID)));
+      prefs::kLanguagePreloadEnginesSyncable, base::Value("xkb:se::swe")));
+  sync_data_list.push_back(
+      CreatePrefSyncData(prefs::kLanguageEnabledExtensionImesSyncable,
+                         base::Value(kIdentityIMEID)));
 
   // Sync for the first time.
   syncer::SyncableService* sync =
@@ -413,23 +412,17 @@
   // Update the global values from the server again.
   syncer::SyncChangeList change_list;
   change_list.push_back(syncer::SyncChange(
-      FROM_HERE,
-      syncer::SyncChange::ACTION_UPDATE,
-      CreatePrefSyncData(
-          prefs::kLanguagePreferredLanguagesSyncable,
-          base::StringValue("de"))));
+      FROM_HERE, syncer::SyncChange::ACTION_UPDATE,
+      CreatePrefSyncData(prefs::kLanguagePreferredLanguagesSyncable,
+                         base::Value("de"))));
   change_list.push_back(syncer::SyncChange(
-      FROM_HERE,
-      syncer::SyncChange::ACTION_UPDATE,
-      CreatePrefSyncData(
-          prefs::kLanguagePreloadEnginesSyncable,
-          base::StringValue(ToInputMethodIds("xkb:de::ger")))));
+      FROM_HERE, syncer::SyncChange::ACTION_UPDATE,
+      CreatePrefSyncData(prefs::kLanguagePreloadEnginesSyncable,
+                         base::Value(ToInputMethodIds("xkb:de::ger")))));
   change_list.push_back(syncer::SyncChange(
-      FROM_HERE,
-      syncer::SyncChange::ACTION_UPDATE,
-      CreatePrefSyncData(
-          prefs::kLanguageEnabledExtensionImesSyncable,
-          base::StringValue(kToUpperIMEID))));
+      FROM_HERE, syncer::SyncChange::ACTION_UPDATE,
+      CreatePrefSyncData(prefs::kLanguageEnabledExtensionImesSyncable,
+                         base::Value(kToUpperIMEID))));
   sync->ProcessSyncChanges(FROM_HERE, change_list);
   content::RunAllBlockingPoolTasksUntilIdle();
 
@@ -465,12 +458,12 @@
   // Create some values to come from the server.
   syncer::SyncDataList sync_data_list;
   sync_data_list.push_back(CreatePrefSyncData(
-      prefs::kLanguagePreferredLanguages, base::StringValue("ru,fi")));
+      prefs::kLanguagePreferredLanguages, base::Value("ru,fi")));
+  sync_data_list.push_back(
+      CreatePrefSyncData(prefs::kLanguagePreloadEngines,
+                         base::Value(ToInputMethodIds("xkb:ru::rus"))));
   sync_data_list.push_back(CreatePrefSyncData(
-      prefs::kLanguagePreloadEngines,
-      base::StringValue(ToInputMethodIds("xkb:ru::rus"))));
-  sync_data_list.push_back(CreatePrefSyncData(
-      prefs::kLanguageEnabledExtensionImes, base::StringValue(kIdentityIMEID)));
+      prefs::kLanguageEnabledExtensionImes, base::Value(kIdentityIMEID)));
 
   // Sync.
   syncer::SyncableService* sync =
@@ -505,13 +498,13 @@
   // Sync. Since this is an existing profile, the local values shouldn't change.
   syncer::SyncDataList sync_data_list;
   sync_data_list.push_back(CreatePrefSyncData(
-      prefs::kLanguagePreferredLanguagesSyncable, base::StringValue("ru,fi")));
-  sync_data_list.push_back(CreatePrefSyncData(
-      prefs::kLanguagePreloadEnginesSyncable,
-      base::StringValue(ToInputMethodIds("xkb:ru::rus"))));
-  sync_data_list.push_back(CreatePrefSyncData(
-      prefs::kLanguageEnabledExtensionImesSyncable,
-      base::StringValue(kToUpperIMEID)));
+      prefs::kLanguagePreferredLanguagesSyncable, base::Value("ru,fi")));
+  sync_data_list.push_back(
+      CreatePrefSyncData(prefs::kLanguagePreloadEnginesSyncable,
+                         base::Value(ToInputMethodIds("xkb:ru::rus"))));
+  sync_data_list.push_back(
+      CreatePrefSyncData(prefs::kLanguageEnabledExtensionImesSyncable,
+                         base::Value(kToUpperIMEID)));
 
   syncer::SyncableService* sync =
       pref_service_->GetSyncableService(
@@ -559,16 +552,16 @@
 
   // Create some tricky values to come from the server.
   syncer::SyncDataList sync_data_list;
-  sync_data_list.push_back(CreatePrefSyncData(
-      prefs::kLanguagePreferredLanguagesSyncable,
-      base::StringValue("ar,fi,es,de,ar")));
+  sync_data_list.push_back(
+      CreatePrefSyncData(prefs::kLanguagePreferredLanguagesSyncable,
+                         base::Value("ar,fi,es,de,ar")));
   sync_data_list.push_back(CreatePrefSyncData(
       prefs::kLanguagePreloadEnginesSyncable,
-      base::StringValue(
+      base::Value(
           "nacl_mozc_us,xkb:ru::rus,xkb:ru::rus,xkb:es::spa,xkb:es::spa")));
-  sync_data_list.push_back(CreatePrefSyncData(
-      prefs::kLanguageEnabledExtensionImesSyncable,
-      base::StringValue(std::string())));
+  sync_data_list.push_back(
+      CreatePrefSyncData(prefs::kLanguageEnabledExtensionImesSyncable,
+                         base::Value(std::string())));
 
   // Sync for the first time.
   syncer::SyncableService* sync =
@@ -612,15 +605,14 @@
       "_comp_ime_nothisisnotactuallyanextensionidxkb:es::spa," +
       ToInputMethodIds("xkb:jp::jpn"));
   syncer::SyncDataList sync_data_list;
+  sync_data_list.push_back(
+      CreatePrefSyncData(prefs::kLanguagePreferredLanguagesSyncable,
+                         base::Value("klingon,en-US")));
   sync_data_list.push_back(CreatePrefSyncData(
-      prefs::kLanguagePreferredLanguagesSyncable,
-      base::StringValue("klingon,en-US")));
-  sync_data_list.push_back(CreatePrefSyncData(
-      prefs::kLanguagePreloadEnginesSyncable,
-      base::StringValue(preload_engines)));
-  sync_data_list.push_back(CreatePrefSyncData(
-      prefs::kLanguageEnabledExtensionImesSyncable,
-      base::StringValue(kUnknownIMEID)));
+      prefs::kLanguagePreloadEnginesSyncable, base::Value(preload_engines)));
+  sync_data_list.push_back(
+      CreatePrefSyncData(prefs::kLanguageEnabledExtensionImesSyncable,
+                         base::Value(kUnknownIMEID)));
 
   // Sync for the first time.
   syncer::SyncableService* sync =
@@ -655,14 +647,12 @@
       "xkb:ru::rus,xkb:xy::xyz," + ToInputMethodIds("xkb:jp::jpn"));
   syncer::SyncDataList sync_data_list;
   sync_data_list.push_back(CreatePrefSyncData(
-      prefs::kLanguagePreferredLanguagesSyncable,
-      base::StringValue("en-US")));
+      prefs::kLanguagePreferredLanguagesSyncable, base::Value("en-US")));
   sync_data_list.push_back(CreatePrefSyncData(
-      prefs::kLanguagePreloadEnginesSyncable,
-      base::StringValue(preload_engines)));
-  sync_data_list.push_back(CreatePrefSyncData(
-      prefs::kLanguageEnabledExtensionImesSyncable,
-      base::StringValue(kUnknownIMEID)));
+      prefs::kLanguagePreloadEnginesSyncable, base::Value(preload_engines)));
+  sync_data_list.push_back(
+      CreatePrefSyncData(prefs::kLanguageEnabledExtensionImesSyncable,
+                         base::Value(kUnknownIMEID)));
 
   // Sync for the first time.
   syncer::SyncableService* sync =
diff --git a/chrome/browser/chromeos/proxy_config_service_impl_unittest.cc b/chrome/browser/chromeos/proxy_config_service_impl_unittest.cc
index 84e0632..71530e9 100644
--- a/chrome/browser/chromeos/proxy_config_service_impl_unittest.cc
+++ b/chrome/browser/chromeos/proxy_config_service_impl_unittest.cc
@@ -350,10 +350,11 @@
         NetworkHandler::Get()->network_state_handler();
     const NetworkState* network = network_state_handler->DefaultNetwork();
     ASSERT_TRUE(network);
-    DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface()->
-        SetServiceProperty(network->path(),
-                           shill::kProxyConfigProperty,
-                           base::StringValue(proxy_config));
+    DBusThreadManager::Get()
+        ->GetShillServiceClient()
+        ->GetTestInterface()
+        ->SetServiceProperty(network->path(), shill::kProxyConfigProperty,
+                             base::Value(proxy_config));
   }
 
   // Synchronously gets the latest proxy config.
diff --git a/chrome/browser/chromeos/proxy_cros_settings_parser.cc b/chrome/browser/chromeos/proxy_cros_settings_parser.cc
index b5bd565..72dd496 100644
--- a/chrome/browser/chromeos/proxy_cros_settings_parser.cc
+++ b/chrome/browser/chromeos/proxy_cros_settings_parser.cc
@@ -17,9 +17,9 @@
 namespace {
 
 base::Value* CreateServerHostValue(const UIProxyConfig::ManualProxy& proxy) {
-  return proxy.server.is_valid() ?
-         new base::StringValue(proxy.server.host_port_pair().host()) :
-         NULL;
+  return proxy.server.is_valid()
+             ? new base::Value(proxy.server.host_port_pair().host())
+             : NULL;
 }
 
 base::Value* CreateServerPortValue(const UIProxyConfig::ManualProxy& proxy) {
@@ -292,7 +292,7 @@
     // Only show pacurl for pac-script mode.
     if (config.mode == UIProxyConfig::MODE_PAC_SCRIPT &&
         config.automatic_proxy.pac_url.is_valid()) {
-      data = new base::StringValue(config.automatic_proxy.pac_url.spec());
+      data = new base::Value(config.automatic_proxy.pac_url.spec());
     }
   } else if (path == kProxySingleHttp) {
     data = CreateServerHostValue(config.single_proxy);
@@ -357,7 +357,7 @@
   // Decorate pref value as CoreOptionsHandler::CreateValueForPref() does.
   base::DictionaryValue* dict = new base::DictionaryValue;
   if (!data)
-    data = new base::StringValue("");
+    data = new base::Value("");
   dict->Set("value", data);
   if (path == kProxyType) {
     if (!controlled_by.empty())
diff --git a/chrome/browser/chromeos/session_length_limiter_unittest.cc b/chrome/browser/chromeos/session_length_limiter_unittest.cc
index 25f17d1..43a7640 100644
--- a/chrome/browser/chromeos/session_length_limiter_unittest.cc
+++ b/chrome/browser/chromeos/session_length_limiter_unittest.cc
@@ -121,10 +121,9 @@
 
 void SessionLengthLimiterTest::SetSessionStartTimePref(
     const base::TimeTicks& session_start_time) {
-  local_state_.SetUserPref(
-      prefs::kSessionStartTime,
-      new base::StringValue(
-          base::Int64ToString(session_start_time.ToInternalValue())));
+  local_state_.SetUserPref(prefs::kSessionStartTime,
+                           new base::Value(base::Int64ToString(
+                               session_start_time.ToInternalValue())));
 }
 
 void SessionLengthLimiterTest::ClearSessionStartTimePref() {
diff --git a/chrome/browser/chromeos/settings/cros_settings.cc b/chrome/browser/chromeos/settings/cros_settings.cc
index a5df79c..91042aac4 100644
--- a/chrome/browser/chromeos/settings/cros_settings.cc
+++ b/chrome/browser/chromeos/settings/cros_settings.cc
@@ -140,7 +140,7 @@
 void CrosSettings::SetString(const std::string& path,
                              const std::string& in_value) {
   DCHECK(CalledOnValidThread());
-  base::StringValue value(in_value);
+  base::Value value(in_value);
   Set(path, value);
 }
 
diff --git a/chrome/browser/chromeos/settings/cros_settings_unittest.cc b/chrome/browser/chromeos/settings/cros_settings_unittest.cc
index 5281063..da1dc1d 100644
--- a/chrome/browser/chromeos/settings/cros_settings_unittest.cc
+++ b/chrome/browser/chromeos/settings/cros_settings_unittest.cc
@@ -133,7 +133,7 @@
 TEST_F(CrosSettingsTest, SetWhitelistWithListOps) {
   std::unique_ptr<base::ListValue> whitelist =
       base::MakeUnique<base::ListValue>();
-  base::StringValue hacky_user("h@xxor");
+  base::Value hacky_user("h@xxor");
   whitelist->Append(hacky_user.CreateDeepCopy());
   AddExpectation(kAccountsPrefAllowNewUser,
                  base::MakeUnique<base::Value>(false));
@@ -146,8 +146,8 @@
 
 TEST_F(CrosSettingsTest, SetWhitelistWithListOps2) {
   base::ListValue whitelist;
-  base::StringValue hacky_user("h@xxor");
-  base::StringValue lamy_user("l@mer");
+  base::Value hacky_user("h@xxor");
+  base::Value lamy_user("l@mer");
   whitelist.Append(hacky_user.CreateDeepCopy());
   std::unique_ptr<base::ListValue> expected_list = whitelist.CreateDeepCopy();
   whitelist.Append(lamy_user.CreateDeepCopy());
diff --git a/chrome/browser/chromeos/settings/device_oauth2_token_service_unittest.cc b/chrome/browser/chromeos/settings/device_oauth2_token_service_unittest.cc
index e2a6a7f..b1fc1c19 100644
--- a/chrome/browser/chromeos/settings/device_oauth2_token_service_unittest.cc
+++ b/chrome/browser/chromeos/settings/device_oauth2_token_service_unittest.cc
@@ -142,8 +142,7 @@
   // (it must have a non-empty value or it won't be used).
   void SetDeviceRefreshTokenInLocalState(const std::string& refresh_token) {
     scoped_testing_local_state_.Get()->SetUserPref(
-        prefs::kDeviceRobotAnyApiRefreshToken,
-        new base::StringValue(refresh_token));
+        prefs::kDeviceRobotAnyApiRefreshToken, new base::Value(refresh_token));
   }
 
   std::string GetValidTokenInfoResponse(const std::string& email) {
diff --git a/chrome/browser/chromeos/settings/device_settings_provider_unittest.cc b/chrome/browser/chromeos/settings/device_settings_provider_unittest.cc
index 7f28e95e..cf507846 100644
--- a/chrome/browser/chromeos/settings/device_settings_provider_unittest.cc
+++ b/chrome/browser/chromeos/settings/device_settings_provider_unittest.cc
@@ -191,7 +191,7 @@
 
   // Helper routine to check value of the LoginScreenDomainAutoComplete policy.
   void VerifyDomainAutoComplete(
-      const base::StringValue* const ptr_to_expected_value) {
+      const base::Value* const ptr_to_expected_value) {
     EXPECT_TRUE(base::Value::Equals(
         provider_->Get(kAccountsPrefLoginScreenDomainAutoComplete),
         ptr_to_expected_value));
@@ -241,7 +241,7 @@
   // Sets should succeed though and be readable from the cache.
   EXPECT_CALL(*this, SettingChanged(_)).Times(AnyNumber());
   EXPECT_CALL(*this, SettingChanged(kReleaseChannel)).Times(1);
-  base::StringValue new_value("stable-channel");
+  base::Value new_value("stable-channel");
   provider_->Set(kReleaseChannel, new_value);
   Mock::VerifyAndClearExpectations(this);
 
@@ -316,9 +316,9 @@
 
   EXPECT_CALL(*this, SettingChanged(_)).Times(AnyNumber());
 
-  base::StringValue value1("beta");
+  base::Value value1("beta");
   provider_->Set(kReleaseChannel, value1);
-  base::StringValue value2("dev");
+  base::Value value2("dev");
   provider_->Set(kReleaseChannel, value2);
 
   // Let the changes propagate through the system.
@@ -425,7 +425,7 @@
   const base::Value expected_disabled_value(true);
   EXPECT_TRUE(base::Value::Equals(provider_->Get(kDeviceDisabled),
                                   &expected_disabled_value));
-  const base::StringValue expected_disabled_message_value(kDisabledMessage);
+  const base::Value expected_disabled_message_value(kDisabledMessage);
   EXPECT_TRUE(base::Value::Equals(provider_->Get(kDeviceDisabledMessage),
                                   &expected_disabled_message_value));
 
@@ -477,7 +477,7 @@
 
   // Check some meaningful value. Policy should be set.
   const std::string domain = "domain.test";
-  const base::StringValue domain_value(domain);
+  const base::Value domain_value(domain);
   SetDomainAutoComplete(domain);
   VerifyDomainAutoComplete(&domain_value);
 }
diff --git a/chrome/browser/chromeos/settings/scoped_cros_settings_test_helper.cc b/chrome/browser/chromeos/settings/scoped_cros_settings_test_helper.cc
index e66d198..ccc9206 100644
--- a/chrome/browser/chromeos/settings/scoped_cros_settings_test_helper.cc
+++ b/chrome/browser/chromeos/settings/scoped_cros_settings_test_helper.cc
@@ -95,7 +95,7 @@
 
 void ScopedCrosSettingsTestHelper::SetString(const std::string& path,
                                              const std::string& in_value) {
-  Set(path, base::StringValue(in_value));
+  Set(path, base::Value(in_value));
 }
 
 void ScopedCrosSettingsTestHelper::StoreCachedDeviceSetting(
diff --git a/chrome/browser/chromeos/settings/stub_cros_settings_provider_unittest.cc b/chrome/browser/chromeos/settings/stub_cros_settings_provider_unittest.cc
index 1a6b4a6..829dbe9 100644
--- a/chrome/browser/chromeos/settings/stub_cros_settings_provider_unittest.cc
+++ b/chrome/browser/chromeos/settings/stub_cros_settings_provider_unittest.cc
@@ -73,7 +73,7 @@
 
 TEST_F(StubCrosSettingsProviderTest, Set) {
   // Setting value and reading it afterwards returns the same value.
-  base::StringValue owner_value("me@owner");
+  base::Value owner_value("me@owner");
   provider_->Set(kDeviceOwner, owner_value);
   AssertPref(kDeviceOwner, &owner_value);
   ExpectObservers(kDeviceOwner, 1);
@@ -81,7 +81,7 @@
 
 TEST_F(StubCrosSettingsProviderTest, SetMissing) {
   // Setting is missing initially but is added by |Set|.
-  base::StringValue pref_value("testing");
+  base::Value pref_value("testing");
   ASSERT_FALSE(provider_->Get(kReleaseChannel));
   provider_->Set(kReleaseChannel, pref_value);
   AssertPref(kReleaseChannel, &pref_value);
diff --git a/chrome/browser/chromeos/settings/system_settings_provider.cc b/chrome/browser/chromeos/settings/system_settings_provider.cc
index 3a0668f..e636b91 100644
--- a/chrome/browser/chromeos/settings/system_settings_provider.cc
+++ b/chrome/browser/chromeos/settings/system_settings_provider.cc
@@ -18,8 +18,8 @@
   system::TimezoneSettings *timezone_settings =
       system::TimezoneSettings::GetInstance();
   timezone_settings->AddObserver(this);
-  timezone_value_.reset(new base::StringValue(
-      timezone_settings->GetCurrentTimezoneID()));
+  timezone_value_.reset(
+      new base::Value(timezone_settings->GetCurrentTimezoneID()));
 }
 
 SystemSettingsProvider::~SystemSettingsProvider() {
@@ -61,8 +61,8 @@
 
 void SystemSettingsProvider::TimezoneChanged(const icu::TimeZone& timezone) {
   // Fires system setting change notification.
-  timezone_value_.reset(new base::StringValue(
-      system::TimezoneSettings::GetTimezoneID(timezone)));
+  timezone_value_.reset(
+      new base::Value(system::TimezoneSettings::GetTimezoneID(timezone)));
   NotifyObservers(kSystemTimezone);
 }
 
diff --git a/chrome/browser/chromeos/settings/system_settings_provider.h b/chrome/browser/chromeos/settings/system_settings_provider.h
index 0a59bc5..e61761f 100644
--- a/chrome/browser/chromeos/settings/system_settings_provider.h
+++ b/chrome/browser/chromeos/settings/system_settings_provider.h
@@ -16,7 +16,6 @@
 
 namespace base {
 class Value;
-using StringValue = Value;
 }
 
 namespace chromeos {
@@ -39,7 +38,7 @@
   // CrosSettingsProvider implementation.
   void DoSet(const std::string& path, const base::Value& in_value) override;
 
-  std::unique_ptr<base::StringValue> timezone_value_;
+  std::unique_ptr<base::Value> timezone_value_;
 
   DISALLOW_COPY_AND_ASSIGN(SystemSettingsProvider);
 };
diff --git a/chrome/browser/chromeos/status/data_promo_notification_unittest.cc b/chrome/browser/chromeos/status/data_promo_notification_unittest.cc
index 901f660..6922e28 100644
--- a/chrome/browser/chromeos/status/data_promo_notification_unittest.cc
+++ b/chrome/browser/chromeos/status/data_promo_notification_unittest.cc
@@ -134,7 +134,7 @@
                              "activated", true /* visible */);
     service_test->SetServiceProperty(
         kCellularServicePath, shill::kActivationStateProperty,
-        base::StringValue(shill::kActivationStateActivated));
+        base::Value(shill::kActivationStateActivated));
     service_test->SetServiceProperty(
         kCellularServicePath, shill::kConnectableProperty, base::Value(true));
   }
diff --git a/chrome/browser/component_updater/origin_trials_component_installer.cc b/chrome/browser/component_updater/origin_trials_component_installer.cc
index 9378dcf..455403d0 100644
--- a/chrome/browser/component_updater/origin_trials_component_installer.cc
+++ b/chrome/browser/component_updater/origin_trials_component_installer.cc
@@ -87,7 +87,7 @@
   std::string override_public_key;
   if (manifest->GetString(kManifestPublicKeyPath, &override_public_key)) {
     local_state->Set(prefs::kOriginTrialPublicKey,
-                     base::StringValue(override_public_key));
+                     base::Value(override_public_key));
   } else {
     local_state->ClearPref(prefs::kOriginTrialPublicKey);
   }
diff --git a/chrome/browser/component_updater/origin_trials_component_installer_unittest.cc b/chrome/browser/component_updater/origin_trials_component_installer_unittest.cc
index 34cbbf0..6fe5938 100644
--- a/chrome/browser/component_updater/origin_trials_component_installer_unittest.cc
+++ b/chrome/browser/component_updater/origin_trials_component_installer_unittest.cc
@@ -115,7 +115,7 @@
 TEST_F(OriginTrialsComponentInstallerTest,
        PublicKeyResetToDefaultWhenOverrideMissing) {
   local_state()->Set(prefs::kOriginTrialPublicKey,
-                     base::StringValue(kExistingPublicKey));
+                     base::Value(kExistingPublicKey));
   ASSERT_EQ(kExistingPublicKey,
             local_state()->GetString(prefs::kOriginTrialPublicKey));
 
diff --git a/chrome/browser/component_updater/supervised_user_whitelist_installer.cc b/chrome/browser/component_updater/supervised_user_whitelist_installer.cc
index d0e79cc..73e0a94 100644
--- a/chrome/browser/component_updater/supervised_user_whitelist_installer.cc
+++ b/chrome/browser/component_updater/supervised_user_whitelist_installer.cc
@@ -439,7 +439,7 @@
   base::ListValue* clients = nullptr;
   success = whitelist_dict->GetList(kClients, &clients);
 
-  const bool removed = clients->Remove(base::StringValue(client_id), nullptr);
+  const bool removed = clients->Remove(base::Value(client_id), nullptr);
 
   if (!clients->empty())
     return removed;
@@ -549,8 +549,8 @@
       clients = new base::ListValue;
       whitelist_dict->Set(kClients, clients);
     }
-    bool success = clients->AppendIfNotPresent(
-        base::MakeUnique<base::StringValue>(client_id));
+    bool success =
+        clients->AppendIfNotPresent(base::MakeUnique<base::Value>(client_id));
     DCHECK(success);
   }
 
diff --git a/chrome/browser/component_updater/widevine_cdm_component_installer.cc b/chrome/browser/component_updater/widevine_cdm_component_installer.cc
index 50dea992..2fc55b9f 100644
--- a/chrome/browser/component_updater/widevine_cdm_component_installer.cc
+++ b/chrome/browser/component_updater/widevine_cdm_component_installer.cc
@@ -367,18 +367,35 @@
     const base::Version& cdm_version,
     const base::FilePath& cdm_install_dir,
     std::unique_ptr<base::DictionaryValue> manifest) {
+  // On some platforms (e.g. Mac) we use symlinks for paths. Since we are
+  // comparing paths below, convert paths to absolute paths to avoid unexpected
+  // failure. base::MakeAbsoluteFilePath() requires IO so it can only be done
+  // in this function.
+  const base::FilePath absolute_cdm_install_dir =
+      base::MakeAbsoluteFilePath(cdm_install_dir);
+  if (absolute_cdm_install_dir.empty()) {
+    PLOG(WARNING) << "Failed to get absolute CDM install path.";
+    return;
+  }
+
   const base::FilePath adapter_version_path =
-      GetPlatformDirectory(cdm_install_dir).AppendASCII(kCdmAdapterVersionName);
+      GetPlatformDirectory(absolute_cdm_install_dir)
+          .AppendASCII(kCdmAdapterVersionName);
   const base::FilePath adapter_install_path =
-      GetPlatformDirectory(cdm_install_dir)
+      GetPlatformDirectory(absolute_cdm_install_dir)
           .AppendASCII(kWidevineCdmAdapterFileName);
 
-  VLOG(1) << "UpdateCdmAdapter: version" << cdm_version.GetString()
-          << " adapter_install_path=" << adapter_install_path.AsUTF8Unsafe()
-          << " adapter_version_path=" << adapter_version_path.AsUTF8Unsafe();
+  VLOG(1) << "UpdateCdmAdapter: version" << cdm_version.GetString();
+  VLOG(1) << " - adapter_install_path=" << adapter_install_path.AsUTF8Unsafe();
+  VLOG(1) << " - adapter_version_path=" << adapter_version_path.AsUTF8Unsafe();
 
   base::FilePath adapter_source_path;
   PathService::Get(chrome::FILE_WIDEVINE_CDM_ADAPTER, &adapter_source_path);
+  adapter_source_path = base::MakeAbsoluteFilePath(adapter_source_path);
+  if (adapter_source_path.empty()) {
+    PLOG(WARNING) << "Failed to get absolute adapter source path.";
+    return;
+  }
 
   const std::string chrome_version = version_info::GetVersionNumber();
   DCHECK(!chrome_version.empty());
@@ -414,8 +431,8 @@
 
   BrowserThread::PostTask(
       content::BrowserThread::UI, FROM_HERE,
-      base::Bind(&RegisterWidevineCdmWithChrome, cdm_version, cdm_install_dir,
-                 base::Passed(&manifest)));
+      base::Bind(&RegisterWidevineCdmWithChrome, cdm_version,
+                 absolute_cdm_install_dir, base::Passed(&manifest)));
 }
 
 #endif  // defined(WIDEVINE_CDM_AVAILABLE) && defined(WIDEVINE_CDM_IS_COMPONENT)
diff --git a/chrome/browser/devtools/devtools_ui_bindings.cc b/chrome/browser/devtools/devtools_ui_bindings.cc
index 91bb6ee7e..a5ef5f6f 100644
--- a/chrome/browser/devtools/devtools_ui_bindings.cc
+++ b/chrome/browser/devtools/devtools_ui_bindings.cc
@@ -290,7 +290,7 @@
   }
 
   base::Value* id = new base::Value(stream_id_);
-  base::StringValue* chunkValue = new base::StringValue(chunk);
+  base::Value* chunkValue = new base::Value(chunk);
   base::Value* encodedValue = new base::Value(encoded);
 
   content::BrowserThread::PostTask(
@@ -633,7 +633,7 @@
 
   base::Value total_size(static_cast<int>(message.length()));
   for (size_t pos = 0; pos < message.length(); pos += kMaxMessageChunkSize) {
-    base::StringValue message_value(message.substr(pos, kMaxMessageChunkSize));
+    base::Value message_value(message.substr(pos, kMaxMessageChunkSize));
     CallClientFunction("DevToolsAPI.dispatchMessageChunk",
                        &message_value, pos ? NULL : &total_size, NULL);
   }
@@ -1090,7 +1090,7 @@
     callback.Run(nullptr);
     return;
   }
-  base::StringValue message_value(message);
+  base::Value message_value(message);
   callback.Run(&message_value);
 }
 
@@ -1130,18 +1130,18 @@
 }
 
 void DevToolsUIBindings::FileSavedAs(const std::string& url) {
-  base::StringValue url_value(url);
+  base::Value url_value(url);
   CallClientFunction("DevToolsAPI.savedURL", &url_value, NULL, NULL);
 }
 
 void DevToolsUIBindings::CanceledFileSaveAs(const std::string& url) {
-  base::StringValue url_value(url);
+  base::Value url_value(url);
   CallClientFunction("DevToolsAPI.canceledSaveURL",
                      &url_value, NULL, NULL);
 }
 
 void DevToolsUIBindings::AppendedTo(const std::string& url) {
-  base::StringValue url_value(url);
+  base::Value url_value(url);
   CallClientFunction("DevToolsAPI.appendedToURL", &url_value, NULL,
                      NULL);
 }
@@ -1156,7 +1156,7 @@
 
 void DevToolsUIBindings::FileSystemRemoved(
     const std::string& file_system_path) {
-  base::StringValue file_system_path_value(file_system_path);
+  base::Value file_system_path_value(file_system_path);
   CallClientFunction("DevToolsAPI.fileSystemRemoved",
                      &file_system_path_value, NULL, NULL);
 }
@@ -1180,7 +1180,7 @@
     int total_work) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   base::Value request_id_value(request_id);
-  base::StringValue file_system_path_value(file_system_path);
+  base::Value file_system_path_value(file_system_path);
   base::Value total_work_value(total_work);
   CallClientFunction("DevToolsAPI.indexingTotalWorkCalculated",
                      &request_id_value, &file_system_path_value,
@@ -1192,7 +1192,7 @@
                                         int worked) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   base::Value request_id_value(request_id);
-  base::StringValue file_system_path_value(file_system_path);
+  base::Value file_system_path_value(file_system_path);
   base::Value worked_value(worked);
   CallClientFunction("DevToolsAPI.indexingWorked", &request_id_value,
                      &file_system_path_value, &worked_value);
@@ -1203,7 +1203,7 @@
   indexing_jobs_.erase(request_id);
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   base::Value request_id_value(request_id);
-  base::StringValue file_system_path_value(file_system_path);
+  base::Value file_system_path_value(file_system_path);
   CallClientFunction("DevToolsAPI.indexingDone", &request_id_value,
                      &file_system_path_value, NULL);
 }
@@ -1219,7 +1219,7 @@
     file_paths_value.AppendString(*it);
   }
   base::Value request_id_value(request_id);
-  base::StringValue file_system_path_value(file_system_path);
+  base::Value file_system_path_value(file_system_path);
   CallClientFunction("DevToolsAPI.searchCompleted", &request_id_value,
                      &file_system_path_value, &file_paths_value);
 }
@@ -1274,9 +1274,10 @@
         new base::DictionaryValue());
     extension_info->Set(
         "startPage",
-        new base::StringValue(extensions::chrome_manifest_urls::GetDevToolsPage(
-                                  extension.get()).spec()));
-    extension_info->Set("name", new base::StringValue(extension->name()));
+        new base::Value(
+            extensions::chrome_manifest_urls::GetDevToolsPage(extension.get())
+                .spec()));
+    extension_info->Set("name", new base::Value(extension->name()));
     extension_info->Set(
         "exposeExperimentalAPIs",
         new base::Value(extension->permissions_data()->HasAPIPermission(
diff --git a/chrome/browser/devtools/devtools_window.cc b/chrome/browser/devtools/devtools_window.cc
index 1fe19787..e27d75b 100644
--- a/chrome/browser/devtools/devtools_window.cc
+++ b/chrome/browser/devtools/devtools_window.cc
@@ -1352,7 +1352,7 @@
       const DevToolsToggleAction::RevealParams* params =
           action.params();
       CHECK(params);
-      base::StringValue url_value(params->url);
+      base::Value url_value(params->url);
       base::Value line_value(static_cast<int>(params->line_number));
       base::Value column_value(static_cast<int>(params->column_number));
       bindings_->CallClientFunction("DevToolsAPI.revealSourceLine",
diff --git a/chrome/browser/download/download_dir_policy_handler.cc b/chrome/browser/download/download_dir_policy_handler.cc
index b64c616f7..cf48ade 100644
--- a/chrome/browser/download/download_dir_policy_handler.cc
+++ b/chrome/browser/download/download_dir_policy_handler.cc
@@ -105,7 +105,7 @@
   if (expanded_value.empty())
     expanded_value = DownloadPrefs::GetDefaultDownloadDirectory().value();
   prefs->SetValue(prefs::kDownloadDefaultDirectory,
-                  base::MakeUnique<base::StringValue>(expanded_value));
+                  base::MakeUnique<base::Value>(expanded_value));
 
   // If the policy is mandatory, prompt for download should be disabled.
   // Otherwise, it would enable a user to bypass the mandatory policy.
diff --git a/chrome/browser/download/download_dir_policy_handler_unittest.cc b/chrome/browser/download/download_dir_policy_handler_unittest.cc
index f7e8acf1..194957cb 100644
--- a/chrome/browser/download/download_dir_policy_handler_unittest.cc
+++ b/chrome/browser/download/download_dir_policy_handler_unittest.cc
@@ -74,7 +74,7 @@
   EXPECT_FALSE(store_->GetValue(prefs::kPromptForDownload, NULL));
   policy.Set(policy::key::kDownloadDirectory, policy::POLICY_LEVEL_MANDATORY,
              policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD,
-             base::MakeUnique<base::StringValue>(std::string()), nullptr);
+             base::MakeUnique<base::Value>(std::string()), nullptr);
   UpdateProviderPolicy(policy);
 
   // Setting a DownloadDirectory should disable the PromptForDownload pref.
@@ -95,7 +95,7 @@
   policy::PolicyMap policy;
   policy.Set(policy::key::kDownloadDirectory, policy::POLICY_LEVEL_MANDATORY,
              policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD,
-             base::MakeUnique<base::StringValue>(kDriveNamePolicyVariableName),
+             base::MakeUnique<base::Value>(kDriveNamePolicyVariableName),
              nullptr);
   UpdateProviderPolicy(policy);
 
@@ -120,15 +120,15 @@
 
   policy.Set(policy::key::kDownloadDirectory, policy::POLICY_LEVEL_MANDATORY,
              policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD,
-             base::MakeUnique<base::StringValue>(kUserIDHash), nullptr);
+             base::MakeUnique<base::Value>(kUserIDHash), nullptr);
   UpdateProviderPolicy(policy);
   EXPECT_FALSE(recommended_store_->GetValue(drive::prefs::kDisableDrive, NULL));
 
   policy.Set(
       policy::key::kDownloadDirectory, policy::POLICY_LEVEL_RECOMMENDED,
       policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD,
-      base::MakeUnique<base::StringValue>(
-          std::string(kDriveNamePolicyVariableName) + kRelativeToDriveRoot),
+      base::MakeUnique<base::Value>(std::string(kDriveNamePolicyVariableName) +
+                                    kRelativeToDriveRoot),
       nullptr);
   UpdateProviderPolicy(policy);
 
@@ -144,7 +144,7 @@
 
   policy.Set(policy::key::kDownloadDirectory, policy::POLICY_LEVEL_RECOMMENDED,
              policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD,
-             base::MakeUnique<base::StringValue>(kUserIDHash), nullptr);
+             base::MakeUnique<base::Value>(kUserIDHash), nullptr);
   UpdateProviderPolicy(policy);
 
   EXPECT_FALSE(recommended_store_->GetValue(prefs::kPromptForDownload, NULL));
diff --git a/chrome/browser/download/download_query_unittest.cc b/chrome/browser/download/download_query_unittest.cc
index 84995e1..9c0a1821 100644
--- a/chrome/browser/download/download_query_unittest.cc
+++ b/chrome/browser/download/download_query_unittest.cc
@@ -128,17 +128,17 @@
 
 template<> void DownloadQueryTest::AddFilter(
     DownloadQuery::FilterType name, const char* cpp_value) {
-  CHECK(query_.AddFilter(name, base::StringValue(cpp_value)));
+  CHECK(query_.AddFilter(name, base::Value(cpp_value)));
 }
 
 template<> void DownloadQueryTest::AddFilter(
     DownloadQuery::FilterType name, std::string cpp_value) {
-  CHECK(query_.AddFilter(name, base::StringValue(cpp_value)));
+  CHECK(query_.AddFilter(name, base::Value(cpp_value)));
 }
 
 template<> void DownloadQueryTest::AddFilter(
     DownloadQuery::FilterType name, const base::char16* cpp_value) {
-  CHECK(query_.AddFilter(name, base::StringValue(cpp_value)));
+  CHECK(query_.AddFilter(name, base::Value(cpp_value)));
 }
 
 template<> void DownloadQueryTest::AddFilter(
@@ -164,7 +164,7 @@
 #if defined(OS_WIN)
 template<> void DownloadQueryTest::AddFilter(
     DownloadQuery::FilterType name, std::wstring cpp_value) {
-  CHECK(query_.AddFilter(name, base::StringValue(cpp_value)));
+  CHECK(query_.AddFilter(name, base::Value(cpp_value)));
 }
 #endif
 
diff --git a/chrome/browser/extensions/activity_log/activity_actions.cc b/chrome/browser/extensions/activity_log/activity_actions.cc
index adc78e0..ec44aec 100644
--- a/chrome/browser/extensions/activity_log/activity_actions.cc
+++ b/chrome/browser/extensions/activity_log/activity_actions.cc
@@ -287,7 +287,7 @@
       result += " PAGE_URL=" + page_url_.spec();
   }
   if (!page_title_.empty()) {
-    base::StringValue title(page_title_);
+    base::Value title(page_title_);
     result += " PAGE_TITLE=" + Serialize(&title);
   }
   if (arg_url_.is_valid()) {
diff --git a/chrome/browser/extensions/activity_log/activity_log.cc b/chrome/browser/extensions/activity_log/activity_log.cc
index f45237d..74cfad3 100644
--- a/chrome/browser/extensions/activity_log/activity_log.cc
+++ b/chrome/browser/extensions/activity_log/activity_log.cc
@@ -278,7 +278,7 @@
       if (action->args()->GetString(url_index, &url_string) &&
           ResolveUrl(action->page_url(), url_string, &arg_url)) {
         action->mutable_args()->Set(url_index,
-                                    new base::StringValue(kArgUrlPlaceholder));
+                                    new base::Value(kArgUrlPlaceholder));
       }
       break;
     }
@@ -309,8 +309,8 @@
         // Single tab ID to translate.
         GetUrlForTabId(tab_id, profile, &arg_url, &arg_incognito);
         if (arg_url.is_valid()) {
-          action->mutable_args()->Set(
-              url_index, new base::StringValue(kArgUrlPlaceholder));
+          action->mutable_args()->Set(url_index,
+                                      new base::Value(kArgUrlPlaceholder));
         }
       } else if (action->mutable_args()->GetList(url_index, &tab_list)) {
         // A list of possible IDs to translate.  Work through in reverse order
@@ -320,13 +320,12 @@
           if (tab_list->GetInteger(i, &tab_id) &&
               GetUrlForTabId(tab_id, profile, &arg_url, &arg_incognito)) {
             if (!arg_incognito)
-              tab_list->Set(i, new base::StringValue(arg_url.spec()));
+              tab_list->Set(i, new base::Value(arg_url.spec()));
             extracted_index = i;
           }
         }
         if (extracted_index >= 0) {
-          tab_list->Set(
-              extracted_index, new base::StringValue(kArgUrlPlaceholder));
+          tab_list->Set(extracted_index, new base::Value(kArgUrlPlaceholder));
         }
       }
       break;
diff --git a/chrome/browser/extensions/activity_log/counting_policy_unittest.cc b/chrome/browser/extensions/activity_log/counting_policy_unittest.cc
index 0df22a3..cad7e143 100644
--- a/chrome/browser/extensions/activity_log/counting_policy_unittest.cc
+++ b/chrome/browser/extensions/activity_log/counting_policy_unittest.cc
@@ -433,8 +433,8 @@
   extension_service_->AddExtension(extension.get());
 
   std::unique_ptr<base::ListValue> args(new base::ListValue());
-  args->Set(0, new base::StringValue("hello"));
-  args->Set(1, new base::StringValue("world"));
+  args->Set(0, new base::Value("hello"));
+  args->Set(1, new base::Value("world"));
   scoped_refptr<Action> action = new Action(extension->id(),
                                             base::Time::Now(),
                                             Action::ACTION_API_CALL,
diff --git a/chrome/browser/extensions/activity_log/fullstream_ui_policy_unittest.cc b/chrome/browser/extensions/activity_log/fullstream_ui_policy_unittest.cc
index 236d43ef..1e0dd11 100644
--- a/chrome/browser/extensions/activity_log/fullstream_ui_policy_unittest.cc
+++ b/chrome/browser/extensions/activity_log/fullstream_ui_policy_unittest.cc
@@ -511,8 +511,8 @@
   extension_service_->AddExtension(extension.get());
 
   std::unique_ptr<base::ListValue> args(new base::ListValue());
-  args->Set(0, new base::StringValue("hello"));
-  args->Set(1, new base::StringValue("world"));
+  args->Set(0, new base::Value("hello"));
+  args->Set(1, new base::Value("world"));
   scoped_refptr<Action> action = new Action(extension->id(),
                                             base::Time::Now(),
                                             Action::ACTION_API_CALL,
diff --git a/chrome/browser/extensions/api/activity_log_private/activity_log_private_api_unittest.cc b/chrome/browser/extensions/api/activity_log_private/activity_log_private_api_unittest.cc
index d813ad5e..ef3ad10 100644
--- a/chrome/browser/extensions/api/activity_log_private/activity_log_private_api_unittest.cc
+++ b/chrome/browser/extensions/api/activity_log_private/activity_log_private_api_unittest.cc
@@ -28,8 +28,8 @@
 
 TEST_F(ActivityLogApiUnitTest, ConvertChromeApiAction) {
   std::unique_ptr<base::ListValue> args(new base::ListValue());
-  args->Set(0, new base::StringValue("hello"));
-  args->Set(1, new base::StringValue("world"));
+  args->Set(0, new base::Value("hello"));
+  args->Set(1, new base::Value("world"));
   scoped_refptr<Action> action(new Action(kExtensionId,
                                           base::Time::Now(),
                                           Action::ACTION_API_CALL,
@@ -46,8 +46,8 @@
 
 TEST_F(ActivityLogApiUnitTest, ConvertDomAction) {
   std::unique_ptr<base::ListValue> args(new base::ListValue());
-  args->Set(0, new base::StringValue("hello"));
-  args->Set(1, new base::StringValue("world"));
+  args->Set(0, new base::Value("hello"));
+  args->Set(1, new base::Value("world"));
   scoped_refptr<Action> action(new Action(kExtensionId,
                                base::Time::Now(),
                                Action::ACTION_DOM_ACCESS,
diff --git a/chrome/browser/extensions/api/cloud_print_private/cloud_print_private_api.cc b/chrome/browser/extensions/api/cloud_print_private/cloud_print_private_api.cc
index a3b40642..71649982 100644
--- a/chrome/browser/extensions/api/cloud_print_private/cloud_print_private_api.cc
+++ b/chrome/browser/extensions/api/cloud_print_private/cloud_print_private_api.cc
@@ -81,7 +81,7 @@
 }
 
 bool CloudPrintPrivateGetHostNameFunction::RunAsync() {
-  SetResult(base::MakeUnique<base::StringValue>(
+  SetResult(base::MakeUnique<base::Value>(
       CloudPrintTestsDelegate::Get()
           ? CloudPrintTestsDelegate::Get()->GetHostName()
           : net::GetHostName()));
@@ -129,7 +129,7 @@
 }
 
 bool CloudPrintPrivateGetClientIdFunction::RunAsync() {
-  SetResult(base::MakeUnique<base::StringValue>(
+  SetResult(base::MakeUnique<base::Value>(
       CloudPrintTestsDelegate::Get()
           ? CloudPrintTestsDelegate::Get()->GetClientId()
           : google_apis::GetOAuth2ClientID(google_apis::CLIENT_CLOUD_PRINT)));
diff --git a/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc b/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc
index a92d060..4b87365 100644
--- a/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc
+++ b/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc
@@ -67,7 +67,7 @@
   scoped_refptr<DesktopCaptureChooseDesktopMediaFunctionBase> self(this);
   if (picker_) {
     picker_.reset();
-    SetResult(base::MakeUnique<base::StringValue>(std::string()));
+    SetResult(base::MakeUnique<base::Value>(std::string()));
     SendResponse(true);
   }
 }
diff --git a/chrome/browser/extensions/api/developer_private/developer_private_api.cc b/chrome/browser/extensions/api/developer_private/developer_private_api.cc
index ccd13f8a..242f8eeb 100644
--- a/chrome/browser/extensions/api/developer_private/developer_private_api.cc
+++ b/chrome/browser/extensions/api/developer_private/developer_private_api.cc
@@ -979,7 +979,7 @@
 
   // TODO(grv) : The unpacked installer should fire an event when complete
   // and return the extension_id.
-  SetResult(base::MakeUnique<base::StringValue>("-1"));
+  SetResult(base::MakeUnique<base::Value>("-1"));
   SendResponse(true);
 }
 
@@ -1153,8 +1153,7 @@
 
 void DeveloperPrivateChoosePathFunction::FileSelected(
     const base::FilePath& path) {
-  Respond(OneArgument(
-      base::MakeUnique<base::StringValue>(path.LossyDisplayName())));
+  Respond(OneArgument(base::MakeUnique<base::Value>(path.LossyDisplayName())));
   Release();
 }
 
diff --git a/chrome/browser/extensions/api/downloads/downloads_api.cc b/chrome/browser/extensions/api/downloads/downloads_api.cc
index c50afbbc..8561193 100644
--- a/chrome/browser/extensions/api/downloads/downloads_api.cc
+++ b/chrome/browser/extensions/api/downloads/downloads_api.cc
@@ -1524,7 +1524,7 @@
     return;
   }
   RecordApiFunctions(DOWNLOADS_FUNCTION_GET_FILE_ICON);
-  SetResult(base::MakeUnique<base::StringValue>(url));
+  SetResult(base::MakeUnique<base::Value>(url));
   SendResponse(true);
 }
 
diff --git a/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.cc b/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.cc
index 38ddb5c..972e8ff 100644
--- a/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.cc
+++ b/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.cc
@@ -142,7 +142,7 @@
 bool EPKPChallengeKeyBase::IsExtensionWhitelisted() const {
   const base::ListValue* list =
       profile_->GetPrefs()->GetList(prefs::kAttestationExtensionWhitelist);
-  base::StringValue value(extension_id_);
+  base::Value value(extension_id_);
   return list->Find(value) != list->end();
 }
 
diff --git a/chrome/browser/extensions/api/extension_action/extension_action_api.cc b/chrome/browser/extensions/api/extension_action/extension_action_api.cc
index 5dc36ad..38cf69ee 100644
--- a/chrome/browser/extensions/api/extension_action/extension_action_api.cc
+++ b/chrome/browser/extensions/api/extension_action/extension_action_api.cc
@@ -527,20 +527,20 @@
 
 ExtensionFunction::ResponseAction
 ExtensionActionGetTitleFunction::RunExtensionAction() {
-  return RespondNow(OneArgument(base::MakeUnique<base::StringValue>(
-      extension_action_->GetTitle(tab_id_))));
+  return RespondNow(OneArgument(
+      base::MakeUnique<base::Value>(extension_action_->GetTitle(tab_id_))));
 }
 
 ExtensionFunction::ResponseAction
 ExtensionActionGetPopupFunction::RunExtensionAction() {
-  return RespondNow(OneArgument(base::MakeUnique<base::StringValue>(
+  return RespondNow(OneArgument(base::MakeUnique<base::Value>(
       extension_action_->GetPopupUrl(tab_id_).spec())));
 }
 
 ExtensionFunction::ResponseAction
 ExtensionActionGetBadgeTextFunction::RunExtensionAction() {
-  return RespondNow(OneArgument(base::MakeUnique<base::StringValue>(
-      extension_action_->GetBadgeText(tab_id_))));
+  return RespondNow(OneArgument(
+      base::MakeUnique<base::Value>(extension_action_->GetBadgeText(tab_id_))));
 }
 
 ExtensionFunction::ResponseAction
diff --git a/chrome/browser/extensions/api/feedback_private/feedback_private_api.cc b/chrome/browser/extensions/api/feedback_private/feedback_private_api.cc
index bf702751..e94081c 100644
--- a/chrome/browser/extensions/api/feedback_private/feedback_private_api.cc
+++ b/chrome/browser/extensions/api/feedback_private/feedback_private_api.cc
@@ -223,7 +223,7 @@
 ExtensionFunction::ResponseAction FeedbackPrivateGetUserEmailFunction::Run() {
   SigninManagerBase* signin_manager = SigninManagerFactory::GetForProfile(
       Profile::FromBrowserContext(browser_context()));
-  return RespondNow(OneArgument(base::MakeUnique<base::StringValue>(
+  return RespondNow(OneArgument(base::MakeUnique<base::Value>(
       signin_manager ? signin_manager->GetAuthenticatedAccountInfo().email
                      : std::string())));
 }
diff --git a/chrome/browser/extensions/api/file_system/file_system_api.cc b/chrome/browser/extensions/api/file_system/file_system_api.cc
index 07de8dd..0563e0f 100644
--- a/chrome/browser/extensions/api/file_system/file_system_api.cc
+++ b/chrome/browser/extensions/api/file_system/file_system_api.cc
@@ -490,7 +490,7 @@
 
   file_path = path_util::PrettifyPath(file_path);
   return RespondNow(
-      OneArgument(base::MakeUnique<base::StringValue>(file_path.value())));
+      OneArgument(base::MakeUnique<base::Value>(file_path.value())));
 }
 
 FileSystemEntryFunction::FileSystemEntryFunction()
diff --git a/chrome/browser/extensions/api/font_settings/font_settings_api.cc b/chrome/browser/extensions/api/font_settings/font_settings_api.cc
index 1d3420a8..0348527 100644
--- a/chrome/browser/extensions/api/font_settings/font_settings_api.cc
+++ b/chrome/browser/extensions/api/font_settings/font_settings_api.cc
@@ -278,7 +278,7 @@
 
   PreferenceAPI::Get(profile)->SetExtensionControlledPref(
       extension_id(), pref_path, kExtensionPrefsScopeRegular,
-      new base::StringValue(params->details.font_id));
+      new base::Value(params->details.font_id));
   return RespondNow(NoArguments());
 }
 
@@ -319,8 +319,8 @@
 
     std::unique_ptr<base::DictionaryValue> font_name(
         new base::DictionaryValue());
-    font_name->Set(kFontIdKey, new base::StringValue(name));
-    font_name->Set(kDisplayNameKey, new base::StringValue(localized_name));
+    font_name->Set(kFontIdKey, new base::Value(name));
+    font_name->Set(kDisplayNameKey, new base::Value(localized_name));
     result->Append(std::move(font_name));
   }
 
diff --git a/chrome/browser/extensions/api/gcm/gcm_api.cc b/chrome/browser/extensions/api/gcm/gcm_api.cc
index dab66217..7f878c3 100644
--- a/chrome/browser/extensions/api/gcm/gcm_api.cc
+++ b/chrome/browser/extensions/api/gcm/gcm_api.cc
@@ -128,7 +128,7 @@
 void GcmRegisterFunction::CompleteFunctionWithResult(
     const std::string& registration_id,
     gcm::GCMClient::Result result) {
-  SetResult(base::MakeUnique<base::StringValue>(registration_id));
+  SetResult(base::MakeUnique<base::Value>(registration_id));
   SetError(GcmResultToError(result));
   SendResponse(gcm::GCMClient::SUCCESS == result);
 }
@@ -182,7 +182,7 @@
 void GcmSendFunction::CompleteFunctionWithResult(
     const std::string& message_id,
     gcm::GCMClient::Result result) {
-  SetResult(base::MakeUnique<base::StringValue>(message_id));
+  SetResult(base::MakeUnique<base::Value>(message_id));
   SetError(GcmResultToError(result));
   SendResponse(gcm::GCMClient::SUCCESS == result);
 }
diff --git a/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc b/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc
index 6f52b003..3ebce8a 100644
--- a/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc
+++ b/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc
@@ -186,7 +186,7 @@
 
 void IdentityGetAuthTokenFunction::CompleteFunctionWithResult(
     const std::string& access_token) {
-  SetResult(base::MakeUnique<base::StringValue>(access_token));
+  SetResult(base::MakeUnique<base::Value>(access_token));
   CompleteAsyncRun(true);
 }
 
diff --git a/chrome/browser/extensions/api/identity/identity_launch_web_auth_flow_function.cc b/chrome/browser/extensions/api/identity/identity_launch_web_auth_flow_function.cc
index 2f00068..882c858b 100644
--- a/chrome/browser/extensions/api/identity/identity_launch_web_auth_flow_function.cc
+++ b/chrome/browser/extensions/api/identity/identity_launch_web_auth_flow_function.cc
@@ -91,7 +91,7 @@
 void IdentityLaunchWebAuthFlowFunction::OnAuthFlowURLChange(
     const GURL& redirect_url) {
   if (redirect_url.GetWithEmptyPath() == final_url_prefix_) {
-    SetResult(base::MakeUnique<base::StringValue>(redirect_url.spec()));
+    SetResult(base::MakeUnique<base::Value>(redirect_url.spec()));
     SendResponse(true);
     if (auth_flow_)
       auth_flow_.release()->DetachDelegateAndDelete();
diff --git a/chrome/browser/extensions/api/instance_id/instance_id_api.cc b/chrome/browser/extensions/api/instance_id/instance_id_api.cc
index afa6daf..0a897d4 100644
--- a/chrome/browser/extensions/api/instance_id/instance_id_api.cc
+++ b/chrome/browser/extensions/api/instance_id/instance_id_api.cc
@@ -95,7 +95,7 @@
 }
 
 void InstanceIDGetIDFunction::GetIDCompleted(const std::string& id) {
-  Respond(OneArgument(base::MakeUnique<base::StringValue>(id)));
+  Respond(OneArgument(base::MakeUnique<base::Value>(id)));
 }
 
 InstanceIDGetCreationTimeFunction::InstanceIDGetCreationTimeFunction() {}
@@ -141,7 +141,7 @@
     const std::string& token,
     instance_id::InstanceID::Result result) {
   if (result == instance_id::InstanceID::SUCCESS)
-    Respond(OneArgument(base::MakeUnique<base::StringValue>(token)));
+    Respond(OneArgument(base::MakeUnique<base::Value>(token)));
   else
     Respond(Error(InstanceIDResultToError(result)));
 }
diff --git a/chrome/browser/extensions/api/language_settings_private/language_settings_private_api.cc b/chrome/browser/extensions/api/language_settings_private/language_settings_private_api.cc
index 514a1be..b2c3ae92 100644
--- a/chrome/browser/extensions/api/language_settings_private/language_settings_private_api.cc
+++ b/chrome/browser/extensions/api/language_settings_private/language_settings_private_api.cc
@@ -440,7 +440,7 @@
 ExtensionFunction::ResponseAction
 LanguageSettingsPrivateGetTranslateTargetLanguageFunction::Run() {
   return RespondNow(OneArgument(
-      base::MakeUnique<base::StringValue>(TranslateService::GetTargetLanguage(
+      base::MakeUnique<base::Value>(TranslateService::GetTargetLanguage(
           chrome_details_.GetProfile()->GetPrefs()))));
 }
 
diff --git a/chrome/browser/extensions/api/mdns/mdns_api_unittest.cc b/chrome/browser/extensions/api/mdns/mdns_api_unittest.cc
index 1158bb2..d103044 100644
--- a/chrome/browser/extensions/api/mdns/mdns_api_unittest.cc
+++ b/chrome/browser/extensions/api/mdns/mdns_api_unittest.cc
@@ -245,7 +245,7 @@
       // Setting app.background.page = "background.html" is sufficient to make
       // the extension type TYPE_PLATFORM_APP.
       manifest.Set(extensions::manifest_keys::kPlatformAppBackgroundPage,
-                   new base::StringValue("background.html"));
+                   new base::Value("background.html"));
     }
 
     std::string error;
diff --git a/chrome/browser/extensions/api/media_galleries/media_galleries_api.cc b/chrome/browser/extensions/api/media_galleries/media_galleries_api.cc
index 57abe0f8..1b9765f2 100644
--- a/chrome/browser/extensions/api/media_galleries/media_galleries_api.cc
+++ b/chrome/browser/extensions/api/media_galleries/media_galleries_api.cc
@@ -743,10 +743,8 @@
       &(*attached_images)[blob_uuids->size()];
   std::unique_ptr<base::DictionaryValue> attached_image(
       new base::DictionaryValue);
-  attached_image->Set(kBlobUUIDKey, new base::StringValue(
-      current_blob->GetUUID()));
-  attached_image->Set(kTypeKey, new base::StringValue(
-      current_image->type));
+  attached_image->Set(kBlobUUIDKey, new base::Value(current_blob->GetUUID()));
+  attached_image->Set(kTypeKey, new base::Value(current_image->type));
   attached_image->Set(
       kSizeKey,
       new base::Value(base::checked_cast<int>(current_image->data.size())));
diff --git a/chrome/browser/extensions/api/messaging/message_service.cc b/chrome/browser/extensions/api/messaging/message_service.cc
index 56d2f39a..154fb99 100644
--- a/chrome/browser/extensions/api/messaging/message_service.cc
+++ b/chrome/browser/extensions/api/messaging/message_service.cc
@@ -85,8 +85,8 @@
     return allow_result;
 
   // Check if the name or the wildcard is in the blacklist.
-  base::StringValue name_value(native_host_name);
-  base::StringValue wildcard_value("*");
+  base::Value name_value(native_host_name);
+  base::Value wildcard_value("*");
   if (blacklist->Find(name_value) == blacklist->end() &&
       blacklist->Find(wildcard_value) == blacklist->end()) {
     return allow_result;
diff --git a/chrome/browser/extensions/api/module/module.cc b/chrome/browser/extensions/api/module/module.cc
index 8c575be..2cec950 100644
--- a/chrome/browser/extensions/api/module/module.cc
+++ b/chrome/browser/extensions/api/module/module.cc
@@ -47,7 +47,7 @@
 
   ExtensionPrefs::Get(browser_context())
       ->UpdateExtensionPref(extension_id(), extension::kUpdateURLData,
-                            new base::StringValue(data));
+                            new base::Value(data));
   return RespondNow(NoArguments());
 }
 
diff --git a/chrome/browser/extensions/api/music_manager_private/music_manager_private_api.cc b/chrome/browser/extensions/api/music_manager_private/music_manager_private_api.cc
index cb0f24b5..341e4cb 100644
--- a/chrome/browser/extensions/api/music_manager_private/music_manager_private_api.cc
+++ b/chrome/browser/extensions/api/music_manager_private/music_manager_private_api.cc
@@ -45,7 +45,7 @@
     SetError(kDeviceIdNotSupported);
     response = false;
   } else {
-    SetResult(base::MakeUnique<base::StringValue>(device_id));
+    SetResult(base::MakeUnique<base::Value>(device_id));
     response = true;
   }
 
diff --git a/chrome/browser/extensions/api/networking_config_chromeos_apitest_chromeos.cc b/chrome/browser/extensions/api/networking_config_chromeos_apitest_chromeos.cc
index 7c3bcfdb..7c967538 100644
--- a/chrome/browser/extensions/api/networking_config_chromeos_apitest_chromeos.cc
+++ b/chrome/browser/extensions/api/networking_config_chromeos_apitest_chromeos.cc
@@ -99,7 +99,7 @@
                              shill::kTypeWifi, shill::kStateOnline,
                              true /* add_to_visible */);
     service_test->SetServiceProperty(kWifi1ServicePath, shill::kWifiBSsid,
-                                     base::StringValue("01:02:ab:7f:90:00"));
+                                     base::Value("01:02:ab:7f:90:00"));
     service_test->SetServiceProperty(
         kWifi1ServicePath, shill::kSignalStrengthProperty, base::Value(40));
     profile_test->AddService(ShillProfileClient::GetSharedProfilePath(),
diff --git a/chrome/browser/extensions/api/networking_private/networking_private_chromeos_apitest.cc b/chrome/browser/extensions/api/networking_private/networking_private_chromeos_apitest.cc
index ba49075..ae542c1 100644
--- a/chrome/browser/extensions/api/networking_private/networking_private_chromeos_apitest.cc
+++ b/chrome/browser/extensions/api/networking_private/networking_private_chromeos_apitest.cc
@@ -231,16 +231,16 @@
                             "stub_cellular_device1");
     device_test_->SetDeviceProperty(kCellularDevicePath,
                                     shill::kCarrierProperty,
-                                    base::StringValue("Cellular1_Carrier"));
+                                    base::Value("Cellular1_Carrier"));
     base::DictionaryValue home_provider;
     home_provider.SetString("name", "Cellular1_Provider");
     home_provider.SetString("code", "000000");
     home_provider.SetString("country", "us");
     device_test_->SetDeviceProperty(
         kCellularDevicePath, shill::kHomeProviderProperty, home_provider);
-    device_test_->SetDeviceProperty(
-        kCellularDevicePath, shill::kTechnologyFamilyProperty,
-        base::StringValue(shill::kNetworkTechnologyGsm));
+    device_test_->SetDeviceProperty(kCellularDevicePath,
+                                    shill::kTechnologyFamilyProperty,
+                                    base::Value(shill::kNetworkTechnologyGsm));
     device_test_->SetSimLocked(kCellularDevicePath, false);
 
     // Add the Cellular Service.
@@ -250,13 +250,13 @@
         kCellular1ServicePath, shill::kAutoConnectProperty, base::Value(true));
     service_test_->SetServiceProperty(
         kCellular1ServicePath, shill::kNetworkTechnologyProperty,
-        base::StringValue(shill::kNetworkTechnologyGsm));
+        base::Value(shill::kNetworkTechnologyGsm));
     service_test_->SetServiceProperty(
         kCellular1ServicePath, shill::kActivationStateProperty,
-        base::StringValue(shill::kActivationStateNotActivated));
-    service_test_->SetServiceProperty(
-        kCellular1ServicePath, shill::kRoamingStateProperty,
-        base::StringValue(shill::kRoamingStateHome));
+        base::Value(shill::kActivationStateNotActivated));
+    service_test_->SetServiceProperty(kCellular1ServicePath,
+                                      shill::kRoamingStateProperty,
+                                      base::Value(shill::kRoamingStateHome));
 
     profile_test_->AddService(kUser1ProfilePath, kCellular1ServicePath);
     content::RunAllPendingInMessageLoop();
@@ -331,14 +331,14 @@
     device_test_->SetDeviceProperty(kWifiDevicePath, shill::kIPConfigsProperty,
                                     wifi_ip_configs);
     device_test_->SetDeviceProperty(kWifiDevicePath, shill::kAddressProperty,
-                                    base::StringValue("001122aabbcc"));
+                                    base::Value("001122aabbcc"));
 
     // Add Services
     AddService("stub_ethernet", "eth0", shill::kTypeEthernet,
                shill::kStateOnline);
     service_test_->SetServiceProperty(
         "stub_ethernet", shill::kProfileProperty,
-        base::StringValue(ShillProfileClient::GetSharedProfilePath()));
+        base::Value(ShillProfileClient::GetSharedProfilePath()));
     profile_test_->AddService(ShillProfileClient::GetSharedProfilePath(),
                               "stub_ethernet");
 
@@ -346,19 +346,18 @@
                shill::kStateOnline);
     service_test_->SetServiceProperty(kWifi1ServicePath,
                                       shill::kSecurityClassProperty,
-                                      base::StringValue(shill::kSecurityWep));
-    service_test_->SetServiceProperty(kWifi1ServicePath,
-                                      shill::kWifiBSsid,
-                                      base::StringValue("00:01:02:03:04:05"));
+                                      base::Value(shill::kSecurityWep));
+    service_test_->SetServiceProperty(kWifi1ServicePath, shill::kWifiBSsid,
+                                      base::Value("00:01:02:03:04:05"));
     service_test_->SetServiceProperty(
         kWifi1ServicePath, shill::kSignalStrengthProperty, base::Value(40));
     service_test_->SetServiceProperty(kWifi1ServicePath,
                                       shill::kProfileProperty,
-                                      base::StringValue(kUser1ProfilePath));
+                                      base::Value(kUser1ProfilePath));
     service_test_->SetServiceProperty(
         kWifi1ServicePath, shill::kConnectableProperty, base::Value(true));
     service_test_->SetServiceProperty(kWifi1ServicePath, shill::kDeviceProperty,
-                                      base::StringValue(kWifiDevicePath));
+                                      base::Value(kWifiDevicePath));
     base::DictionaryValue static_ipconfig;
     static_ipconfig.SetStringWithoutPathExpansion(shill::kAddressProperty,
                                                   "1.2.3.4");
@@ -376,7 +375,7 @@
                shill::kStateIdle);
     service_test_->SetServiceProperty(kWifi2ServicePath,
                                       shill::kSecurityClassProperty,
-                                      base::StringValue(shill::kSecurityPsk));
+                                      base::Value(shill::kSecurityPsk));
     service_test_->SetServiceProperty(
         kWifi2ServicePath, shill::kSignalStrengthProperty, base::Value(80));
     service_test_->SetServiceProperty(
@@ -386,7 +385,7 @@
     service_test_->SetServiceProperty(
         "stub_wimax", shill::kSignalStrengthProperty, base::Value(40));
     service_test_->SetServiceProperty("stub_wimax", shill::kProfileProperty,
-                                      base::StringValue(kUser1ProfilePath));
+                                      base::Value(kUser1ProfilePath));
     service_test_->SetServiceProperty("stub_wimax", shill::kConnectableProperty,
                                       base::Value(true));
     profile_test_->AddService(kUser1ProfilePath, "stub_wimax");
@@ -400,22 +399,21 @@
                                       base::Value(5000));
     service_test_->SetServiceProperty(kWifi2ServicePath,
                                       shill::kProfileProperty,
-                                      base::StringValue(kUser1ProfilePath));
+                                      base::Value(kUser1ProfilePath));
     profile_test_->AddService(kUser1ProfilePath, kWifi2ServicePath);
 
     AddService("stub_vpn1", "vpn1", shill::kTypeVPN, shill::kStateOnline);
-    service_test_->SetServiceProperty(
-        "stub_vpn1", shill::kProviderTypeProperty,
-        base::StringValue(shill::kProviderOpenVpn));
+    service_test_->SetServiceProperty("stub_vpn1", shill::kProviderTypeProperty,
+                                      base::Value(shill::kProviderOpenVpn));
     profile_test_->AddService(kUser1ProfilePath, "stub_vpn1");
 
     AddService("stub_vpn2", "vpn2", shill::kTypeVPN, shill::kStateOffline);
     service_test_->SetServiceProperty(
         "stub_vpn2", shill::kProviderTypeProperty,
-        base::StringValue(shill::kProviderThirdPartyVpn));
+        base::Value(shill::kProviderThirdPartyVpn));
     service_test_->SetServiceProperty(
         "stub_vpn2", shill::kProviderHostProperty,
-        base::StringValue("third_party_provider_extension_id"));
+        base::Value("third_party_provider_extension_id"));
     profile_test_->AddService(kUser1ProfilePath, "stub_vpn2");
 
     content::RunAllPendingInMessageLoop();
@@ -454,9 +452,8 @@
 IN_PROC_BROWSER_TEST_F(NetworkingPrivateChromeOSApiTest, StartActivateSprint) {
   SetupCellular();
   // Set the carrier to Sprint.
-  device_test_->SetDeviceProperty(kCellularDevicePath,
-                                  shill::kCarrierProperty,
-                                  base::StringValue(shill::kCarrierSprint));
+  device_test_->SetDeviceProperty(kCellularDevicePath, shill::kCarrierProperty,
+                                  base::Value(shill::kCarrierSprint));
   EXPECT_TRUE(RunNetworkingSubtest("startActivateSprint")) << message_;
   EXPECT_EQ(0, UIDelegateStub::s_show_account_details_called_);
 }
@@ -566,7 +563,7 @@
       "    }"
       "}";
   service_test_->SetServiceProperty(kWifi2ServicePath, shill::kUIDataProperty,
-                                    base::StringValue(uidata_blob));
+                                    base::Value(uidata_blob));
   service_test_->SetServiceProperty(
       kWifi2ServicePath, shill::kAutoConnectProperty, base::Value(false));
 
@@ -592,10 +589,10 @@
       "}";
 
   policy::PolicyMap policy;
-  policy.Set(
-      policy::key::kOpenNetworkConfiguration, policy::POLICY_LEVEL_MANDATORY,
-      policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD,
-      base::WrapUnique(new base::StringValue(user_policy_blob)), nullptr);
+  policy.Set(policy::key::kOpenNetworkConfiguration,
+             policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER,
+             policy::POLICY_SOURCE_CLOUD,
+             base::WrapUnique(new base::Value(user_policy_blob)), nullptr);
   provider_.UpdateChromePolicy(policy);
 
   content::RunAllPendingInMessageLoop();
diff --git a/chrome/browser/extensions/api/notifications/notifications_api.cc b/chrome/browser/extensions/api/notifications/notifications_api.cc
index cd435f5..eac302ae 100644
--- a/chrome/browser/extensions/api/notifications/notifications_api.cc
+++ b/chrome/browser/extensions/api/notifications/notifications_api.cc
@@ -704,7 +704,7 @@
       notification_id = base::RandBytesAsString(16);
   }
 
-  SetResult(base::MakeUnique<base::StringValue>(notification_id));
+  SetResult(base::MakeUnique<base::Value>(notification_id));
 
   // TODO(dewittj): Add more human-readable error strings if this fails.
   if (!CreateNotification(notification_id, &params_->options))
@@ -817,8 +817,8 @@
           ? api::notifications::PERMISSION_LEVEL_GRANTED
           : api::notifications::PERMISSION_LEVEL_DENIED;
 
-  SetResult(base::MakeUnique<base::StringValue>(
-      api::notifications::ToString(result)));
+  SetResult(
+      base::MakeUnique<base::Value>(api::notifications::ToString(result)));
   SendResponse(true);
 
   return true;
diff --git a/chrome/browser/extensions/api/omnibox/omnibox_api.cc b/chrome/browser/extensions/api/omnibox/omnibox_api.cc
index b984950..69c9e10 100644
--- a/chrome/browser/extensions/api/omnibox/omnibox_api.cc
+++ b/chrome/browser/extensions/api/omnibox/omnibox_api.cc
@@ -74,7 +74,7 @@
   std::unique_ptr<base::DictionaryValue> dict = suggestion.ToValue();
   // Add the content field so that the dictionary can be used to populate an
   // omnibox::SuggestResult.
-  dict->SetWithoutPathExpansion(kSuggestionContent, new base::StringValue(""));
+  dict->SetWithoutPathExpansion(kSuggestionContent, new base::Value(""));
   prefs->UpdateExtensionPref(extension_id,
                              kOmniboxDefaultSuggestion,
                              dict.release());
@@ -112,7 +112,7 @@
     return false;
 
   std::unique_ptr<base::ListValue> args(new base::ListValue());
-  args->Set(0, new base::StringValue(input));
+  args->Set(0, new base::Value(input));
   args->Set(1, new base::Value(suggest_id));
 
   std::unique_ptr<Event> event = base::MakeUnique<Event>(
@@ -140,13 +140,13 @@
       active_tab_permission_granter()->GrantIfRequested(extension);
 
   std::unique_ptr<base::ListValue> args(new base::ListValue());
-  args->Set(0, new base::StringValue(input));
+  args->Set(0, new base::Value(input));
   if (disposition == WindowOpenDisposition::NEW_FOREGROUND_TAB)
-    args->Set(1, new base::StringValue(kForegroundTabDisposition));
+    args->Set(1, new base::Value(kForegroundTabDisposition));
   else if (disposition == WindowOpenDisposition::NEW_BACKGROUND_TAB)
-    args->Set(1, new base::StringValue(kBackgroundTabDisposition));
+    args->Set(1, new base::Value(kBackgroundTabDisposition));
   else
-    args->Set(1, new base::StringValue(kCurrentTabDisposition));
+    args->Set(1, new base::Value(kCurrentTabDisposition));
 
   std::unique_ptr<Event> event = base::MakeUnique<Event>(
       events::OMNIBOX_ON_INPUT_ENTERED, omnibox::OnInputEntered::kEventName,
diff --git a/chrome/browser/extensions/api/permissions/permissions_api_helpers_unittest.cc b/chrome/browser/extensions/api/permissions/permissions_api_helpers_unittest.cc
index 170a37fa..cdaa34d 100644
--- a/chrome/browser/extensions/api/permissions/permissions_api_helpers_unittest.cc
+++ b/chrome/browser/extensions/api/permissions/permissions_api_helpers_unittest.cc
@@ -58,14 +58,13 @@
   std::string expected_apis[] = {"tabs", "fileBrowserHandler",
                                  "fileBrowserHandlerInternal"};
   for (size_t i = 0; i < arraysize(expected_apis); ++i) {
-    std::unique_ptr<base::Value> value(new base::StringValue(expected_apis[i]));
+    std::unique_ptr<base::Value> value(new base::Value(expected_apis[i]));
     EXPECT_NE(api_list->end(), api_list->Find(*value));
   }
 
   std::string expected_origins[] = { "http://a.com/*", "http://b.com/*" };
   for (size_t i = 0; i < arraysize(expected_origins); ++i) {
-    std::unique_ptr<base::Value> value(
-        new base::StringValue(expected_origins[i]));
+    std::unique_ptr<base::Value> value(new base::Value(expected_origins[i]));
     EXPECT_NE(origin_list->end(), origin_list->Find(*value));
   }
 
diff --git a/chrome/browser/extensions/api/preference/preference_api_prefs_unittest.cc b/chrome/browser/extensions/api/preference/preference_api_prefs_unittest.cc
index a4a8933..2c5209a 100644
--- a/chrome/browser/extensions/api/preference/preference_api_prefs_unittest.cc
+++ b/chrome/browser/extensions/api/preference/preference_api_prefs_unittest.cc
@@ -192,9 +192,8 @@
 class ControlledPrefsInstallOneExtension
     : public ExtensionControlledPrefsTest {
   void Initialize() override {
-    InstallExtensionControlledPref(extension1(),
-                                   kPref1,
-                                   new base::StringValue("val1"));
+    InstallExtensionControlledPref(extension1(), kPref1,
+                                   new base::Value("val1"));
   }
   void Verify() override {
     std::string actual = prefs()->pref_service()->GetString(kPref1);
@@ -209,10 +208,10 @@
     : public ExtensionControlledPrefsTest {
  public:
   void Initialize() override {
-    InstallExtensionControlledPref(
-        extension1(), kPref1, new base::StringValue("val1"));
-    InstallExtensionControlledPrefIncognito(
-        extension1(), kPref1, new base::StringValue("val2"));
+    InstallExtensionControlledPref(extension1(), kPref1,
+                                   new base::Value("val1"));
+    InstallExtensionControlledPrefIncognito(extension1(), kPref1,
+                                            new base::Value("val2"));
     std::unique_ptr<PrefService> incog_prefs(
         prefs_.CreateIncognitoPrefService());
     std::string actual = incog_prefs->GetString(kPref1);
@@ -240,10 +239,10 @@
   ControlledPrefsInstallIncognitoSessionOnly() : iteration_(0) {}
 
   void Initialize() override {
-    InstallExtensionControlledPref(
-        extension1(), kPref1, new base::StringValue("val1"));
-    InstallExtensionControlledPrefIncognitoSessionOnly(
-        extension1(), kPref1, new base::StringValue("val2"));
+    InstallExtensionControlledPref(extension1(), kPref1,
+                                   new base::Value("val1"));
+    InstallExtensionControlledPrefIncognitoSessionOnly(extension1(), kPref1,
+                                                       new base::Value("val2"));
     std::unique_ptr<PrefService> incog_prefs(
         prefs_.CreateIncognitoPrefService());
     std::string actual = incog_prefs->GetString(kPref1);
@@ -273,10 +272,10 @@
 
 class ControlledPrefsUninstallExtension : public ExtensionControlledPrefsTest {
   void Initialize() override {
-    InstallExtensionControlledPref(
-        extension1(), kPref1, new base::StringValue("val1"));
-    InstallExtensionControlledPref(
-        extension1(), kPref2, new base::StringValue("val2"));
+    InstallExtensionControlledPref(extension1(), kPref1,
+                                   new base::Value("val1"));
+    InstallExtensionControlledPref(extension1(), kPref2,
+                                   new base::Value("val2"));
     scoped_refptr<ContentSettingsStore> store = content_settings_store();
     ContentSettingsPattern pattern =
         ContentSettingsPattern::FromString("http://[*.]example.com");
@@ -325,7 +324,7 @@
     EXPECT_CALL(observer, OnPreferenceChanged(_));
     EXPECT_CALL(incognito_observer, OnPreferenceChanged(_));
     InstallExtensionControlledPref(extension1(), kPref1,
-        new base::StringValue("https://www.chromium.org"));
+                                   new base::Value("https://www.chromium.org"));
     Mock::VerifyAndClearExpectations(&observer);
     Mock::VerifyAndClearExpectations(&incognito_observer);
 
@@ -333,7 +332,7 @@
     EXPECT_CALL(observer, OnPreferenceChanged(_)).Times(0);
     EXPECT_CALL(incognito_observer, OnPreferenceChanged(_)).Times(0);
     InstallExtensionControlledPref(extension1(), kPref1,
-        new base::StringValue("https://www.chromium.org"));
+                                   new base::Value("https://www.chromium.org"));
     Mock::VerifyAndClearExpectations(&observer);
     Mock::VerifyAndClearExpectations(&incognito_observer);
 
@@ -341,22 +340,22 @@
     EXPECT_CALL(observer, OnPreferenceChanged(_));
     EXPECT_CALL(incognito_observer, OnPreferenceChanged(_));
     InstallExtensionControlledPref(extension1(), kPref1,
-        new base::StringValue("chrome://newtab"));
+                                   new base::Value("chrome://newtab"));
     Mock::VerifyAndClearExpectations(&observer);
     Mock::VerifyAndClearExpectations(&incognito_observer);
     // Change only incognito persistent value.
     EXPECT_CALL(observer, OnPreferenceChanged(_)).Times(0);
     EXPECT_CALL(incognito_observer, OnPreferenceChanged(_));
-    InstallExtensionControlledPrefIncognito(extension1(), kPref1,
-        new base::StringValue("chrome://newtab2"));
+    InstallExtensionControlledPrefIncognito(
+        extension1(), kPref1, new base::Value("chrome://newtab2"));
     Mock::VerifyAndClearExpectations(&observer);
     Mock::VerifyAndClearExpectations(&incognito_observer);
 
     // Change only incognito session-only value.
     EXPECT_CALL(observer, OnPreferenceChanged(_)).Times(0);
     EXPECT_CALL(incognito_observer, OnPreferenceChanged(_));
-    InstallExtensionControlledPrefIncognito(extension1(), kPref1,
-        new base::StringValue("chrome://newtab3"));
+    InstallExtensionControlledPrefIncognito(
+        extension1(), kPref1, new base::Value("chrome://newtab3"));
     Mock::VerifyAndClearExpectations(&observer);
     Mock::VerifyAndClearExpectations(&incognito_observer);
 
@@ -381,8 +380,8 @@
 // Tests disabling an extension.
 class ControlledPrefsDisableExtension : public ExtensionControlledPrefsTest {
   void Initialize() override {
-    InstallExtensionControlledPref(
-        extension1(), kPref1, new base::StringValue("val1"));
+    InstallExtensionControlledPref(extension1(), kPref1,
+                                   new base::Value("val1"));
     std::string actual = prefs()->pref_service()->GetString(kPref1);
     EXPECT_EQ("val1", actual);
     prefs()->SetExtensionDisabled(extension1()->id(),
@@ -398,8 +397,8 @@
 // Tests disabling and reenabling an extension.
 class ControlledPrefsReenableExtension : public ExtensionControlledPrefsTest {
   void Initialize() override {
-    InstallExtensionControlledPref(
-        extension1(), kPref1, new base::StringValue("val1"));
+    InstallExtensionControlledPref(extension1(), kPref1,
+                                   new base::Value("val1"));
     prefs()->SetExtensionDisabled(extension1()->id(),
                                   Extension::DISABLE_USER_ACTION);
     prefs()->SetExtensionEnabled(extension1()->id());
@@ -415,10 +414,10 @@
     : public ExtensionControlledPrefsTest {
  public:
   void Initialize() override {
-    base::StringValue* v1 = new base::StringValue("https://www.chromium.org");
-    base::StringValue* v2 = new base::StringValue("https://www.chromium.org");
-    base::StringValue* v1i = new base::StringValue("https://www.chromium.org");
-    base::StringValue* v2i = new base::StringValue("https://www.chromium.org");
+    base::Value* v1 = new base::Value("https://www.chromium.org");
+    base::Value* v2 = new base::Value("https://www.chromium.org");
+    base::Value* v1i = new base::Value("https://www.chromium.org");
+    base::Value* v2i = new base::Value("https://www.chromium.org");
     // Ownership is taken, value shall not be deleted.
     InstallExtensionControlledPref(extension1(), kPref1, v1);
     InstallExtensionControlledPrefIncognito(extension1(), kPref1, v1i);
@@ -441,8 +440,8 @@
       : iteration_(0) {}
   ~ControlledPrefsDisableExtensions() override {}
   void Initialize() override {
-    InstallExtensionControlledPref(
-        extension1(), kPref1, new base::StringValue("val1"));
+    InstallExtensionControlledPref(extension1(), kPref1,
+                                   new base::Value("val1"));
     // This becomes only active in the second verification phase.
     prefs_.set_extensions_disabled(true);
   }
diff --git a/chrome/browser/extensions/api/settings_overrides/settings_overrides_api.cc b/chrome/browser/extensions/api/settings_overrides/settings_overrides_api.cc
index 2717383..609163e 100644
--- a/chrome/browser/extensions/api/settings_overrides/settings_overrides_api.cc
+++ b/chrome/browser/extensions/api/settings_overrides/settings_overrides_api.cc
@@ -159,7 +159,7 @@
         ExtensionPrefs::Get(profile_)->GetInstallParam(extension->id());
     if (settings->homepage) {
       SetPref(extension->id(), prefs::kHomePage,
-              base::MakeUnique<base::StringValue>(SubstituteInstallParam(
+              base::MakeUnique<base::Value>(SubstituteInstallParam(
                   settings->homepage->spec(), install_parameter)));
       SetPref(extension->id(), prefs::kHomePageIsNewTabPage,
               base::MakeUnique<base::Value>(false));
diff --git a/chrome/browser/extensions/api/storage/policy_value_store_unittest.cc b/chrome/browser/extensions/api/storage/policy_value_store_unittest.cc
index ae8fbef..1bd814d 100644
--- a/chrome/browser/extensions/api/storage/policy_value_store_unittest.cc
+++ b/chrome/browser/extensions/api/storage/policy_value_store_unittest.cc
@@ -143,7 +143,7 @@
 TEST_F(PolicyValueStoreTest, ReadOnly) {
   ValueStore::WriteOptions options = ValueStore::DEFAULTS;
 
-  base::StringValue string_value("value");
+  base::Value string_value("value");
   EXPECT_FALSE(store_->Set(options, "key", string_value)->status().ok());
 
   base::DictionaryValue dict;
@@ -159,7 +159,7 @@
 
 TEST_F(PolicyValueStoreTest, NotifyOnChanges) {
   // Notify when setting the initial policy.
-  const base::StringValue value("111");
+  const base::Value value("111");
   {
     ValueStoreChangeList changes;
     changes.push_back(ValueStoreChange("aaa", nullptr, value.CreateDeepCopy()));
@@ -193,7 +193,7 @@
   Mock::VerifyAndClearExpectations(&observer_);
 
   // Notify when policies change.
-  const base::StringValue new_value("222");
+  const base::Value new_value("222");
   {
     ValueStoreChangeList changes;
     changes.push_back(ValueStoreChange("bbb", value.CreateDeepCopy(),
diff --git a/chrome/browser/extensions/api/storage/settings_apitest.cc b/chrome/browser/extensions/api/storage/settings_apitest.cc
index ac1d74b7..e0c56008a 100644
--- a/chrome/browser/extensions/api/storage/settings_apitest.cc
+++ b/chrome/browser/extensions/api/storage/settings_apitest.cc
@@ -329,7 +329,7 @@
 
   // Set "foo" to "bar" via sync.
   syncer::SyncChangeList sync_changes;
-  base::StringValue bar("bar");
+  base::Value bar("bar");
   sync_changes.push_back(settings_sync_util::CreateAdd(
       extension_id, "foo", bar, kModelType));
   SendChanges(sync_changes);
@@ -374,7 +374,7 @@
 
   // Set "foo" to "bar" via sync.
   syncer::SyncChangeList sync_changes;
-  base::StringValue bar("bar");
+  base::Value bar("bar");
   sync_changes.push_back(settings_sync_util::CreateAdd(
       extension_id, "foo", bar, kModelType));
   SendChanges(sync_changes);
diff --git a/chrome/browser/extensions/api/storage/settings_sync_unittest.cc b/chrome/browser/extensions/api/storage/settings_sync_unittest.cc
index 1f68049..7ac4ca5 100644
--- a/chrome/browser/extensions/api/storage/settings_sync_unittest.cc
+++ b/chrome/browser/extensions/api/storage/settings_sync_unittest.cc
@@ -300,7 +300,7 @@
   syncer::ModelType model_type = syncer::APP_SETTINGS;
   Manifest::Type type = Manifest::TYPE_LEGACY_PACKAGED_APP;
 
-  base::StringValue value1("fooValue");
+  base::Value value1("fooValue");
   base::ListValue value2;
   value2.AppendString("barValue");
 
@@ -349,7 +349,7 @@
   syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
   Manifest::Type type = Manifest::TYPE_EXTENSION;
 
-  base::StringValue value1("fooValue");
+  base::Value value1("fooValue");
   base::ListValue value2;
   value2.AppendString("barValue");
 
@@ -381,7 +381,7 @@
   syncer::ModelType model_type = syncer::APP_SETTINGS;
   Manifest::Type type = Manifest::TYPE_LEGACY_PACKAGED_APP;
 
-  base::StringValue value1("fooValue");
+  base::Value value1("fooValue");
   base::ListValue value2;
   value2.AppendString("barValue");
 
@@ -421,7 +421,7 @@
   syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
   Manifest::Type type = Manifest::TYPE_EXTENSION;
 
-  base::StringValue value1("fooValue");
+  base::Value value1("fooValue");
   base::ListValue value2;
   value2.AppendString("barValue");
 
@@ -494,7 +494,7 @@
   syncer::ModelType model_type = syncer::APP_SETTINGS;
   Manifest::Type type = Manifest::TYPE_LEGACY_PACKAGED_APP;
 
-  base::StringValue value1("fooValue");
+  base::Value value1("fooValue");
   base::ListValue value2;
   value2.AppendString("barValue");
 
@@ -621,7 +621,7 @@
 }
 
 TEST_F(ExtensionSettingsSyncTest, ExtensionAndAppSettingsSyncSeparately) {
-  base::StringValue value1("fooValue");
+  base::Value value1("fooValue");
   base::ListValue value2;
   value2.AppendString("barValue");
 
@@ -680,8 +680,8 @@
   syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
   Manifest::Type type = Manifest::TYPE_EXTENSION;
 
-  base::StringValue fooValue("fooValue");
-  base::StringValue barValue("barValue");
+  base::Value fooValue("fooValue");
+  base::Value barValue("barValue");
 
   // There is a bit of a convoluted method to get storage areas that can fail;
   // hand out TestingValueStore object then toggle them failing/succeeding
@@ -869,8 +869,8 @@
   syncer::ModelType model_type = syncer::APP_SETTINGS;
   Manifest::Type type = Manifest::TYPE_LEGACY_PACKAGED_APP;
 
-  base::StringValue fooValue("fooValue");
-  base::StringValue barValue("barValue");
+  base::Value fooValue("fooValue");
+  base::Value barValue("barValue");
 
   ValueStore* good = AddExtensionAndGetStorage("good", type);
   ValueStore* bad = AddExtensionAndGetStorage("bad", type);
@@ -961,8 +961,8 @@
   syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
   Manifest::Type type = Manifest::TYPE_EXTENSION;
 
-  base::StringValue fooValue("fooValue");
-  base::StringValue barValue("barValue");
+  base::Value fooValue("fooValue");
+  base::Value barValue("barValue");
 
   ValueStore* good = AddExtensionAndGetStorage("good", type);
   ValueStore* bad = AddExtensionAndGetStorage("bad", type);
@@ -1009,8 +1009,8 @@
   syncer::ModelType model_type = syncer::APP_SETTINGS;
   Manifest::Type type = Manifest::TYPE_LEGACY_PACKAGED_APP;
 
-  base::StringValue fooValue("fooValue");
-  base::StringValue barValue("barValue");
+  base::Value fooValue("fooValue");
+  base::Value barValue("barValue");
 
   ValueStore* good = AddExtensionAndGetStorage("good", type);
   ValueStore* bad = AddExtensionAndGetStorage("bad", type);
@@ -1102,8 +1102,8 @@
   syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
   Manifest::Type type = Manifest::TYPE_EXTENSION;
 
-  base::StringValue fooValue("fooValue");
-  base::StringValue barValue("barValue");
+  base::Value fooValue("fooValue");
+  base::Value barValue("barValue");
 
   ValueStore* good = AddExtensionAndGetStorage("good", type);
   ValueStore* bad = AddExtensionAndGetStorage("bad", type);
@@ -1184,8 +1184,8 @@
   syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
   Manifest::Type type = Manifest::TYPE_EXTENSION;
 
-  base::StringValue fooValue("fooValue");
-  base::StringValue barValue("barValue");
+  base::Value fooValue("fooValue");
+  base::Value barValue("barValue");
 
   ValueStore* good = AddExtensionAndGetStorage("good", type);
   ValueStore* bad = AddExtensionAndGetStorage("bad", type);
@@ -1277,7 +1277,7 @@
   for (size_t i = 0; i < 10000; ++i) {
     string_10k.append("a");
   }
-  base::StringValue large_value(string_10k);
+  base::Value large_value(string_10k);
 
   GetSyncableService(model_type)
       ->MergeDataAndStartSyncing(
@@ -1319,7 +1319,7 @@
 
   {
     syncer::SyncDataList sync_data_list;
-    std::unique_ptr<base::Value> string_value(new base::StringValue("value"));
+    std::unique_ptr<base::Value> string_value(new base::Value("value"));
     sync_data_list.push_back(settings_sync_util::CreateData(
         "ext", "key.with.dot", *string_value, model_type));
 
@@ -1335,15 +1335,14 @@
     ASSERT_TRUE(data->status().ok());
 
     base::DictionaryValue expected_data;
-    expected_data.SetWithoutPathExpansion(
-        "key.with.dot",
-        new base::StringValue("value"));
+    expected_data.SetWithoutPathExpansion("key.with.dot",
+                                          new base::Value("value"));
     EXPECT_TRUE(base::Value::Equals(&expected_data, &data->settings()));
   }
 
   // Test dots in keys going to sync.
   {
-    std::unique_ptr<base::Value> string_value(new base::StringValue("spot"));
+    std::unique_ptr<base::Value> string_value(new base::Value("spot"));
     storage->Set(DEFAULTS, "key.with.spot", *string_value);
 
     ASSERT_EQ(1u, sync_processor_->changes().size());
diff --git a/chrome/browser/extensions/api/sync_file_system/sync_file_system_api.cc b/chrome/browser/extensions/api/sync_file_system/sync_file_system_api.cc
index a7fdbf9e..a8f276050 100644
--- a/chrome/browser/extensions/api/sync_file_system/sync_file_system_api.cc
+++ b/chrome/browser/extensions/api/sync_file_system/sync_file_system_api.cc
@@ -371,8 +371,8 @@
 
 ExtensionFunction::ResponseAction
 SyncFileSystemGetConflictResolutionPolicyFunction::Run() {
-  return RespondNow(OneArgument(
-      base::MakeUnique<base::StringValue>(api::sync_file_system::ToString(
+  return RespondNow(
+      OneArgument(base::MakeUnique<base::Value>(api::sync_file_system::ToString(
           api::sync_file_system::CONFLICT_RESOLUTION_POLICY_LAST_WRITE_WIN))));
 }
 
diff --git a/chrome/browser/extensions/api/system_private/system_private_api.cc b/chrome/browser/extensions/api/system_private/system_private_api.cc
index d128aa2..997e83e 100644
--- a/chrome/browser/extensions/api/system_private/system_private_api.cc
+++ b/chrome/browser/extensions/api/system_private/system_private_api.cc
@@ -79,8 +79,8 @@
   EXTENSION_FUNCTION_VALIDATE(
       value >= 0 &&
       value < static_cast<int>(arraysize(kIncognitoModeAvailabilityStrings)));
-  return RespondNow(OneArgument(base::MakeUnique<base::StringValue>(
-      kIncognitoModeAvailabilityStrings[value])));
+  return RespondNow(OneArgument(
+      base::MakeUnique<base::Value>(kIncognitoModeAvailabilityStrings[value])));
 }
 
 ExtensionFunction::ResponseAction SystemPrivateGetUpdateStatusFunction::Run() {
@@ -145,8 +145,8 @@
 }
 
 ExtensionFunction::ResponseAction SystemPrivateGetApiKeyFunction::Run() {
-  return RespondNow(OneArgument(
-      base::MakeUnique<base::StringValue>(google_apis::GetAPIKey())));
+  return RespondNow(
+      OneArgument(base::MakeUnique<base::Value>(google_apis::GetAPIKey())));
 }
 
 void DispatchVolumeChangedEvent(double volume, bool is_volume_muted) {
diff --git a/chrome/browser/extensions/api/tabs/tabs_api.cc b/chrome/browser/extensions/api/tabs/tabs_api.cc
index 9fb95b9c..e39eee5 100644
--- a/chrome/browser/extensions/api/tabs/tabs_api.cc
+++ b/chrome/browser/extensions/api/tabs/tabs_api.cc
@@ -1674,7 +1674,7 @@
     return;
   }
 
-  SetResult(base::MakeUnique<base::StringValue>(base64_result));
+  SetResult(base::MakeUnique<base::Value>(base64_result));
   SendResponse(true);
 }
 
@@ -1784,7 +1784,7 @@
 }
 
 void TabsDetectLanguageFunction::GotLanguage(const std::string& language) {
-  SetResult(base::MakeUnique<base::StringValue>(language.c_str()));
+  SetResult(base::MakeUnique<base::Value>(language.c_str()));
   SendResponse(true);
 
   Release();  // Balanced in Run()
diff --git a/chrome/browser/extensions/api/web_request/web_request_api_unittest.cc b/chrome/browser/extensions/api/web_request/web_request_api_unittest.cc
index c74a5711..044a7e5f 100644
--- a/chrome/browser/extensions/api/web_request/web_request_api_unittest.cc
+++ b/chrome/browser/extensions/api/web_request/web_request_api_unittest.cc
@@ -68,7 +68,6 @@
 using base::BinaryValue;
 using base::DictionaryValue;
 using base::ListValue;
-using base::StringValue;
 using base::Time;
 using base::TimeDelta;
 using base::Value;
@@ -609,7 +608,7 @@
       &raw);
   extensions::subtle::AppendKeyValuePair(
       keys::kRequestBodyRawFileKey,
-      base::MakeUnique<base::StringValue>(std::string()), &raw);
+      base::MakeUnique<base::Value>(std::string()), &raw);
   extensions::subtle::AppendKeyValuePair(
       keys::kRequestBodyRawBytesKey,
       BinaryValue::CreateWithCopiedBuffer(kPlainBlock2, kPlainBlock2Length),
diff --git a/chrome/browser/extensions/chrome_app_sorting.cc b/chrome/browser/extensions/chrome_app_sorting.cc
index 81f9ef5..c924513 100644
--- a/chrome/browser/extensions/chrome_app_sorting.cc
+++ b/chrome/browser/extensions/chrome_app_sorting.cc
@@ -321,9 +321,10 @@
       extension_id, page_ordinal, GetAppLaunchOrdinal(extension_id));
   AddOrdinalMapping(extension_id, page_ordinal, new_app_launch_ordinal);
 
-  base::Value* new_value = new_app_launch_ordinal.IsValid() ?
-      new base::StringValue(new_app_launch_ordinal.ToInternalValue()) :
-      NULL;
+  base::Value* new_value =
+      new_app_launch_ordinal.IsValid()
+          ? new base::Value(new_app_launch_ordinal.ToInternalValue())
+          : NULL;
 
   ExtensionPrefs::Get(browser_context_)->UpdateExtensionPref(
       extension_id,
@@ -400,9 +401,10 @@
       extension_id, GetPageOrdinal(extension_id), app_launch_ordinal);
   AddOrdinalMapping(extension_id, new_page_ordinal, app_launch_ordinal);
 
-  base::Value* new_value = new_page_ordinal.IsValid() ?
-      new base::StringValue(new_page_ordinal.ToInternalValue()) :
-      NULL;
+  base::Value* new_value =
+      new_page_ordinal.IsValid()
+          ? new base::Value(new_page_ordinal.ToInternalValue())
+          : NULL;
 
   ExtensionPrefs::Get(browser_context_)->UpdateExtensionPref(
       extension_id,
diff --git a/chrome/browser/extensions/extension_assets_manager_chromeos.cc b/chrome/browser/extensions/extension_assets_manager_chromeos.cc
index 50bec5a..c6213bc 100644
--- a/chrome/browser/extensions/extension_assets_manager_chromeos.cc
+++ b/chrome/browser/extensions/extension_assets_manager_chromeos.cc
@@ -454,7 +454,7 @@
     versions.push_back(it.key());
   }
 
-  base::StringValue user_name(profile->GetProfileUserName());
+  base::Value user_name(profile->GetProfileUserName());
   for (std::vector<std::string>::const_iterator it = versions.begin();
        it != versions.end(); it++) {
     base::DictionaryValue* version_info = NULL;
diff --git a/chrome/browser/extensions/extension_management.cc b/chrome/browser/extensions/extension_management.cc
index 1e8904b..f169ae0 100644
--- a/chrome/browser/extensions/extension_management.cc
+++ b/chrome/browser/extensions/extension_management.cc
@@ -273,7 +273,7 @@
   default_settings_.reset(new internal::IndividualSettings());
 
   // Parse default settings.
-  const base::StringValue wildcard("*");
+  const base::Value wildcard("*");
   if (denied_list_pref &&
       denied_list_pref->Find(wildcard) != denied_list_pref->end()) {
     default_settings_->installation_mode = INSTALLATION_BLOCKED;
diff --git a/chrome/browser/extensions/extension_management_test_util.cc b/chrome/browser/extensions/extension_management_test_util.cc
index 85b19468..ec6313c 100644
--- a/chrome/browser/extensions/extension_management_test_util.cc
+++ b/chrome/browser/extensions/extension_management_test_util.cc
@@ -233,8 +233,7 @@
     list_value = new base::ListValue();
     pref_->Set(path, list_value);
   }
-  CHECK(
-      list_value->AppendIfNotPresent(base::MakeUnique<base::StringValue>(str)));
+  CHECK(list_value->AppendIfNotPresent(base::MakeUnique<base::Value>(str)));
 }
 
 void ExtensionManagementPrefUpdaterBase::RemoveStringFromList(
@@ -242,7 +241,7 @@
     const std::string& str) {
   base::ListValue* list_value = nullptr;
   if (pref_->GetList(path, &list_value))
-    CHECK(list_value->Remove(base::StringValue(str), nullptr));
+    CHECK(list_value->Remove(base::Value(str), nullptr));
 }
 
 // ExtensionManagementPolicyUpdater --------------------------------------------
diff --git a/chrome/browser/extensions/extension_message_bubble_controller_unittest.cc b/chrome/browser/extensions/extension_message_bubble_controller_unittest.cc
index c599ff74..232e913 100644
--- a/chrome/browser/extensions/extension_message_bubble_controller_unittest.cc
+++ b/chrome/browser/extensions/extension_message_bubble_controller_unittest.cc
@@ -304,7 +304,7 @@
         false);  // is_incognito_enabled.
     extension_prefs_value_map->SetExtensionPref(id, proxy_config::prefs::kProxy,
                                                 kExtensionPrefsScopeRegular,
-                                                new base::StringValue(id));
+                                                new base::Value(id));
 
     if (ExtensionRegistry::Get(profile())->enabled_extensions().GetByID(id))
       return testing::AssertionSuccess();
@@ -915,9 +915,8 @@
                     const base::Time& time,
                     ExtensionPrefs* prefs) {
   std::string time_str = base::Int64ToString(time.ToInternalValue());
-  prefs->UpdateExtensionPref(extension_id,
-                             "install_time",
-                             new base::StringValue(time_str));
+  prefs->UpdateExtensionPref(extension_id, "install_time",
+                             new base::Value(time_str));
 }
 
 // The feature this is meant to test is only implemented on Windows and Mac.
diff --git a/chrome/browser/extensions/extension_service_sync_unittest.cc b/chrome/browser/extensions/extension_service_sync_unittest.cc
index b19b087..5ff7700a 100644
--- a/chrome/browser/extensions/extension_service_sync_unittest.cc
+++ b/chrome/browser/extensions/extension_service_sync_unittest.cc
@@ -1692,7 +1692,7 @@
         supervised_users::kApprovedExtensions, extension_id);
     syncer::SyncData sync_data =
         SupervisedUserSettingsService::CreateSyncDataForSetting(
-            key, base::StringValue(version));
+            key, base::Value(version));
 
     SyncChangeList list(1, SyncChange(FROM_HERE, type, sync_data));
 
diff --git a/chrome/browser/extensions/extension_storage_monitor.cc b/chrome/browser/extensions/extension_storage_monitor.cc
index 238ed9c..6c88c23 100644
--- a/chrome/browser/extensions/extension_storage_monitor.cc
+++ b/chrome/browser/extensions/extension_storage_monitor.cc
@@ -607,11 +607,9 @@
     const std::string& extension_id,
     int64_t next_threshold) {
   extension_prefs_->UpdateExtensionPref(
-      extension_id,
-      kPrefNextStorageThreshold,
-      next_threshold > 0
-          ? new base::StringValue(base::Int64ToString(next_threshold))
-          : NULL);
+      extension_id, kPrefNextStorageThreshold,
+      next_threshold > 0 ? new base::Value(base::Int64ToString(next_threshold))
+                         : NULL);
 }
 
 int64_t ExtensionStorageMonitor::GetNextStorageThresholdFromPrefs(
diff --git a/chrome/browser/geolocation/chrome_access_token_store.cc b/chrome/browser/geolocation/chrome_access_token_store.cc
index 41b3bac9..0aaa8301 100644
--- a/chrome/browser/geolocation/chrome_access_token_store.cc
+++ b/chrome/browser/geolocation/chrome_access_token_store.cc
@@ -118,8 +118,8 @@
   DictionaryPrefUpdate update(g_browser_process->local_state(),
                               prefs::kGeolocationAccessToken);
   base::DictionaryValue* access_token_dictionary = update.Get();
-  access_token_dictionary->SetWithoutPathExpansion(
-      server_url.spec(), new base::StringValue(token));
+  access_token_dictionary->SetWithoutPathExpansion(server_url.spec(),
+                                                   new base::Value(token));
 }
 
 void ChromeAccessTokenStore::SaveAccessToken(
diff --git a/chrome/browser/google/google_update_win.cc b/chrome/browser/google/google_update_win.cc
index c70b2a1..a0b8698 100644
--- a/chrome/browser/google/google_update_win.cc
+++ b/chrome/browser/google/google_update_win.cc
@@ -34,7 +34,6 @@
 #include "chrome/common/url_constants.h"
 #include "chrome/grit/generated_resources.h"
 #include "chrome/install_static/install_util.h"
-#include "chrome/installer/util/browser_distribution.h"
 #include "chrome/installer/util/google_update_settings.h"
 #include "chrome/installer/util/helper.h"
 #include "chrome/installer/util/install_util.h"
@@ -94,9 +93,8 @@
     const base::FilePath& chrome_exe_path,
     bool system_level_install) {
   DCHECK_NE(InstallUtil::IsPerUserInstall(), system_level_install);
-  BrowserDistribution* dist = BrowserDistribution::GetDistribution();
-  base::FilePath user_exe_path = installer::GetChromeInstallPath(false, dist);
-  base::FilePath machine_exe_path = installer::GetChromeInstallPath(true, dist);
+  base::FilePath user_exe_path = installer::GetChromeInstallPath(false);
+  base::FilePath machine_exe_path = installer::GetChromeInstallPath(true);
   if (!base::FilePath::CompareEqualIgnoreCase(chrome_exe_path.value(),
                                         user_exe_path.value()) &&
       !base::FilePath::CompareEqualIgnoreCase(chrome_exe_path.value(),
diff --git a/chrome/browser/google/google_update_win_unittest.cc b/chrome/browser/google/google_update_win_unittest.cc
index 944c3955..033fa73 100644
--- a/chrome/browser/google/google_update_win_unittest.cc
+++ b/chrome/browser/google/google_update_win_unittest.cc
@@ -27,7 +27,6 @@
 #include "base/win/scoped_comptr.h"
 #include "chrome/common/chrome_version.h"
 #include "chrome/install_static/test/scoped_install_details.h"
-#include "chrome/installer/util/browser_distribution.h"
 #include "chrome/installer/util/google_update_settings.h"
 #include "chrome/installer/util/helper.h"
 #include "google_update/google_update_idl.h"
@@ -542,8 +541,8 @@
     // standard install location for this mode (system-level or user-level).
     base::FilePath file_exe;
     ASSERT_TRUE(PathService::Get(base::FILE_EXE, &file_exe));
-    base::FilePath install_dir(installer::GetChromeInstallPath(
-        system_level_install_, BrowserDistribution::GetDistribution()));
+    base::FilePath install_dir(
+        installer::GetChromeInstallPath(system_level_install_));
     file_exe_override_.reset(new base::ScopedPathOverride(
         base::FILE_EXE, install_dir.Append(file_exe.BaseName()),
         true /* is_absolute */, false /* create */));
diff --git a/chrome/browser/media/router/mojo/media_router_mojo_impl.cc b/chrome/browser/media/router/mojo/media_router_mojo_impl.cc
index 82bf5d6..edec152b 100644
--- a/chrome/browser/media/router/mojo/media_router_mojo_impl.cc
+++ b/chrome/browser/media/router/mojo/media_router_mojo_impl.cc
@@ -185,18 +185,17 @@
   }
 
   auto* sinks_query = it->second.get();
-  sinks_query->has_cached_result = true;
-  sinks_query->origins = origins;
   sinks_query->cached_sink_list = sinks;
+  sinks_query->origins = origins;
 
-  if (!sinks_query->observers.might_have_observers()) {
-    DVLOG_WITH_INSTANCE(1)
-        << "Received sink list without any active observers: " << media_source;
-  } else {
+  if (sinks_query->observers.might_have_observers()) {
     for (auto& observer : sinks_query->observers) {
-      observer.OnSinksUpdated(sinks_query->cached_sink_list,
+      observer.OnSinksUpdated(*sinks_query->cached_sink_list,
                               sinks_query->origins);
     }
+  } else {
+    DVLOG_WITH_INSTANCE(1)
+        << "Received sink list without any active observers: " << media_source;
   }
 }
 
@@ -215,8 +214,18 @@
     return;
   }
 
-  for (auto& observer : it->second->observers)
-    observer.OnRoutesUpdated(routes, joinable_route_ids);
+  auto* routes_query = it->second.get();
+  routes_query->cached_route_list = routes;
+  routes_query->joinable_route_ids = joinable_route_ids;
+
+  if (routes_query->observers.might_have_observers()) {
+    for (auto& observer : routes_query->observers)
+      observer.OnRoutesUpdated(routes, joinable_route_ids);
+  } else {
+    DVLOG_WITH_INSTANCE(1)
+        << "Received routes update without any active observers: "
+        << media_source;
+  }
 }
 
 void MediaRouterMojoImpl::RouteResponseReceived(
@@ -393,9 +402,9 @@
   // to it. Fail if |observer| is already registered.
   const std::string& source_id = observer->source().id();
   std::unique_ptr<MediaSinksQuery>& sinks_query = sinks_queries_[source_id];
-  bool new_query = false;
+  bool is_new_query = false;
   if (!sinks_query) {
-    new_query = true;
+    is_new_query = true;
     sinks_query = base::MakeUnique<MediaSinksQuery>();
   } else {
     DCHECK(!sinks_query->observers.HasObserver(observer));
@@ -409,12 +418,12 @@
                              std::vector<url::Origin>());
   } else {
     // Need to call MRPM to start observing sinks if the query is new.
-    if (new_query) {
+    if (is_new_query) {
       SetWakeReason(MediaRouteProviderWakeReason::START_OBSERVING_MEDIA_SINKS);
       RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoStartObservingMediaSinks,
                             base::Unretained(this), source_id));
-    } else if (sinks_query->has_cached_result) {
-      observer->OnSinksUpdated(sinks_query->cached_sink_list,
+    } else if (sinks_query->cached_sink_list) {
+      observer->OnSinksUpdated(*sinks_query->cached_sink_list,
                                sinks_query->origins);
     }
   }
@@ -459,16 +468,48 @@
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   const MediaSource::Id source_id = observer->source_id();
   auto& routes_query = routes_queries_[source_id];
+  bool is_new_query = false;
   if (!routes_query) {
+    is_new_query = true;
     routes_query = base::MakeUnique<MediaRoutesQuery>();
   } else {
     DCHECK(!routes_query->observers.HasObserver(observer));
   }
 
   routes_query->observers.AddObserver(observer);
-  SetWakeReason(MediaRouteProviderWakeReason::START_OBSERVING_MEDIA_ROUTES);
-  RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoStartObservingMediaRoutes,
-                        base::Unretained(this), source_id));
+  if (is_new_query) {
+    SetWakeReason(MediaRouteProviderWakeReason::START_OBSERVING_MEDIA_ROUTES);
+    RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoStartObservingMediaRoutes,
+                          base::Unretained(this), source_id));
+    // The MRPM will call MediaRouterMojoImpl::OnRoutesUpdated() soon, if there
+    // are any existing routes the new observer should be aware of.
+  } else if (routes_query->cached_route_list) {
+    // Return to the event loop before notifying of a cached route list because
+    // MediaRoutesObserver is calling this method from its constructor, and that
+    // must complete before invoking its virtual OnRoutesUpdated() method.
+    content::BrowserThread::PostTask(
+        content::BrowserThread::UI, FROM_HERE,
+        base::Bind(&MediaRouterMojoImpl::NotifyOfExistingRoutesIfRegistered,
+                   weak_factory_.GetWeakPtr(), source_id, observer));
+  }
+}
+
+void MediaRouterMojoImpl::NotifyOfExistingRoutesIfRegistered(
+    const MediaSource::Id& source_id,
+    MediaRoutesObserver* observer) const {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+  // Check that the route query still exists with a cached result, and that the
+  // observer is still registered. Otherwise, there is nothing to report to the
+  // observer.
+  const auto it = routes_queries_.find(source_id);
+  if (it == routes_queries_.end() || !it->second->cached_route_list ||
+      !it->second->observers.HasObserver(observer)) {
+    return;
+  }
+
+  observer->OnRoutesUpdated(*it->second->cached_route_list,
+                            it->second->joinable_route_ids);
 }
 
 void MediaRouterMojoImpl::UnregisterMediaRoutesObserver(
@@ -685,8 +726,7 @@
     for (auto& source_and_query : sinks_queries_) {
       const auto& query = source_and_query.second;
       query->is_active = false;
-      query->has_cached_result = false;
-      query->cached_sink_list.clear();
+      query->cached_sink_list = base::nullopt;
       query->origins.clear();
     }
   } else {
diff --git a/chrome/browser/media/router/mojo/media_router_mojo_impl.h b/chrome/browser/media/router/mojo/media_router_mojo_impl.h
index 73d7187..b5c0d70 100644
--- a/chrome/browser/media/router/mojo/media_router_mojo_impl.h
+++ b/chrome/browser/media/router/mojo/media_router_mojo_impl.h
@@ -20,6 +20,7 @@
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "base/observer_list.h"
+#include "base/optional.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "build/build_config.h"
 #include "chrome/browser/media/router/issue.h"
@@ -170,13 +171,10 @@
     // True if the query has been sent to the MRPM.
     bool is_active = false;
 
-    // True if cached result is available.
-    bool has_cached_result = false;
-
-    // Cached list of sinks for the query, if |has_cached_result| is true.
-    // Empty otherwise.
-    std::vector<MediaSink> cached_sink_list;
+    // Cached list of sinks and origins for the query.
+    base::Optional<std::vector<MediaSink>> cached_sink_list;
     std::vector<url::Origin> origins;
+
     base::ObserverList<MediaSinksObserver> observers;
 
    private:
@@ -190,6 +188,11 @@
 
     // True if the query has been sent to the MRPM.  False otherwise.
     bool is_active = false;
+
+    // Cached list of routes and joinable route IDs for the query.
+    base::Optional<std::vector<MediaRoute>> cached_route_list;
+    std::vector<std::string> joinable_route_ids;
+
     base::ObserverList<MediaRoutesObserver> observers;
 
    private:
@@ -232,6 +235,11 @@
   void RegisterRouteMessageObserver(RouteMessageObserver* observer) override;
   void UnregisterRouteMessageObserver(RouteMessageObserver* observer) override;
 
+  // Notifies |observer| of any existing cached routes, if it is still
+  // registered.
+  void NotifyOfExistingRoutesIfRegistered(const MediaSource::Id& source_id,
+                                          MediaRoutesObserver* observer) const;
+
   // These calls invoke methods in the component extension via Mojo.
   void DoCreateRoute(const MediaSource::Id& source_id,
                      const MediaSink::Id& sink_id,
diff --git a/chrome/browser/media/router/mojo/media_router_mojo_impl_unittest.cc b/chrome/browser/media/router/mojo/media_router_mojo_impl_unittest.cc
index 45ed335..20dfac3 100644
--- a/chrome/browser/media/router/mojo/media_router_mojo_impl_unittest.cc
+++ b/chrome/browser/media/router/mojo/media_router_mojo_impl_unittest.cc
@@ -56,6 +56,7 @@
 using testing::Return;
 using testing::ReturnRef;
 using testing::SaveArg;
+using testing::Sequence;
 
 namespace media_router {
 
@@ -806,7 +807,7 @@
   MediaSource different_media_source(kSource2);
   EXPECT_CALL(mock_media_route_provider_,
               StartObservingMediaRoutes(media_source.id()))
-      .Times(2);
+      .Times(1);
   EXPECT_CALL(
       mock_media_route_provider_,
       StartObservingMediaRoutes(different_media_source.id()))
@@ -869,6 +870,62 @@
   ProcessEventLoop();
 }
 
+// Tests that multiple MediaRoutesObservers having the same query do not cause
+// extra extension wake-ups because the OnRoutesUpdated() results are cached.
+TEST_F(MediaRouterMojoImplTest, RegisterMediaRoutesObserver_DedupingWithCache) {
+  const MediaSource media_source = MediaSource(kSource);
+  std::vector<MediaRoute> expected_routes;
+  expected_routes.push_back(MediaRoute(kRouteId, media_source, kSinkId,
+                                       kDescription, false, "", false));
+  std::vector<MediaRoute::Id> expected_joinable_route_ids;
+  expected_joinable_route_ids.push_back(kJoinableRouteId);
+
+  Sequence sequence;
+
+  // Creating the first observer will wake-up the provider and ask it to start
+  // observing routes having source |kSource|. The provider will respond with
+  // the existing route.
+  EXPECT_CALL(mock_media_route_provider_,
+              StartObservingMediaRoutes(media_source.id()))
+      .Times(1);
+  std::unique_ptr<MockMediaRoutesObserver> observer1(
+      new MockMediaRoutesObserver(router(), media_source.id()));
+  ProcessEventLoop();
+  EXPECT_CALL(*observer1, OnRoutesUpdated(SequenceEquals(expected_routes),
+                                          expected_joinable_route_ids))
+      .Times(1);
+  media_router_proxy_->OnRoutesUpdated(expected_routes, media_source.id(),
+                                       expected_joinable_route_ids);
+  ProcessEventLoop();
+
+  // Creating two more observers will not wake up the provider. Instead, the
+  // cached route list will be returned.
+  std::unique_ptr<MockMediaRoutesObserver> observer2(
+      new MockMediaRoutesObserver(router(), media_source.id()));
+  std::unique_ptr<MockMediaRoutesObserver> observer3(
+      new MockMediaRoutesObserver(router(), media_source.id()));
+  EXPECT_CALL(*observer2, OnRoutesUpdated(SequenceEquals(expected_routes),
+                                          expected_joinable_route_ids))
+      .Times(1);
+  EXPECT_CALL(*observer3, OnRoutesUpdated(SequenceEquals(expected_routes),
+                                          expected_joinable_route_ids))
+      .Times(1);
+  ProcessEventLoop();
+
+  // Kill 2 of three observers, and expect nothing happens at the provider.
+  observer1.reset();
+  observer2.reset();
+  ProcessEventLoop();
+
+  // Kill the final observer, and expect the provider to be woken-up and called
+  // with the "stop observing" notification.
+  EXPECT_CALL(mock_media_route_provider_,
+              StopObservingMediaRoutes(media_source.id()))
+      .Times(1);
+  observer3.reset();
+  ProcessEventLoop();
+}
+
 TEST_F(MediaRouterMojoImplTest, SendRouteMessage) {
   EXPECT_CALL(
       mock_media_route_provider_, SendRouteMessage(kRouteId, kMessage, _))
diff --git a/chrome/browser/media/router/presentation_service_delegate_impl.cc b/chrome/browser/media/router/presentation_service_delegate_impl.cc
index 2cd8f50..0bf2874 100644
--- a/chrome/browser/media/router/presentation_service_delegate_impl.cc
+++ b/chrome/browser/media/router/presentation_service_delegate_impl.cc
@@ -1056,7 +1056,7 @@
           ->GetPrefs()
           ->GetList(prefs::kMediaRouterTabMirroringSources);
   return origins &&
-         origins->Find(base::StringValue(origin.Serialize())) != origins->end();
+         origins->Find(base::Value(origin.Serialize())) != origins->end();
 }
 #endif  // !defined(OS_ANDROID)
 
diff --git a/chrome/browser/media/router/presentation_service_delegate_impl_unittest.cc b/chrome/browser/media/router/presentation_service_delegate_impl_unittest.cc
index eb1632f..e410d16 100644
--- a/chrome/browser/media/router/presentation_service_delegate_impl_unittest.cc
+++ b/chrome/browser/media/router/presentation_service_delegate_impl_unittest.cc
@@ -547,7 +547,7 @@
   {
     ListPrefUpdate update(profile()->GetPrefs(),
                           prefs::kMediaRouterTabMirroringSources);
-    update->AppendIfNotPresent(base::MakeUnique<base::StringValue>(origin));
+    update->AppendIfNotPresent(base::MakeUnique<base::Value>(origin));
   }
 
   // Auto-join requests should be rejected.
@@ -567,7 +567,7 @@
   {
     ListPrefUpdate update(profile()->GetPrefs(),
                           prefs::kMediaRouterTabMirroringSources);
-    update->Remove(base::StringValue(origin), nullptr);
+    update->Remove(base::Value(origin), nullptr);
   }
 
   // Auto-join requests should now go through.
@@ -597,14 +597,14 @@
   {
     ListPrefUpdate update(profile()->GetOffTheRecordProfile()->GetPrefs(),
                           prefs::kMediaRouterTabMirroringSources);
-    update->AppendIfNotPresent(base::MakeUnique<base::StringValue>(origin));
+    update->AppendIfNotPresent(base::MakeUnique<base::Value>(origin));
   }
 
   // Setting the pref in incognito shouldn't set it for the non-incognito
   // profile.
   const base::ListValue* non_incognito_origins =
       profile()->GetPrefs()->GetList(prefs::kMediaRouterTabMirroringSources);
-  EXPECT_EQ(non_incognito_origins->Find(base::StringValue(origin)),
+  EXPECT_EQ(non_incognito_origins->Find(base::Value(origin)),
             non_incognito_origins->end());
 
   // Auto-join requests should be rejected.
@@ -624,7 +624,7 @@
   {
     ListPrefUpdate update(profile()->GetOffTheRecordProfile()->GetPrefs(),
                           prefs::kMediaRouterTabMirroringSources);
-    update->Remove(base::StringValue(origin), nullptr);
+    update->Remove(base::Value(origin), nullptr);
   }
 
   // Auto-join requests should now go through.
diff --git a/chrome/browser/net/disk_cache_dir_policy_handler.cc b/chrome/browser/net/disk_cache_dir_policy_handler.cc
index ec3402f12..150ebadb 100644
--- a/chrome/browser/net/disk_cache_dir_policy_handler.cc
+++ b/chrome/browser/net/disk_cache_dir_policy_handler.cc
@@ -29,7 +29,7 @@
     base::FilePath::StringType expanded_value =
         policy::path_parser::ExpandPathVariables(string_value);
     prefs->SetValue(prefs::kDiskCacheDir,
-                    base::MakeUnique<base::StringValue>(expanded_value));
+                    base::MakeUnique<base::Value>(expanded_value));
   }
 }
 
diff --git a/chrome/browser/net/disk_cache_dir_policy_handler_unittest.cc b/chrome/browser/net/disk_cache_dir_policy_handler_unittest.cc
index c5611bc5..59a3027 100644
--- a/chrome/browser/net/disk_cache_dir_policy_handler_unittest.cc
+++ b/chrome/browser/net/disk_cache_dir_policy_handler_unittest.cc
@@ -41,8 +41,7 @@
   // Use a variable in the value. It should be expanded by the handler.
   const std::string in = "${user_name}/foo";
   policy_.Set(key::kDiskCacheDir, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-              POLICY_SOURCE_CLOUD, base::MakeUnique<base::StringValue>(in),
-              nullptr);
+              POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>(in), nullptr);
   handler_.ApplyPolicySettings(policy_, &prefs_);
 
   const base::Value* value;
diff --git a/chrome/browser/notifications/notifier_state_tracker.cc b/chrome/browser/notifications/notifier_state_tracker.cc
index 6f094080..a7d2a92 100644
--- a/chrome/browser/notifications/notifier_state_tracker.cc
+++ b/chrome/browser/notifications/notifier_state_tracker.cc
@@ -123,12 +123,12 @@
 
   bool add_new_item = false;
   const char* pref_name = NULL;
-  std::unique_ptr<base::StringValue> id;
+  std::unique_ptr<base::Value> id;
   switch (notifier_id.type) {
     case NotifierId::APPLICATION:
       pref_name = prefs::kMessageCenterDisabledExtensionIds;
       add_new_item = !enabled;
-      id.reset(new base::StringValue(notifier_id.id));
+      id.reset(new base::Value(notifier_id.id));
 #if BUILDFLAG(ENABLE_EXTENSIONS)
       FirePermissionLevelChangedEvent(notifier_id, enabled);
 #endif
@@ -137,7 +137,7 @@
 #if defined(OS_CHROMEOS)
       pref_name = prefs::kMessageCenterDisabledSystemComponentIds;
       add_new_item = !enabled;
-      id.reset(new base::StringValue(notifier_id.id));
+      id.reset(new base::Value(notifier_id.id));
 #else
       return;
 #endif
diff --git a/chrome/browser/password_manager/credential_manager_browsertest.cc b/chrome/browser/password_manager/credential_manager_browsertest.cc
index be572bb..4520685 100644
--- a/chrome/browser/password_manager/credential_manager_browsertest.cc
+++ b/chrome/browser/password_manager/credential_manager_browsertest.cc
@@ -118,16 +118,8 @@
 
 IN_PROC_BROWSER_TEST_F(CredentialManagerBrowserTest,
                        StoreSavesPSLMatchedCredential) {
-  // Setup HTTPS server serving files from standard test directory.
-  static constexpr base::FilePath::CharType kDocRoot[] =
-      FILE_PATH_LITERAL("chrome/test/data");
-  net::EmbeddedTestServer https_test_server(
-      net::EmbeddedTestServer::TYPE_HTTPS);
-  https_test_server.ServeFilesFromSourceDirectory(base::FilePath(kDocRoot));
-  ASSERT_TRUE(https_test_server.Start());
-
   // Setup mock certificate for all origins.
-  auto cert = https_test_server.GetCertificate();
+  auto cert = https_test_server().GetCertificate();
   net::CertVerifyResult verify_result;
   verify_result.cert_status = 0;
   verify_result.is_issued_by_known_root = true;
@@ -144,7 +136,7 @@
               .get());
 
   // The call to |GetURL| is needed to get the correct port.
-  GURL psl_url = https_test_server.GetURL("psl.example.com", "/");
+  GURL psl_url = https_test_server().GetURL("psl.example.com", "/");
 
   autofill::PasswordForm signin_form;
   signin_form.signon_realm = psl_url.spec();
@@ -153,7 +145,7 @@
   signin_form.origin = psl_url;
   password_store->AddLogin(signin_form);
 
-  NavigateToURL(https_test_server, "www.example.com",
+  NavigateToURL(https_test_server(), "www.example.com",
                 "/password/password_form.html");
 
   // Call the API to trigger |get| and |store| and redirect.
@@ -187,7 +179,7 @@
   // There should be an entry for both psl.example.com and www.example.com.
   password_manager::TestPasswordStore::PasswordMap passwords =
       password_store->stored_passwords();
-  GURL www_url = https_test_server.GetURL("www.example.com", "/");
+  GURL www_url = https_test_server().GetURL("www.example.com", "/");
   EXPECT_EQ(2U, passwords.size());
   EXPECT_TRUE(base::ContainsKey(passwords, psl_url.spec()));
   EXPECT_TRUE(base::ContainsKey(passwords, www_url.spec()));
diff --git a/chrome/browser/password_manager/password_manager_browsertest.cc b/chrome/browser/password_manager/password_manager_browsertest.cc
index bb692e70..3598b35 100644
--- a/chrome/browser/password_manager/password_manager_browsertest.cc
+++ b/chrome/browser/password_manager/password_manager_browsertest.cc
@@ -52,7 +52,6 @@
 #include "content/public/test/test_utils.h"
 #include "net/base/filename_util.h"
 #include "net/dns/mock_host_resolver.h"
-#include "net/test/embedded_test_server/embedded_test_server.h"
 #include "net/test/embedded_test_server/http_request.h"
 #include "net/test/embedded_test_server/http_response.h"
 #include "net/url_request/test_url_fetcher_factory.h"
@@ -1386,19 +1385,13 @@
       ::switches::kAllowRunningInsecureContent);
   base::CommandLine::ForCurrentProcess()->AppendSwitch(
       ::switches::kIgnoreCertificateErrors);
-  const base::FilePath::CharType kDocRoot[] =
-      FILE_PATH_LITERAL("chrome/test/data");
-  net::EmbeddedTestServer https_test_server(
-      net::EmbeddedTestServer::TYPE_HTTPS);
-  https_test_server.ServeFilesFromSourceDirectory(base::FilePath(kDocRoot));
-  ASSERT_TRUE(https_test_server.Start());
 
   // This test case cannot inject the scripts via content::ExecuteScript() in
   // files served through HTTPS. Therefore the scripts are made part of the HTML
   // site and executed on load.
   std::string path =
       "/password/separate_login_form_with_onload_submit_script.html";
-  GURL https_url(https_test_server.GetURL(path));
+  GURL https_url(https_test_server().GetURL(path));
   ASSERT_TRUE(https_url.SchemeIs(url::kHttpsScheme));
 
   NavigationObserver observer(WebContents());
@@ -1421,15 +1414,9 @@
       ::switches::kAllowRunningInsecureContent);
   base::CommandLine::ForCurrentProcess()->AppendSwitch(
       ::switches::kIgnoreCertificateErrors);
-  const base::FilePath::CharType kDocRoot[] =
-      FILE_PATH_LITERAL("chrome/test/data");
-  net::EmbeddedTestServer https_test_server(
-      net::EmbeddedTestServer::TYPE_HTTPS);
-  https_test_server.ServeFilesFromSourceDirectory(base::FilePath(kDocRoot));
-  ASSERT_TRUE(https_test_server.Start());
 
   std::string path = "/password/password_form.html";
-  GURL https_url(https_test_server.GetURL(path));
+  GURL https_url(https_test_server().GetURL(path));
   ASSERT_TRUE(https_url.SchemeIs(url::kHttpsScheme));
 
   NavigationObserver form_observer(WebContents());
@@ -1490,14 +1477,8 @@
 // Tests that after HTTP -> HTTPS migration the credential is autofilled.
 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
                        HttpMigratedCredentialAutofilled) {
-  net::EmbeddedTestServer https_test_server(
-      net::EmbeddedTestServer::TYPE_HTTPS);
-  https_test_server.ServeFilesFromSourceDirectory(
-      base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
-  ASSERT_TRUE(https_test_server.Start());
-
   // Add an http credential to the password store.
-  GURL https_origin = https_test_server.base_url();
+  GURL https_origin = https_test_server().base_url();
   ASSERT_TRUE(https_origin.SchemeIs(url::kHttpsScheme));
   GURL::Replacements rep;
   rep.SetSchemeStr(url::kHttpScheme);
@@ -1518,7 +1499,7 @@
 
   NavigationObserver form_observer(WebContents());
   ui_test_utils::NavigateToURL(
-      browser(), https_test_server.GetURL("/password/password_form.html"));
+      browser(), https_test_server().GetURL("/password/password_form.html"));
   form_observer.Wait();
   WaitForPasswordStore();
 
diff --git a/chrome/browser/password_manager/password_manager_test_base.cc b/chrome/browser/password_manager/password_manager_test_base.cc
index 5d46088..c398a21 100644
--- a/chrome/browser/password_manager/password_manager_test_base.cc
+++ b/chrome/browser/password_manager/password_manager_test_base.cc
@@ -115,8 +115,8 @@
   EXPECT_FALSE(IsShowingUpdatePrompt());
 }
 
-PasswordManagerBrowserTestBase::PasswordManagerBrowserTestBase() {
-}
+PasswordManagerBrowserTestBase::PasswordManagerBrowserTestBase()
+    : https_test_server_(net::EmbeddedTestServer::TYPE_HTTPS) {}
 PasswordManagerBrowserTestBase::~PasswordManagerBrowserTestBase() {
 }
 
@@ -131,6 +131,12 @@
       password_manager::BuildPasswordStore<
           content::BrowserContext, password_manager::TestPasswordStore>);
   ASSERT_TRUE(embedded_test_server()->Start());
+
+  // Setup HTTPS server serving files from standard test directory.
+  static constexpr base::FilePath::CharType kDocRoot[] =
+      FILE_PATH_LITERAL("chrome/test/data");
+  https_test_server().ServeFilesFromSourceDirectory(base::FilePath(kDocRoot));
+  ASSERT_TRUE(https_test_server().Start());
 }
 
 void PasswordManagerBrowserTestBase::TearDownOnMainThread() {
diff --git a/chrome/browser/password_manager/password_manager_test_base.h b/chrome/browser/password_manager/password_manager_test_base.h
index 96180c9..bb095d7 100644
--- a/chrome/browser/password_manager/password_manager_test_base.h
+++ b/chrome/browser/password_manager/password_manager_test_base.h
@@ -12,6 +12,7 @@
 #include "components/password_manager/core/browser/password_store_consumer.h"
 #include "content/public/browser/web_contents_observer.h"
 #include "content/public/test/test_utils.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
 
 namespace autofill {
 struct PasswordForm;
@@ -138,8 +139,10 @@
   // Accessors
   content::WebContents* WebContents();
   content::RenderViewHost* RenderViewHost();
+  net::EmbeddedTestServer& https_test_server() { return https_test_server_; }
 
  private:
+  net::EmbeddedTestServer https_test_server_;
   DISALLOW_COPY_AND_ASSIGN(PasswordManagerBrowserTestBase);
 };
 
diff --git a/chrome/browser/policy/cloud/cloud_policy_browsertest.cc b/chrome/browser/policy/cloud/cloud_policy_browsertest.cc
index edc27531..04705a3 100644
--- a/chrome/browser/policy/cloud/cloud_policy_browsertest.cc
+++ b/chrome/browser/policy/cloud/cloud_policy_browsertest.cc
@@ -169,7 +169,7 @@
                 base::MakeUnique<base::Value>(1000), nullptr);
   expected->Set(key::kHomepageLocation, POLICY_LEVEL_RECOMMENDED,
                 POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-                base::MakeUnique<base::StringValue>(homepage), nullptr);
+                base::MakeUnique<base::Value>(homepage), nullptr);
 }
 
 }  // namespace
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
index d45468b5..803684c3 100644
--- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc
+++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -247,6 +247,9 @@
   { key::kEnableSha1ForLocalAnchors,
     ssl_config::prefs::kCertEnableSha1LocalAnchors,
     base::Value::Type::BOOLEAN },
+  { key::kEnableCommonNameFallbackForLocalAnchors,
+    ssl_config::prefs::kCertEnableCommonNameFallbackLocalAnchors,
+    base::Value::Type::BOOLEAN },
   { key::kAuthSchemes,
     prefs::kAuthSchemes,
     base::Value::Type::STRING },
diff --git a/chrome/browser/policy/managed_bookmarks_policy_handler_unittest.cc b/chrome/browser/policy/managed_bookmarks_policy_handler_unittest.cc
index bba50c8..8e4a2fc 100644
--- a/chrome/browser/policy/managed_bookmarks_policy_handler_unittest.cc
+++ b/chrome/browser/policy/managed_bookmarks_policy_handler_unittest.cc
@@ -181,15 +181,15 @@
 TEST_F(ManagedBookmarksPolicyHandlerTest, WrongPolicyType) {
   PolicyMap policy;
   // The expected type is base::ListValue, but this policy sets it as an
-  // unparsed base::StringValue. Any type other than ListValue should fail.
+  // unparsed base::Value. Any type other than ListValue should fail.
   policy.Set(key::kManagedBookmarks, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
              POLICY_SOURCE_CLOUD,
-             base::MakeUnique<base::StringValue>("["
-                                                 "  {"
-                                                 "    \"name\": \"Google\","
-                                                 "    \"url\": \"google.com\""
-                                                 "  },"
-                                                 "]"),
+             base::MakeUnique<base::Value>("["
+                                           "  {"
+                                           "    \"name\": \"Google\","
+                                           "    \"url\": \"google.com\""
+                                           "  },"
+                                           "]"),
              nullptr);
   UpdateProviderPolicy(policy);
   EXPECT_FALSE(store_->GetValue(bookmarks::prefs::kManagedBookmarks, NULL));
diff --git a/chrome/browser/policy/policy_browsertest.cc b/chrome/browser/policy/policy_browsertest.cc
index cf6f84c3..d61a51d 100644
--- a/chrome/browser/policy/policy_browsertest.cc
+++ b/chrome/browser/policy/policy_browsertest.cc
@@ -856,7 +856,7 @@
     PolicyMap policies;
     policies.Set(key::kApplicationLocaleValue, POLICY_LEVEL_MANDATORY,
                  POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-                 base::MakeUnique<base::StringValue>("fr"), nullptr);
+                 base::MakeUnique<base::Value>("fr"), nullptr);
     provider_.UpdateChromePolicy(policies);
     // The "en-US" ResourceBundle is always loaded before this step for tests,
     // but in this test we want the browser to load the bundle as it
@@ -995,13 +995,13 @@
                base::MakeUnique<base::Value>(true), nullptr);
   policies.Set(key::kDefaultSearchProviderKeyword, POLICY_LEVEL_MANDATORY,
                POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-               base::MakeUnique<base::StringValue>(kKeyword), nullptr);
+               base::MakeUnique<base::Value>(kKeyword), nullptr);
   policies.Set(key::kDefaultSearchProviderSearchURL, POLICY_LEVEL_MANDATORY,
                POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-               base::MakeUnique<base::StringValue>(kSearchURL), nullptr);
+               base::MakeUnique<base::Value>(kSearchURL), nullptr);
   policies.Set(key::kDefaultSearchProviderInstantURL, POLICY_LEVEL_MANDATORY,
                POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-               base::MakeUnique<base::StringValue>(kInstantURL), nullptr);
+               base::MakeUnique<base::Value>(kInstantURL), nullptr);
   std::unique_ptr<base::ListValue> alternate_urls(new base::ListValue);
   alternate_urls->AppendString(kAlternateURL0);
   alternate_urls->AppendString(kAlternateURL1);
@@ -1010,18 +1010,17 @@
                std::move(alternate_urls), nullptr);
   policies.Set(key::kDefaultSearchProviderSearchTermsReplacementKey,
                POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-               base::MakeUnique<base::StringValue>(kSearchTermsReplacementKey),
+               base::MakeUnique<base::Value>(kSearchTermsReplacementKey),
                nullptr);
   policies.Set(key::kDefaultSearchProviderImageURL, POLICY_LEVEL_MANDATORY,
                POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-               base::MakeUnique<base::StringValue>(kImageURL), nullptr);
+               base::MakeUnique<base::Value>(kImageURL), nullptr);
   policies.Set(key::kDefaultSearchProviderImageURLPostParams,
                POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-               base::MakeUnique<base::StringValue>(kImageURLPostParams),
-               nullptr);
+               base::MakeUnique<base::Value>(kImageURLPostParams), nullptr);
   policies.Set(key::kDefaultSearchProviderNewTabURL, POLICY_LEVEL_MANDATORY,
                POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-               base::MakeUnique<base::StringValue>(kNewTabURL), nullptr);
+               base::MakeUnique<base::Value>(kNewTabURL), nullptr);
   UpdateProviderPolicy(policies);
   default_search = service->GetDefaultSearchProvider();
   ASSERT_TRUE(default_search);
@@ -1452,11 +1451,10 @@
   base::ScopedTempDir forced_dir;
   ASSERT_TRUE(forced_dir.CreateUniqueTempDir());
   PolicyMap policies;
-  policies.Set(
-      key::kDownloadDirectory, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-      POLICY_SOURCE_CLOUD,
-      base::MakeUnique<base::StringValue>(forced_dir.GetPath().value()),
-      nullptr);
+  policies.Set(key::kDownloadDirectory, POLICY_LEVEL_MANDATORY,
+               POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
+               base::MakeUnique<base::Value>(forced_dir.GetPath().value()),
+               nullptr);
   UpdateProviderPolicy(policies);
   DownloadAndVerifyFile(browser(), forced_dir.GetPath(), file);
   // Verify that the first download location wasn't affected.
@@ -2077,7 +2075,7 @@
   PolicyMap policies;
   policies.Set(key::kHomepageLocation, POLICY_LEVEL_MANDATORY,
                POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-               base::MakeUnique<base::StringValue>(chrome::kChromeUICreditsURL),
+               base::MakeUnique<base::Value>(chrome::kChromeUICreditsURL),
                nullptr);
   UpdateProviderPolicy(policies);
   EXPECT_TRUE(chrome::ExecuteCommand(browser(), IDC_HOME));
@@ -2469,7 +2467,7 @@
   CheckURLIsBlocked(browser(), file_path2.c_str());
 
   // Replace the URLblacklist with disabling the file scheme.
-  blacklist.Remove(base::StringValue("file://*"), NULL);
+  blacklist.Remove(base::Value("file://*"), NULL);
   policies.Set(key::kURLBlacklist, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
                POLICY_SOURCE_CLOUD, blacklist.CreateDeepCopy(), nullptr);
   UpdateProviderPolicy(policies);
@@ -2477,8 +2475,7 @@
 
   PrefService* prefs = browser()->profile()->GetPrefs();
   const base::ListValue* list_url = prefs->GetList(policy_prefs::kUrlBlacklist);
-  EXPECT_EQ(list_url->Find(base::StringValue("file://*")),
-            list_url->end());
+  EXPECT_EQ(list_url->Find(base::Value("file://*")), list_url->end());
 
   base::ListValue disabledscheme;
   disabledscheme.AppendString("file");
@@ -2488,8 +2485,7 @@
   FlushBlacklistPolicy();
 
   list_url = prefs->GetList(policy_prefs::kUrlBlacklist);
-  EXPECT_NE(list_url->Find(base::StringValue("file://*")),
-            list_url->end());
+  EXPECT_NE(list_url->Find(base::Value("file://*")), list_url->end());
 
   // Whitelist one folder and blacklist an another just inside.
   base::ListValue whitelist;
@@ -3079,8 +3075,7 @@
                  base::MakeUnique<base::Value>(false), nullptr);
     policies.Set(key::kHomepageLocation, POLICY_LEVEL_MANDATORY,
                  POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-                 base::MakeUnique<base::StringValue>("http://chromium.org"),
-                 nullptr);
+                 base::MakeUnique<base::Value>("http://chromium.org"), nullptr);
     provider_.UpdateChromePolicy(policies);
   }
 };
@@ -3691,7 +3686,7 @@
     if (enable) {
       policies.Set(key::kWebRtcUdpPortRange, POLICY_LEVEL_MANDATORY,
                    POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-                   base::MakeUnique<base::StringValue>(kTestWebRtcUdpPortRange),
+                   base::MakeUnique<base::Value>(kTestWebRtcUdpPortRange),
                    nullptr);
     }
     provider_.UpdateChromePolicy(policies);
@@ -4013,7 +4008,7 @@
     PolicyMap policies;
     policies.Set(key::kVariationsRestrictParameter, POLICY_LEVEL_MANDATORY,
                  POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-                 base::MakeUnique<base::StringValue>("restricted"), nullptr);
+                 base::MakeUnique<base::Value>("restricted"), nullptr);
     provider_.UpdateChromePolicy(policies);
   }
 };
diff --git a/chrome/browser/prefs/chrome_pref_service_unittest.cc b/chrome/browser/prefs/chrome_pref_service_unittest.cc
index da2f3e4..1a181f4 100644
--- a/chrome/browser/prefs/chrome_pref_service_unittest.cc
+++ b/chrome/browser/prefs/chrome_pref_service_unittest.cc
@@ -59,14 +59,12 @@
     // Set some (WebKit) user preferences.
     sync_preferences::TestingPrefServiceSyncable* pref_services =
         profile()->GetTestingPrefService();
-    pref_services->SetUserPref(prefs::kDefaultCharset,
-                               new base::StringValue("utf8"));
+    pref_services->SetUserPref(prefs::kDefaultCharset, new base::Value("utf8"));
     pref_services->SetUserPref(prefs::kWebKitDefaultFontSize,
                                new base::Value(20));
     pref_services->SetUserPref(prefs::kWebKitTextAreasAreResizable,
                                new base::Value(false));
-    pref_services->SetUserPref("webkit.webprefs.foo",
-                               new base::StringValue("bar"));
+    pref_services->SetUserPref("webkit.webprefs.foo", new base::Value("bar"));
   }
 };
 
diff --git a/chrome/browser/prefs/profile_pref_store_manager_unittest.cc b/chrome/browser/prefs/profile_pref_store_manager_unittest.cc
index 49d3884..701c8fe8 100644
--- a/chrome/browser/prefs/profile_pref_store_manager_unittest.cc
+++ b/chrome/browser/prefs/profile_pref_store_manager_unittest.cc
@@ -198,14 +198,13 @@
     pref_store->AddObserver(&registry_verifier_);
     PersistentPrefStore::PrefReadError error = pref_store->ReadPrefs();
     EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NO_FILE, error);
-    pref_store->SetValue(kTrackedAtomic,
-                         base::MakeUnique<base::StringValue>(kFoobar),
+    pref_store->SetValue(kTrackedAtomic, base::MakeUnique<base::Value>(kFoobar),
                          WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
     pref_store->SetValue(kProtectedAtomic,
-                         base::MakeUnique<base::StringValue>(kHelloWorld),
+                         base::MakeUnique<base::Value>(kHelloWorld),
                          WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
     pref_store->SetValue(kUnprotectedPref,
-                         base::MakeUnique<base::StringValue>(kFoobar),
+                         base::MakeUnique<base::Value>(kFoobar),
                          WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
     pref_store->RemoveObserver(&registry_verifier_);
     pref_store->CommitPendingWrite();
@@ -321,8 +320,8 @@
 
 TEST_F(ProfilePrefStoreManagerTest, InitializePrefsFromMasterPrefs) {
   auto master_prefs = base::MakeUnique<base::DictionaryValue>();
-  master_prefs->Set(kTrackedAtomic, new base::StringValue(kFoobar));
-  master_prefs->Set(kProtectedAtomic, new base::StringValue(kHelloWorld));
+  master_prefs->Set(kTrackedAtomic, new base::Value(kFoobar));
+  master_prefs->Set(kProtectedAtomic, new base::Value(kHelloWorld));
   EXPECT_TRUE(
       manager_->InitializePrefsFromMasterPrefs(std::move(master_prefs)));
 
@@ -483,7 +482,7 @@
   // Trigger the logic that migrates it back to the unprotected preferences
   // file.
   pref_store_->SetValue(kProtectedAtomic,
-                        base::WrapUnique(new base::StringValue(kGoodbyeWorld)),
+                        base::WrapUnique(new base::Value(kGoodbyeWorld)),
                         WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
   LoadExistingPrefs();
   ExpectStringValueEquals(kProtectedAtomic, kGoodbyeWorld);
diff --git a/chrome/browser/prefs/proxy_policy_unittest.cc b/chrome/browser/prefs/proxy_policy_unittest.cc
index aadac72..8fdcaab 100644
--- a/chrome/browser/prefs/proxy_policy_unittest.cc
+++ b/chrome/browser/prefs/proxy_policy_unittest.cc
@@ -129,15 +129,15 @@
   command_line_.AppendSwitchASCII(switches::kProxyBypassList, "123");
   command_line_.AppendSwitchASCII(switches::kProxyServer, "789");
   std::unique_ptr<base::Value> mode_name(
-      new base::StringValue(ProxyPrefs::kFixedServersProxyModeName));
+      new base::Value(ProxyPrefs::kFixedServersProxyModeName));
   PolicyMap policy;
   policy.Set(key::kProxyMode, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
              POLICY_SOURCE_CLOUD, std::move(mode_name), nullptr);
   policy.Set(key::kProxyBypassList, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             POLICY_SOURCE_CLOUD, base::MakeUnique<base::StringValue>("abc"),
+             POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>("abc"),
              nullptr);
   policy.Set(key::kProxyServer, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             POLICY_SOURCE_CLOUD, base::MakeUnique<base::StringValue>("ghi"),
+             POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>("ghi"),
              nullptr);
   provider_.UpdateChromePolicy(policy);
 
@@ -166,7 +166,7 @@
   command_line_.AppendSwitchASCII(switches::kProxyBypassList, "123");
   command_line_.AppendSwitchASCII(switches::kProxyServer, "789");
   std::unique_ptr<base::Value> mode_name(
-      new base::StringValue(ProxyPrefs::kAutoDetectProxyModeName));
+      new base::Value(ProxyPrefs::kAutoDetectProxyModeName));
   PolicyMap policy;
   policy.Set(key::kProxyMode, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
              POLICY_SOURCE_CLOUD, std::move(mode_name), nullptr);
@@ -194,7 +194,7 @@
 TEST_F(ProxyPolicyTest, OverridesCommandLineNoProxy) {
   command_line_.AppendSwitch(switches::kNoProxyServer);
   std::unique_ptr<base::Value> mode_name(
-      new base::StringValue(ProxyPrefs::kAutoDetectProxyModeName));
+      new base::Value(ProxyPrefs::kAutoDetectProxyModeName));
   PolicyMap policy;
   policy.Set(key::kProxyMode, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
              POLICY_SOURCE_CLOUD, std::move(mode_name), nullptr);
@@ -218,7 +218,7 @@
 TEST_F(ProxyPolicyTest, OverridesCommandLineAutoDetect) {
   command_line_.AppendSwitch(switches::kProxyAutoDetect);
   std::unique_ptr<base::Value> mode_name(
-      new base::StringValue(ProxyPrefs::kDirectProxyModeName));
+      new base::Value(ProxyPrefs::kDirectProxyModeName));
   PolicyMap policy;
   policy.Set(key::kProxyMode, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
              POLICY_SOURCE_CLOUD, std::move(mode_name), nullptr);
diff --git a/chrome/browser/prefs/session_startup_pref.cc b/chrome/browser/prefs/session_startup_pref.cc
index 7bcf8d03..b7dd90f 100644
--- a/chrome/browser/prefs/session_startup_pref.cc
+++ b/chrome/browser/prefs/session_startup_pref.cc
@@ -90,7 +90,7 @@
     url_pref_list->Clear();
     for (size_t i = 0; i < pref.urls.size(); ++i) {
       url_pref_list->Set(static_cast<int>(i),
-                         new base::StringValue(pref.urls[i].spec()));
+                         new base::Value(pref.urls[i].spec()));
     }
   }
 }
diff --git a/chrome/browser/prefs/session_startup_pref_unittest.cc b/chrome/browser/prefs/session_startup_pref_unittest.cc
index 0f0470a7..ebe69c2b 100644
--- a/chrome/browser/prefs/session_startup_pref_unittest.cc
+++ b/chrome/browser/prefs/session_startup_pref_unittest.cc
@@ -27,8 +27,8 @@
 
 TEST_F(SessionStartupPrefTest, URLListIsFixedUp) {
   base::ListValue* url_pref_list = new base::ListValue;
-  url_pref_list->Set(0, new base::StringValue("google.com"));
-  url_pref_list->Set(1, new base::StringValue("chromium.org"));
+  url_pref_list->Set(0, new base::Value("google.com"));
+  url_pref_list->Set(1, new base::Value("chromium.org"));
   pref_service_->SetUserPref(prefs::kURLsToRestoreOnStartup, url_pref_list);
 
   SessionStartupPref result =
@@ -40,13 +40,13 @@
 
 TEST_F(SessionStartupPrefTest, URLListManagedOverridesUser) {
   base::ListValue* url_pref_list1 = new base::ListValue;
-  url_pref_list1->Set(0, new base::StringValue("chromium.org"));
+  url_pref_list1->Set(0, new base::Value("chromium.org"));
   pref_service_->SetUserPref(prefs::kURLsToRestoreOnStartup, url_pref_list1);
 
   base::ListValue* url_pref_list2 = new base::ListValue;
-  url_pref_list2->Set(0, new base::StringValue("chromium.org"));
-  url_pref_list2->Set(1, new base::StringValue("chromium.org"));
-  url_pref_list2->Set(2, new base::StringValue("chromium.org"));
+  url_pref_list2->Set(0, new base::Value("chromium.org"));
+  url_pref_list2->Set(1, new base::Value("chromium.org"));
+  url_pref_list2->Set(2, new base::Value("chromium.org"));
   pref_service_->SetManagedPref(prefs::kURLsToRestoreOnStartup,
                                 url_pref_list2);
 
diff --git a/chrome/browser/printing/cloud_print/cloud_print_proxy_service_unittest.cc b/chrome/browser/printing/cloud_print/cloud_print_proxy_service_unittest.cc
index a7f92ac..8636b75 100644
--- a/chrome/browser/printing/cloud_print/cloud_print_proxy_service_unittest.cc
+++ b/chrome/browser/printing/cloud_print/cloud_print_proxy_service_unittest.cc
@@ -246,7 +246,7 @@
       profile_.GetTestingPrefService();
   prefs->SetUserPref(
       prefs::kCloudPrintEmail,
-      new base::StringValue(MockServiceProcessControl::EnabledUserId()));
+      new base::Value(MockServiceProcessControl::EnabledUserId()));
 
   service.Initialize();
 
@@ -261,8 +261,7 @@
 
   sync_preferences::TestingPrefServiceSyncable* prefs =
       profile_.GetTestingPrefService();
-  prefs->SetUserPref(prefs::kCloudPrintEmail,
-                     new base::StringValue(std::string()));
+  prefs->SetUserPref(prefs::kCloudPrintEmail, new base::Value(std::string()));
 
   service.Initialize();
   service.RefreshStatusFromService();
@@ -279,8 +278,7 @@
 
   sync_preferences::TestingPrefServiceSyncable* prefs =
       profile_.GetTestingPrefService();
-  prefs->SetUserPref(prefs::kCloudPrintEmail,
-                     new base::StringValue(std::string()));
+  prefs->SetUserPref(prefs::kCloudPrintEmail, new base::Value(std::string()));
   prefs->SetManagedPref(prefs::kCloudPrintProxyEnabled, new base::Value(false));
 
   service.Initialize();
@@ -297,8 +295,7 @@
 
   sync_preferences::TestingPrefServiceSyncable* prefs =
       profile_.GetTestingPrefService();
-  prefs->SetUserPref(prefs::kCloudPrintEmail,
-                     new base::StringValue(std::string()));
+  prefs->SetUserPref(prefs::kCloudPrintEmail, new base::Value(std::string()));
   prefs->SetManagedPref(prefs::kCloudPrintProxyEnabled, new base::Value(false));
 
   service.Initialize();
@@ -316,7 +313,7 @@
       profile_.GetTestingPrefService();
   prefs->SetUserPref(
       prefs::kCloudPrintEmail,
-      new base::StringValue(MockServiceProcessControl::EnabledUserId()));
+      new base::Value(MockServiceProcessControl::EnabledUserId()));
 
   service.Initialize();
 
@@ -335,8 +332,7 @@
 
   sync_preferences::TestingPrefServiceSyncable* prefs =
       profile_.GetTestingPrefService();
-  prefs->SetUserPref(prefs::kCloudPrintEmail,
-                     new base::StringValue(std::string()));
+  prefs->SetUserPref(prefs::kCloudPrintEmail, new base::Value(std::string()));
 
   service.Initialize();
   service.RefreshStatusFromService();
@@ -359,8 +355,7 @@
 
   sync_preferences::TestingPrefServiceSyncable* prefs =
       profile_.GetTestingPrefService();
-  prefs->SetUserPref(prefs::kCloudPrintEmail,
-                     new base::StringValue(std::string()));
+  prefs->SetUserPref(prefs::kCloudPrintEmail, new base::Value(std::string()));
   prefs->SetManagedPref(prefs::kCloudPrintProxyEnabled, new base::Value(false));
 
   service.Initialize();
@@ -380,8 +375,7 @@
 
   sync_preferences::TestingPrefServiceSyncable* prefs =
       profile_.GetTestingPrefService();
-  prefs->SetUserPref(prefs::kCloudPrintEmail,
-                     new base::StringValue(std::string()));
+  prefs->SetUserPref(prefs::kCloudPrintEmail, new base::Value(std::string()));
   prefs->SetManagedPref(prefs::kCloudPrintProxyEnabled, new base::Value(false));
 
   service.Initialize();
@@ -401,7 +395,7 @@
       profile_.GetTestingPrefService();
   prefs->SetUserPref(
       prefs::kCloudPrintEmail,
-      new base::StringValue(MockServiceProcessControl::EnabledUserId()));
+      new base::Value(MockServiceProcessControl::EnabledUserId()));
 
   service.Initialize();
   EXPECT_EQ(std::string(), prefs->GetString(prefs::kCloudPrintEmail));
@@ -423,8 +417,7 @@
 
   sync_preferences::TestingPrefServiceSyncable* prefs =
       profile_.GetTestingPrefService();
-  prefs->SetUserPref(prefs::kCloudPrintEmail,
-                     new base::StringValue(std::string()));
+  prefs->SetUserPref(prefs::kCloudPrintEmail, new base::Value(std::string()));
   prefs->SetManagedPref(prefs::kCloudPrintProxyEnabled, new base::Value(false));
 
   service.Initialize();
diff --git a/chrome/browser/printing/print_preview_dialog_controller_browsertest.cc b/chrome/browser/printing/print_preview_dialog_controller_browsertest.cc
index 335becff..62c6a0a 100644
--- a/chrome/browser/printing/print_preview_dialog_controller_browsertest.cc
+++ b/chrome/browser/printing/print_preview_dialog_controller_browsertest.cc
@@ -266,6 +266,9 @@
   chrome::Reload(browser(), WindowOpenDisposition::CURRENT_TAB);
   content::WaitForLoadStop(
       browser()->tab_strip_model()->GetActiveWebContents());
+  // Load stop may occure right after the reload commits, and the dialog is
+  // destroyed in a task posted during commit. Make sure that task is executed.
+  base::RunLoop().RunUntilIdle();
   ASSERT_TRUE(dialog_destroyed_observer.dialog_destroyed());
 
   // Try printing again.
diff --git a/chrome/browser/profiles/profile_window_browsertest.cc b/chrome/browser/profiles/profile_window_browsertest.cc
index d1233ae5..012fb67 100644
--- a/chrome/browser/profiles/profile_window_browsertest.cc
+++ b/chrome/browser/profiles/profile_window_browsertest.cc
@@ -289,8 +289,8 @@
   run_loop.Run();
 
   ui_test_utils::NavigateToURL(browser(), GURL(url_to_test));
-  EXPECT_TRUE(RunJavascriptTest(
-      "testPodFocused", new base::StringValue(expected_path.AsUTF8Unsafe())));
+  EXPECT_TRUE(RunJavascriptTest("testPodFocused",
+                                new base::Value(expected_path.AsUTF8Unsafe())));
 }
 
 #endif  // !defined(OS_CHROMEOS) && !defined(OS_ANDROID)
diff --git a/chrome/browser/push_messaging/push_messaging_app_identifier.cc b/chrome/browser/push_messaging/push_messaging_app_identifier.cc
index fc2f52a..61f8c78 100644
--- a/chrome/browser/push_messaging/push_messaging_app_identifier.cc
+++ b/chrome/browser/push_messaging/push_messaging_app_identifier.cc
@@ -131,8 +131,8 @@
     Profile* profile,
     const GURL& origin,
     int64_t service_worker_registration_id) {
-  const base::StringValue pref_value =
-      base::StringValue(MakePrefValue(origin, service_worker_registration_id));
+  const base::Value pref_value =
+      base::Value(MakePrefValue(origin, service_worker_registration_id));
 
   const base::DictionaryValue* map =
       profile->GetPrefs()->GetDictionary(prefs::kPushMessagingAppIdentifierMap);
diff --git a/chrome/browser/renderer_host/render_process_host_chrome_browsertest.cc b/chrome/browser/renderer_host/render_process_host_chrome_browsertest.cc
index c9da53c..e4eac62b 100644
--- a/chrome/browser/renderer_host/render_process_host_chrome_browsertest.cc
+++ b/chrome/browser/renderer_host/render_process_host_chrome_browsertest.cc
@@ -525,21 +525,21 @@
 class WindowDestroyer : public content::WebContentsObserver {
  public:
   WindowDestroyer(content::WebContents* web_contents, TabStripModel* model)
-      : content::WebContentsObserver(web_contents), tab_strip_model_(model) {}
+      : content::WebContentsObserver(web_contents),
+        tab_strip_model_(model),
+        browser_closed_observer_(chrome::NOTIFICATION_BROWSER_CLOSED,
+                                 content::NotificationService::AllSources()) {}
+
+  // Wait for the browser window to be destroyed.
+  void Wait() { browser_closed_observer_.Wait(); }
 
   void RenderProcessGone(base::TerminationStatus status) override {
-    // Wait for the window to be destroyed, which will ensure all other
-    // RenderViewHost objects are deleted before we return and proceed with
-    // the next iteration of notifications.
-    content::WindowedNotificationObserver observer(
-        chrome::NOTIFICATION_BROWSER_CLOSED,
-        content::NotificationService::AllSources());
     tab_strip_model_->CloseAllTabs();
-    observer.Wait();
   }
 
  private:
   TabStripModel* tab_strip_model_;
+  content::WindowedNotificationObserver browser_closed_observer_;
 
   DISALLOW_COPY_AND_ASSIGN(WindowDestroyer);
 };
@@ -572,16 +572,12 @@
   // Create an object that will close the window on a process crash.
   WindowDestroyer destroyer(wc1, browser()->tab_strip_model());
 
-  content::WindowedNotificationObserver observer(
-      chrome::NOTIFICATION_BROWSER_CLOSED,
-      content::NotificationService::AllSources());
-
   // Kill the renderer process, simulating a crash. This should the ProcessDied
   // method to be called. Alternatively, RenderProcessHost::OnChannelError can
   // be called to directly force a call to ProcessDied.
   wc1->GetRenderProcessHost()->Shutdown(-1, true);
 
-  observer.Wait();
+  destroyer.Wait();
 }
 
 // Sets up the browser in order to start the tests with two tabs open: one
diff --git a/chrome/browser/resources/options/options.js b/chrome/browser/resources/options/options.js
index 821d7ea..cdfb732 100644
--- a/chrome/browser/resources/options/options.js
+++ b/chrome/browser/resources/options/options.js
@@ -290,6 +290,9 @@
   window.setTimeout(function() {
     document.documentElement.classList.remove('loading');
     chrome.send('onFinishedLoadingOptions');
+    chrome.send(
+        'metricsHandler:recordTime',
+        ['Settings.TimeUntilInteractive', window.performance.now()]);
   }, 0);
 }
 
diff --git a/chrome/browser/resources/settings/appearance_page/appearance_page.html b/chrome/browser/resources/settings/appearance_page/appearance_page.html
index de37163..ac2a024 100644
--- a/chrome/browser/resources/settings/appearance_page/appearance_page.html
+++ b/chrome/browser/resources/settings/appearance_page/appearance_page.html
@@ -111,11 +111,11 @@
               hidden="[[!pageVisibility.homeButton]]">
             <settings-radio-group pref="{{prefs.homepage_is_newtabpage}}">
               <controlled-radio-button class="list-item" name="true"
-                  pref="[[prefs.homepage_is_newtabpage]]">
+                  pref="[[prefs.homepage_is_newtabpage]]" ignore-extensions>
                 $i18n{homePageNtp}
               </controlled-radio-button>
               <controlled-radio-button class="list-item" name="false"
-                  pref="[[prefs.homepage_is_newtabpage]]">
+                  pref="[[prefs.homepage_is_newtabpage]]" ignore-extensions>
                 $i18n{other}
                 <!-- TODO(dbeam): this can show double indicators when both
                      homepage and whether to use the NTP as the homepage are
@@ -123,7 +123,7 @@
                 <settings-input no-label-float pref="{{prefs.homepage}}"
                     label="$i18n{exampleDotCom}"
                     can-tab="[[!prefs.homepage_is_newtabpage.value]]"
-                    stop-keyboard-event-propagation>
+                    stop-keyboard-event-propagation ignore-extensions>
                 </settings-input>
               </controlled-radio-button>
               <template is="dom-if" if="[[prefs.homepage.extensionId]]">
diff --git a/chrome/browser/resources/settings/controls/settings_boolean_control_behavior.js b/chrome/browser/resources/settings/controls/settings_boolean_control_behavior.js
index bae9955..ffb43f0 100644
--- a/chrome/browser/resources/settings/controls/settings_boolean_control_behavior.js
+++ b/chrome/browser/resources/settings/controls/settings_boolean_control_behavior.js
@@ -126,7 +126,7 @@
    * @private
    */
   controlDisabled_: function() {
-    return this.disabled || this.isPrefPolicyControlled();
+    return this.disabled || this.isPrefEnforced();
   },
 };
 
diff --git a/chrome/browser/resources/settings/controls/settings_input.js b/chrome/browser/resources/settings/controls/settings_input.js
index 0bee823..2b39de1 100644
--- a/chrome/browser/resources/settings/controls/settings_input.js
+++ b/chrome/browser/resources/settings/controls/settings_input.js
@@ -123,6 +123,6 @@
    * @private
    */
   isDisabled_: function(disabled) {
-    return disabled || this.isPrefPolicyControlled();
+    return disabled || this.isPrefEnforced();
   },
 });
diff --git a/chrome/browser/resources/settings/internet_page/network_proxy.html b/chrome/browser/resources/settings/internet_page/network_proxy.html
index f2c2b8d9..9f251db 100644
--- a/chrome/browser/resources/settings/internet_page/network_proxy.html
+++ b/chrome/browser/resources/settings/internet_page/network_proxy.html
@@ -59,7 +59,8 @@
       <div class="settings-box continuation single-column">
         <div class="layout horizontal center">
           <cr-policy-network-indicator
-              property="[[networkProperties.ProxySettings.Type]]">
+              property="[[networkProperties.ProxySettings.Type]]"
+              ignore-extensions>
           </cr-policy-network-indicator>
           <div>$i18n{networkProxyEnforcedPolicy}</div>
         </div>
diff --git a/chrome/browser/resources/settings/on_startup_page/on_startup_page.html b/chrome/browser/resources/settings/on_startup_page/on_startup_page.html
index 940c053..1d1642e 100644
--- a/chrome/browser/resources/settings/on_startup_page/on_startup_page.html
+++ b/chrome/browser/resources/settings/on_startup_page/on_startup_page.html
@@ -14,7 +14,7 @@
       <settings-radio-group id="onStartupRadioGroup"
           pref="{{prefs.session.restore_on_startup}}">
         <controlled-radio-button name="[[prefValues_.OPEN_NEW_TAB]]"
-            pref="[[prefs.session.restore_on_startup]]">
+            pref="[[prefs.session.restore_on_startup]]" ignore-extensions>
           $i18n{onStartupOpenNewTab}
         </controlled-radio-button>
         <template is="dom-if" if="[[showIndicator_(
diff --git a/chrome/browser/resources/settings/settings.html b/chrome/browser/resources/settings/settings.html
index 191d3144..dcd77ad 100644
--- a/chrome/browser/resources/settings/settings.html
+++ b/chrome/browser/resources/settings/settings.html
@@ -9,7 +9,6 @@
   <link rel="import" href="chrome://resources/html/polymer.html">
   <link rel="import" href="settings_ui/settings_ui.html">
   <link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css">
-  <link rel="import" href="chrome://resources/html/i18n_template.html">
   <!-- Do not add any <link rel="..."> elements below here. Imports outside of
        <head> are disallowed by HTML5 and cause undefined behavior that
        confuses Polymer's lifecycle methods: crbug.com/638074. -->
diff --git a/chrome/browser/resources/settings/settings_ui/settings_ui.js b/chrome/browser/resources/settings/settings_ui/settings_ui.js
index e6fbee50..e3c3ca1a 100644
--- a/chrome/browser/resources/settings/settings_ui/settings_ui.js
+++ b/chrome/browser/resources/settings/settings_ui/settings_ui.js
@@ -90,6 +90,8 @@
     }.bind(this));
 
     CrPolicyStrings = {
+      controlledSettingExtension:
+          loadTimeData.getString('controlledSettingExtension'),
       controlledSettingPolicy:
           loadTimeData.getString('controlledSettingPolicy'),
       controlledSettingRecommendedMatches:
@@ -160,6 +162,11 @@
 
   /** @override */
   attached: function() {
+    setTimeout(function() {
+      chrome.send(
+          'metricsHandler:recordTime',
+          ['Settings.TimeUntilInteractive', window.performance.now()]);
+    });
     // Preload bold Roboto so it doesn't load and flicker the first time used.
     document.fonts.load('bold 12px Roboto');
     settings.setGlobalScrollTarget(this.$.headerPanel.scroller);
diff --git a/chrome/browser/resources/settings/system_page/system_page.html b/chrome/browser/resources/settings/system_page/system_page.html
index 6cd6aa2..d1d8229 100644
--- a/chrome/browser/resources/settings/system_page/system_page.html
+++ b/chrome/browser/resources/settings/system_page/system_page.html
@@ -33,7 +33,7 @@
     </div>
     <div class="settings-box">
       <controlled-button class="primary-button" pref="[[prefs.proxy]]"
-          on-tap="onChangeProxySettingsTap_">
+          on-tap="onChangeProxySettingsTap_" ignore-extensions>
         $i18n{changeProxySettings}
       </controlled-button>
     </div>
diff --git a/chrome/browser/resources/webapks/about_webapks.css b/chrome/browser/resources/webapks/about_webapks.css
index 11ceac58..a6cbc37 100644
--- a/chrome/browser/resources/webapks/about_webapks.css
+++ b/chrome/browser/resources/webapks/about_webapks.css
@@ -46,3 +46,9 @@
   text-align: start;
   white-space: nowrap;
 }
+
+.app-property-value {
+  font-weight: normal;
+  text-align: start;
+  white-space: nowrap;
+}
diff --git a/chrome/browser/resources/webapks/about_webapks.js b/chrome/browser/resources/webapks/about_webapks.js
index ae929d6..9d5fb8f 100644
--- a/chrome/browser/resources/webapks/about_webapks.js
+++ b/chrome/browser/resources/webapks/about_webapks.js
@@ -4,10 +4,19 @@
 
 /**
  * @typedef {{
+ *   name: string,
  *   shortName: string,
  *   packageName: string,
  *   shellApkVersion: number,
- *   versionCode: number
+ *   versionCode: number,
+ *   uri: string,
+ *   scope: string,
+ *   manifestUrl: string,
+ *   manifestStartUrl: string,
+ *   displayMode: string,
+ *   orientation: string,
+ *   themeColor: string,
+ *   backgroundColor: string,
  * }}
  */
 var WebApkInfo;
@@ -17,11 +26,12 @@
  * |className| class.
  *
  * @param {string} text Text to be shown in the span.
+ * @param {string} type Type of element to be added such as 'div'.
  * @param {string} className Class to be assigned to the new element.
  * @return {Element} The created element.
  */
-function createSpanWithTextAndClass(text, className) {
-  var element = createElementWithClassName('span', className);
+function createElementWithTextAndClass(text, type, className) {
+  var element = createElementWithClassName(type, className);
   element.textContent = text;
   return element;
 }
@@ -41,29 +51,47 @@
 }
 
 /**
+ * @param {HTMLElement} webApkList List of elements which contain WebAPK
+ * attributes.
+ * @param {string} label Text that identifies the new element.
+ * @param {string} value Text to set in the new element.
+ */
+function addWebApkField(webApkList, label, value) {
+  var divElement =
+      createElementWithTextAndClass(label, 'div', 'app-property-label');
+  divElement.appendChild(
+      createElementWithTextAndClass(value, 'span', 'app-property-value'));
+  webApkList.appendChild(divElement);
+}
+
+/**
  * Adds a new entry to the page with the information of a WebAPK.
  *
  * @param {WebApkInfo} webApkInfo Information about an installed WebAPK.
  */
 function addWebApk(webApkInfo) {
-  var webApkList = $('webapk-list');
+  /** @type {HTMLElement} */ var webApkList = $('webapk-list');
 
   webApkList.appendChild(
-      createSpanWithTextAndClass(webApkInfo.shortName, 'app-name'));
+      createElementWithTextAndClass(webApkInfo.name, 'span', 'app-name'));
 
-  webApkList.appendChild(
-      createSpanWithTextAndClass('Package name: ', 'app-property-label'));
-  webApkList.appendChild(document.createTextNode(webApkInfo.packageName));
+  webApkList.appendChild(createElementWithTextAndClass(
+      'Short name: ', 'span', 'app-property-label'));
+  webApkList.appendChild(document.createTextNode(webApkInfo.shortName));
 
-  webApkList.appendChild(document.createElement('br'));
-  webApkList.appendChild(createSpanWithTextAndClass(
-      'Shell APK version: ', 'app-property-label'));
-  webApkList.appendChild(document.createTextNode(webApkInfo.shellApkVersion));
-
-  webApkList.appendChild(document.createElement('br'));
-  webApkList.appendChild(
-      createSpanWithTextAndClass('Version code: ', 'app-property-label'));
-  webApkList.appendChild(document.createTextNode(webApkInfo.versionCode));
+  addWebApkField(webApkList, 'Package name: ', webApkInfo.packageName);
+  addWebApkField(
+      webApkList, 'Shell APK version: ', "" + webApkInfo.shellApkVersion);
+  addWebApkField(webApkList, 'Version code: ', "" + webApkInfo.versionCode);
+  addWebApkField(webApkList, 'URI: ', webApkInfo.uri);
+  addWebApkField(webApkList, 'Scope: ', webApkInfo.scope);
+  addWebApkField(webApkList, 'Manifest URL: ', webApkInfo.manifestUrl);
+  addWebApkField(
+      webApkList, 'Manifest Start URL: ', webApkInfo.manifestStartUrl);
+  addWebApkField(webApkList, 'Display Mode: ', webApkInfo.displayMode);
+  addWebApkField(webApkList, 'Orientation: ', webApkInfo.orientation);
+  addWebApkField(webApkList, 'Theme color: ', webApkInfo.themeColor);
+  addWebApkField(webApkList, 'Background color: ', webApkInfo.backgroundColor);
 }
 
 document.addEventListener('DOMContentLoaded', function() {
diff --git a/chrome/browser/safe_browsing/incident_reporting/extension_data_collection_unittest.cc b/chrome/browser/safe_browsing/incident_reporting/extension_data_collection_unittest.cc
index c78892b..c5141eb 100644
--- a/chrome/browser/safe_browsing/incident_reporting/extension_data_collection_unittest.cc
+++ b/chrome/browser/safe_browsing/incident_reporting/extension_data_collection_unittest.cc
@@ -99,8 +99,8 @@
   extension_service_->AddExtension(extension.get());
 
   extension_prefs_->UpdateExtensionPref(
-      extension_id, "install_time", new base::StringValue(base::Int64ToString(
-                                        install_time.ToInternalValue())));
+      extension_id, "install_time",
+      new base::Value(base::Int64ToString(install_time.ToInternalValue())));
   extension_prefs_->UpdateExtensionPref(extension_id, "state",
                                         new base::Value(state_value));
 }
diff --git a/chrome/browser/safe_browsing/incident_reporting/preference_validation_delegate_unittest.cc b/chrome/browser/safe_browsing/incident_reporting/preference_validation_delegate_unittest.cc
index ec2c18f..7eb3d96 100644
--- a/chrome/browser/safe_browsing/incident_reporting/preference_validation_delegate_unittest.cc
+++ b/chrome/browser/safe_browsing/incident_reporting/preference_validation_delegate_unittest.cc
@@ -139,7 +139,7 @@
       case Value::Type::DOUBLE:
         return std::unique_ptr<Value>(new base::Value(0.47));
       case Value::Type::STRING:
-        return std::unique_ptr<Value>(new base::StringValue("i have a spleen"));
+        return std::unique_ptr<Value>(new base::Value("i have a spleen"));
       case Value::Type::DICTIONARY: {
         std::unique_ptr<base::DictionaryValue> value(
             new base::DictionaryValue());
diff --git a/chrome/browser/ssl/chrome_expect_ct_reporter.cc b/chrome/browser/ssl/chrome_expect_ct_reporter.cc
index d10a652..6cfaf54f 100644
--- a/chrome/browser/ssl/chrome_expect_ct_reporter.cc
+++ b/chrome/browser/ssl/chrome_expect_ct_reporter.cc
@@ -39,7 +39,7 @@
   std::vector<std::string> pem_encoded_chain;
   cert_chain->GetPEMEncodedChain(&pem_encoded_chain);
   for (const std::string& cert : pem_encoded_chain)
-    result->Append(base::MakeUnique<base::StringValue>(cert));
+    result->Append(base::MakeUnique<base::Value>(cert));
 
   return result;
 }
diff --git a/chrome/browser/supervised_user/legacy/supervised_user_shared_settings_service_unittest.cc b/chrome/browser/supervised_user/legacy/supervised_user_shared_settings_service_unittest.cc
index cfed6f0..2c6b4b1a 100644
--- a/chrome/browser/supervised_user/legacy/supervised_user_shared_settings_service_unittest.cc
+++ b/chrome/browser/supervised_user/legacy/supervised_user_shared_settings_service_unittest.cc
@@ -22,7 +22,6 @@
 #include "testing/gtest/include/gtest/gtest.h"
 
 using base::DictionaryValue;
-using base::StringValue;
 using base::Value;
 using sync_pb::ManagedUserSharedSettingSpecifics;
 using syncer::SUPERVISED_USER_SHARED_SETTINGS;
@@ -160,9 +159,9 @@
   const char kIdB[] = "bbbbbb";
   const char kIdC[] = "cccccc";
 
-  StringValue name("Jack");
+  Value name("Jack");
   Value age(8);
-  StringValue bar("bar");
+  Value bar("bar");
   settings_service_.SetValue(kIdA, "name", name);
   ASSERT_EQ(1u, sync_processor_->changes().size());
   VerifySyncChangesAndClear();
@@ -202,15 +201,15 @@
   const char kIdC[] = "cccccc";
 
   Value age(8);
-  StringValue bar("bar");
-  settings_service_.SetValue(kIdA, "name", StringValue("Jack"));
+  Value bar("bar");
+  settings_service_.SetValue(kIdA, "name", Value("Jack"));
   settings_service_.SetValue(kIdA, "age", age);
   settings_service_.SetValue(kIdB, "foo", bar);
 
   settings_service_.StopSyncing(SUPERVISED_USER_SHARED_SETTINGS);
 
-  StringValue name("Jill");
-  StringValue blurp("blurp");
+  Value name("Jill");
+  Value blurp("blurp");
   SyncDataList sync_data;
   sync_data.push_back(
       SupervisedUserSharedSettingsService::CreateSyncDataForSetting(
@@ -252,13 +251,13 @@
   const char kIdC[] = "cccccc";
 
   Value age(8);
-  StringValue bar("bar");
-  settings_service_.SetValue(kIdA, "name", StringValue("Jack"));
+  Value bar("bar");
+  settings_service_.SetValue(kIdA, "name", Value("Jack"));
   settings_service_.SetValue(kIdA, "age", age);
   settings_service_.SetValue(kIdB, "foo", bar);
 
-  StringValue name("Jill");
-  StringValue blurp("blurp");
+  Value name("Jill");
+  Value blurp("blurp");
   SyncChangeList changes;
   changes.push_back(
       SyncChange(FROM_HERE,
diff --git a/chrome/browser/supervised_user/legacy/supervised_user_shared_settings_update_unittest.cc b/chrome/browser/supervised_user/legacy/supervised_user_shared_settings_update_unittest.cc
index 83173f6..f8045716 100644
--- a/chrome/browser/supervised_user/legacy/supervised_user_shared_settings_update_unittest.cc
+++ b/chrome/browser/supervised_user/legacy/supervised_user_shared_settings_update_unittest.cc
@@ -32,15 +32,14 @@
 TEST_F(SupervisedUserSharedSettingsUpdateTest, Success) {
   SupervisedUserSharedSettingsUpdate update(
       &service_, "abcdef", "name",
-      std::unique_ptr<base::Value>(new base::StringValue("Hans Moleman")),
+      std::unique_ptr<base::Value>(new base::Value("Hans Moleman")),
       base::Bind(&SupervisedUserSharedSettingsUpdateTest::OnSettingUpdated,
                  base::Unretained(this)));
   syncer::SyncChangeList changes;
   changes.push_back(syncer::SyncChange(
-      FROM_HERE,
-      syncer::SyncChange::ACTION_UPDATE,
+      FROM_HERE, syncer::SyncChange::ACTION_UPDATE,
       SupervisedUserSharedSettingsService::CreateSyncDataForSetting(
-          "abcdef", "name", base::StringValue("Hans Moleman"), true)));
+          "abcdef", "name", base::Value("Hans Moleman"), true)));
   syncer::SyncError error = service_.ProcessSyncChanges(FROM_HERE, changes);
   EXPECT_FALSE(error.IsSet()) << error.ToString();
   ASSERT_TRUE(result_);
@@ -50,20 +49,16 @@
 TEST_F(SupervisedUserSharedSettingsUpdateTest, Failure) {
   SupervisedUserSharedSettingsUpdate update(
       &service_, "abcdef", "name",
-      std::unique_ptr<base::Value>(new base::StringValue("Hans Moleman")),
+      std::unique_ptr<base::Value>(new base::Value("Hans Moleman")),
       base::Bind(&SupervisedUserSharedSettingsUpdateTest::OnSettingUpdated,
                  base::Unretained(this)));
 
   // Syncing down a different change will cause the update to fail.
   syncer::SyncChangeList changes;
   changes.push_back(syncer::SyncChange(
-      FROM_HERE,
-      syncer::SyncChange::ACTION_UPDATE,
+      FROM_HERE, syncer::SyncChange::ACTION_UPDATE,
       SupervisedUserSharedSettingsService::CreateSyncDataForSetting(
-          "abcdef",
-          "name",
-          base::StringValue("Barney Gumble"),
-          true)));
+          "abcdef", "name", base::Value("Barney Gumble"), true)));
   syncer::SyncError error = service_.ProcessSyncChanges(FROM_HERE, changes);
   EXPECT_FALSE(error.IsSet()) << error.ToString();
   ASSERT_TRUE(result_);
@@ -74,7 +69,7 @@
   {
     SupervisedUserSharedSettingsUpdate update(
         &service_, "abcdef", "name",
-        std::unique_ptr<base::Value>(new base::StringValue("Hans Moleman")),
+        std::unique_ptr<base::Value>(new base::Value("Hans Moleman")),
         base::Bind(&SupervisedUserSharedSettingsUpdateTest::OnSettingUpdated,
                    base::Unretained(this)));
     ASSERT_FALSE(result_);
diff --git a/chrome/browser/supervised_user/supervised_user_service.cc b/chrome/browser/supervised_user/supervised_user_service.cc
index 2f7f904..0f67367 100644
--- a/chrome/browser/supervised_user/supervised_user_service.cc
+++ b/chrome/browser/supervised_user/supervised_user_service.cc
@@ -1180,7 +1180,7 @@
     std::string key = SupervisedUserSettingsService::MakeSplitSettingKey(
         supervised_users::kApprovedExtensions, id);
     std::unique_ptr<base::Value> version_value(
-        new base::StringValue(version.GetString()));
+        new base::Value(version.GetString()));
     GetSettingsService()->UpdateSetting(key, std::move(version_value));
   }
   // Upon extension update, the approved version may (or may not) match the
diff --git a/chrome/browser/supervised_user/supervised_user_service_browsertest.cc b/chrome/browser/supervised_user/supervised_user_service_browsertest.cc
index a1b4e31..1b7ac01 100644
--- a/chrome/browser/supervised_user/supervised_user_service_browsertest.cc
+++ b/chrome/browser/supervised_user/supervised_user_service_browsertest.cc
@@ -131,7 +131,7 @@
   std::string name = "Supervised User Test Name";
   settings->SetLocalSetting(
       supervised_users::kUserName,
-      std::unique_ptr<base::Value>(new base::StringValue(name)));
+      std::unique_ptr<base::Value>(new base::Value(name)));
   EXPECT_FALSE(prefs->IsUserModifiablePreference(prefs::kProfileName));
   EXPECT_EQ(name, prefs->GetString(prefs::kProfileName));
 
@@ -145,7 +145,7 @@
   std::string new_name = "New Supervised User Test Name";
   settings->SetLocalSetting(
       supervised_users::kUserName,
-      std::unique_ptr<base::Value>(new base::StringValue(new_name)));
+      std::unique_ptr<base::Value>(new base::Value(new_name)));
   EXPECT_EQ(new_name, prefs->GetString(prefs::kProfileName));
   EXPECT_EQ(new_name, base::UTF16ToUTF8(entry->GetName()));
 
diff --git a/chrome/browser/supervised_user/supervised_user_settings_service_unittest.cc b/chrome/browser/supervised_user/supervised_user_settings_service_unittest.cc
index dc790a7f3..483e1a61 100644
--- a/chrome/browser/supervised_user/supervised_user_settings_service_unittest.cc
+++ b/chrome/browser/supervised_user/supervised_user_settings_service_unittest.cc
@@ -85,14 +85,13 @@
     split_items_.SetStringWithoutPathExpansion(key, value);
     settings_service_.UploadItem(
         SupervisedUserSettingsService::MakeSplitSettingKey(kSplitItemName, key),
-        std::unique_ptr<base::Value>(new base::StringValue(value)));
+        std::unique_ptr<base::Value>(new base::Value(value)));
   }
 
   void UploadAtomicItem(const std::string& value) {
-    atomic_setting_value_.reset(new base::StringValue(value));
+    atomic_setting_value_.reset(new base::Value(value));
     settings_service_.UploadItem(
-        kAtomicItemName,
-        std::unique_ptr<base::Value>(new base::StringValue(value)));
+        kAtomicItemName, std::unique_ptr<base::Value>(new base::Value(value)));
   }
 
   void VerifySyncDataItem(syncer::SyncData sync_data) {
@@ -158,7 +157,7 @@
   settings_.reset();
   syncer::SyncData data =
       SupervisedUserSettingsService::CreateSyncDataForSetting(
-          kSettingsName, base::StringValue(kSettingsValue));
+          kSettingsName, base::Value(kSettingsValue));
   syncer::SyncChangeList change_list;
   change_list.push_back(
       syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_ADD, data));
@@ -222,7 +221,7 @@
     syncer::SyncDataList sync_data;
     // Adding 1 Atomic entry.
     sync_data.push_back(SupervisedUserSettingsService::CreateSyncDataForSetting(
-        kSettingsName, base::StringValue(kSettingsValue)));
+        kSettingsName, base::Value(kSettingsValue)));
     // Adding 2 SplitSettings from dictionary.
     base::DictionaryValue dict;
     dict.SetString("foo", "bar");
@@ -281,7 +280,7 @@
   settings_.reset();
   settings_service_.SetLocalSetting(
       kSettingsName,
-      std::unique_ptr<base::Value>(new base::StringValue(kSettingsValue)));
+      std::unique_ptr<base::Value>(new base::Value(kSettingsValue)));
   ASSERT_TRUE(settings_);
   ASSERT_TRUE(settings_->GetWithoutPathExpansion(kSettingsName, &value));
   std::string string_value;
diff --git a/chrome/browser/task_profiler/task_profiler_data_serializer.cc b/chrome/browser/task_profiler/task_profiler_data_serializer.cc
index 6f4b52e..ffc07fc 100644
--- a/chrome/browser/task_profiler/task_profiler_data_serializer.cc
+++ b/chrome/browser/task_profiler/task_profiler_data_serializer.cc
@@ -52,7 +52,7 @@
   dictionary->Set(prefix + "_location", location_value.release());
 
   dictionary->Set(prefix + "_thread",
-                  new base::StringValue(birth.sanitized_thread_name));
+                  new base::Value(birth.sanitized_thread_name));
 }
 
 // Re-serializes the |death_data| into |dictionary|.
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index 08540e8d..540431c1 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -239,6 +239,8 @@
     "webui/chromeos/login/auto_enrollment_check_screen_handler.h",
     "webui/chromeos/login/base_screen_handler.cc",
     "webui/chromeos/login/base_screen_handler.h",
+    "webui/chromeos/login/base_webui_handler.cc",
+    "webui/chromeos/login/base_webui_handler.h",
     "webui/chromeos/login/controller_pairing_screen_handler.cc",
     "webui/chromeos/login/controller_pairing_screen_handler.h",
     "webui/chromeos/login/core_oobe_handler.cc",
diff --git a/chrome/browser/ui/app_list/extension_app_model_builder_unittest.cc b/chrome/browser/ui/app_list/extension_app_model_builder_unittest.cc
index d21cfebd5..968f669 100644
--- a/chrome/browser/ui/app_list/extension_app_model_builder_unittest.cc
+++ b/chrome/browser/ui/app_list/extension_app_model_builder_unittest.cc
@@ -271,10 +271,8 @@
   // Creates a corrupted ordinal case.
   extensions::ExtensionScopedPrefs* scoped_prefs =
       extensions::ExtensionPrefs::Get(profile_.get());
-  scoped_prefs->UpdateExtensionPref(
-      kHostedAppId,
-      "page_ordinal",
-      new base::StringValue("a corrupted ordinal"));
+  scoped_prefs->UpdateExtensionPref(kHostedAppId, "page_ordinal",
+                                    new base::Value("a corrupted ordinal"));
 
   // This should not assert or crash.
   CreateBuilder();
diff --git a/chrome/browser/ui/app_list/start_page_service.cc b/chrome/browser/ui/app_list/start_page_service.cc
index f75493a..db48a06 100644
--- a/chrome/browser/ui/app_list/start_page_service.cc
+++ b/chrome/browser/ui/app_list/start_page_service.cc
@@ -676,8 +676,7 @@
     if (contents_ && contents_->GetWebUI()) {
       contents_->GetWebUI()->CallJavascriptFunctionUnsafe(
           "appList.startPage.onAppListDoodleUpdated", *doodle_json,
-          base::StringValue(
-              UIThreadSearchTermsData(profile_).GoogleBaseURLValue()));
+          base::Value(UIThreadSearchTermsData(profile_).GoogleBaseURLValue()));
     }
   }
 
diff --git a/chrome/browser/ui/login/login_handler_browsertest.cc b/chrome/browser/ui/login/login_handler_browsertest.cc
index d3e1ca5..63cd691 100644
--- a/chrome/browser/ui/login/login_handler_browsertest.cc
+++ b/chrome/browser/ui/login/login_handler_browsertest.cc
@@ -98,6 +98,7 @@
 
 const char kMultiRealmTestPage[] = "/login/multi_realm.html";
 const int  kMultiRealmTestRealmCount = 2;
+const int kMultiRealmTestAuthRequestsCount = 4;
 
 const char kSingleRealmTestPage[] = "/login/single_realm.html";
 
@@ -460,104 +461,102 @@
 // Test handling of resources that require authentication even though
 // the page they are included on doesn't.  In this case we should only
 // present the minimal number of prompts necessary for successfully
-// displaying the page.  First we check whether cancelling works as
-// expected.
-IN_PROC_BROWSER_TEST_F(LoginPromptBrowserTest, MultipleRealmCancellation) {
+// displaying the page.
+class MultiRealmLoginPromptBrowserTest : public LoginPromptBrowserTest {
+ public:
+  void TearDownOnMainThread() override {
+    login_prompt_observer_.UnregisterAll();
+    LoginPromptBrowserTest::TearDownOnMainThread();
+  }
+
+  // Load the multi-realm test page, waits for LoginHandlers to be created, then
+  // calls |for_each_realm_func| once for each authentication realm, passing a
+  // LoginHandler for the realm as an argument. The page should stop loading
+  // after that.
+  template <class F>
+  void RunTest(const F& for_each_realm_func);
+
+  NavigationController* GetNavigationController() {
+    return &browser()
+                ->tab_strip_model()
+                ->GetActiveWebContents()
+                ->GetController();
+  }
+
+  LoginPromptBrowserTestObserver* login_prompt_observer() {
+    return &login_prompt_observer_;
+  }
+
+ private:
+  LoginPromptBrowserTestObserver login_prompt_observer_;
+};
+
+template <class F>
+void MultiRealmLoginPromptBrowserTest::RunTest(const F& for_each_realm_func) {
   ASSERT_TRUE(embedded_test_server()->Start());
   GURL test_page = embedded_test_server()->GetURL(kMultiRealmTestPage);
 
-  content::WebContents* contents =
-      browser()->tab_strip_model()->GetActiveWebContents();
-  NavigationController* controller = &contents->GetController();
-  LoginPromptBrowserTestObserver observer;
+  NavigationController* controller = GetNavigationController();
 
-  observer.Register(content::Source<NavigationController>(controller));
+  login_prompt_observer_.Register(
+      content::Source<NavigationController>(controller));
 
   WindowedLoadStopObserver load_stop_waiter(controller, 1);
 
-  {
-    WindowedAuthNeededObserver auth_needed_waiter(controller);
-    browser()->OpenURL(OpenURLParams(test_page, Referrer(),
-                                     WindowOpenDisposition::CURRENT_TAB,
-                                     ui::PAGE_TRANSITION_TYPED, false));
-    auth_needed_waiter.Wait();
-  }
+  browser()->OpenURL(OpenURLParams(test_page, Referrer(),
+                                   WindowOpenDisposition::CURRENT_TAB,
+                                   ui::PAGE_TRANSITION_TYPED, false));
 
-  int n_handlers = 0;
+  // Need to have LoginHandlers created for all requests that need
+  // authentication.
+  while (login_prompt_observer_.handlers().size() <
+         kMultiRealmTestAuthRequestsCount)
+    WindowedAuthNeededObserver(controller).Wait();
 
-  while (n_handlers < kMultiRealmTestRealmCount) {
-    WindowedAuthNeededObserver auth_needed_waiter(controller);
+  // Now confirm or cancel auth once per realm.
+  std::set<std::string> seen_realms;
+  for (int i = 0; i < kMultiRealmTestRealmCount; ++i) {
+    auto it = std::find_if(
+        login_prompt_observer_.handlers().begin(),
+        login_prompt_observer_.handlers().end(),
+        [&seen_realms](LoginHandler* handler) {
+          return seen_realms.count(handler->auth_info()->realm) == 0;
+        });
+    ASSERT_TRUE(it != login_prompt_observer_.handlers().end());
+    seen_realms.insert((*it)->auth_info()->realm);
 
-    while (!observer.handlers().empty()) {
-      WindowedAuthCancelledObserver auth_cancelled_waiter(controller);
-      LoginHandler* handler = *observer.handlers().begin();
-
-      ASSERT_TRUE(handler);
-      n_handlers++;
-      handler->CancelAuth();
-      auth_cancelled_waiter.Wait();
-    }
-
-    if (n_handlers < kMultiRealmTestRealmCount)
-      auth_needed_waiter.Wait();
+    for_each_realm_func(*it);
   }
 
   load_stop_waiter.Wait();
-
-  EXPECT_EQ(kMultiRealmTestRealmCount, n_handlers);
-  EXPECT_EQ(0, observer.auth_supplied_count());
-  EXPECT_LT(0, observer.auth_needed_count());
-  EXPECT_LT(0, observer.auth_cancelled_count());
 }
 
-// Similar to the MultipleRealmCancellation test above, but tests
-// whether supplying credentials work as exepcted.
-IN_PROC_BROWSER_TEST_F(LoginPromptBrowserTest, MultipleRealmConfirmation) {
-  ASSERT_TRUE(embedded_test_server()->Start());
-  GURL test_page = embedded_test_server()->GetURL(kMultiRealmTestPage);
+// Checks that cancelling works as expected.
+IN_PROC_BROWSER_TEST_F(MultiRealmLoginPromptBrowserTest,
+                       MultipleRealmCancellation) {
+  RunTest([this](LoginHandler* handler) {
+    WindowedAuthCancelledObserver waiter(GetNavigationController());
+    handler->CancelAuth();
+    waiter.Wait();
+  });
 
-  content::WebContents* contents =
-      browser()->tab_strip_model()->GetActiveWebContents();
-  NavigationController* controller = &contents->GetController();
-  LoginPromptBrowserTestObserver observer;
+  EXPECT_EQ(0, login_prompt_observer()->auth_supplied_count());
+  EXPECT_LT(0, login_prompt_observer()->auth_needed_count());
+  EXPECT_LT(0, login_prompt_observer()->auth_cancelled_count());
+}
 
-  observer.Register(content::Source<NavigationController>(controller));
+// Checks that supplying credentials works as exepcted.
+IN_PROC_BROWSER_TEST_F(MultiRealmLoginPromptBrowserTest,
+                       MultipleRealmConfirmation) {
+  RunTest([this](LoginHandler* handler) {
+    WindowedAuthSuppliedObserver waiter(GetNavigationController());
+    SetAuthFor(handler);
+    waiter.Wait();
+  });
 
-  WindowedLoadStopObserver load_stop_waiter(controller, 1);
-  int n_handlers = 0;
-
-  {
-    WindowedAuthNeededObserver auth_needed_waiter(controller);
-
-    browser()->OpenURL(OpenURLParams(test_page, Referrer(),
-                                     WindowOpenDisposition::CURRENT_TAB,
-                                     ui::PAGE_TRANSITION_TYPED, false));
-    auth_needed_waiter.Wait();
-  }
-
-  while (n_handlers < kMultiRealmTestRealmCount) {
-    WindowedAuthNeededObserver auth_needed_waiter(controller);
-
-    while (!observer.handlers().empty()) {
-      WindowedAuthSuppliedObserver auth_supplied_waiter(controller);
-      LoginHandler* handler = *observer.handlers().begin();
-
-      ASSERT_TRUE(handler);
-      n_handlers++;
-      SetAuthFor(handler);
-      auth_supplied_waiter.Wait();
-    }
-
-    if (n_handlers < kMultiRealmTestRealmCount)
-      auth_needed_waiter.Wait();
-  }
-
-  load_stop_waiter.Wait();
-
-  EXPECT_EQ(kMultiRealmTestRealmCount, n_handlers);
-  EXPECT_LT(0, observer.auth_needed_count());
-  EXPECT_LT(0, observer.auth_supplied_count());
-  EXPECT_EQ(0, observer.auth_cancelled_count());
+  EXPECT_LT(0, login_prompt_observer()->auth_needed_count());
+  EXPECT_LT(0, login_prompt_observer()->auth_supplied_count());
+  EXPECT_EQ(0, login_prompt_observer()->auth_cancelled_count());
 }
 
 // Testing for recovery from an incorrect password for the case where
diff --git a/chrome/browser/ui/login/login_handler_test_utils.cc b/chrome/browser/ui/login/login_handler_test_utils.cc
index a0814c6b..d1c419d7 100644
--- a/chrome/browser/ui/login/login_handler_test_utils.cc
+++ b/chrome/browser/ui/login/login_handler_test_utils.cc
@@ -57,6 +57,10 @@
   registrar_.Add(this, chrome::NOTIFICATION_AUTH_CANCELLED, source);
 }
 
+void LoginPromptBrowserTestObserver::UnregisterAll() {
+  registrar_.RemoveAll();
+}
+
 WindowedLoadStopObserver::WindowedLoadStopObserver(
     content::NavigationController* controller,
     int notification_count)
diff --git a/chrome/browser/ui/login/login_handler_test_utils.h b/chrome/browser/ui/login/login_handler_test_utils.h
index 8f32a54f..bf277a0 100644
--- a/chrome/browser/ui/login/login_handler_test_utils.h
+++ b/chrome/browser/ui/login/login_handler_test_utils.h
@@ -31,6 +31,7 @@
   void RemoveHandler(LoginHandler* handler);
 
   void Register(const content::NotificationSource& source);
+  void UnregisterAll();
 
   const std::list<LoginHandler*>& handlers() const { return handlers_; }
 
diff --git a/chrome/browser/ui/omnibox/omnibox_controller_unittest.cc b/chrome/browser/ui/omnibox/omnibox_controller_unittest.cc
index c46bbb4..16874ca 100644
--- a/chrome/browser/ui/omnibox/omnibox_controller_unittest.cc
+++ b/chrome/browser/ui/omnibox/omnibox_controller_unittest.cc
@@ -6,7 +6,6 @@
 
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
-#include "base/strings/string_util.h"
 #include "chrome/browser/autocomplete/chrome_autocomplete_provider_client.h"
 #include "chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.h"
 #include "chrome/test/base/testing_profile.h"
@@ -19,6 +18,7 @@
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace {
+
 class TestOmniboxClient : public OmniboxClient {
  public:
   explicit TestOmniboxClient(Profile* profile)
@@ -31,62 +31,10 @@
       override {
     return base::MakeUnique<ChromeAutocompleteProviderClient>(profile_);
   }
-  std::unique_ptr<OmniboxNavigationObserver> CreateOmniboxNavigationObserver(
-      const base::string16& text,
-      const AutocompleteMatch& match,
-      const AutocompleteMatch& alternate_nav_match) override {
-    return nullptr;
-  }
-  bool CurrentPageExists() const override { return true; }
-  const GURL& GetURL() const override { return GURL::EmptyGURL(); }
-  const base::string16& GetTitle() const override {
-    return base::EmptyString16();
-  }
-  gfx::Image GetFavicon() const override { return gfx::Image(); }
-  bool IsInstantNTP() const override { return false; }
-  bool IsSearchResultsPage() const override { return false; }
-  bool IsLoading() const override { return false; }
-  bool IsPasteAndGoEnabled() const override { return false; }
-  bool IsNewTabPage(const std::string& url) const override { return false; }
-  bool IsHomePage(const std::string& url) const override { return false; }
   const SessionID& GetSessionID() const override { return session_id_; }
-  bookmarks::BookmarkModel* GetBookmarkModel() override { return nullptr; }
-  TemplateURLService* GetTemplateURLService() override { return nullptr; }
   const AutocompleteSchemeClassifier& GetSchemeClassifier() const override {
     return scheme_classifier_;
   }
-  AutocompleteClassifier* GetAutocompleteClassifier() override {
-    return nullptr;
-  }
-  gfx::Image GetIconIfExtensionMatch(
-      const AutocompleteMatch& match) const override {
-    return gfx::Image();
-  }
-  bool ProcessExtensionKeyword(TemplateURL* template_url,
-                               const AutocompleteMatch& match,
-                               WindowOpenDisposition disposition,
-                               OmniboxNavigationObserver* observer) override {
-    return false;
-  }
-  void OnInputStateChanged() override {}
-  void OnFocusChanged(OmniboxFocusState state,
-                      OmniboxFocusChangeReason reason) override {}
-  void OnResultChanged(const AutocompleteResult& result,
-                       bool default_match_changed,
-                       const base::Callback<void(const SkBitmap& bitmap)>&
-                           on_bitmap_fetched) override {}
-  void OnCurrentMatchChanged(const AutocompleteMatch& match) override {}
-  void OnTextChanged(const AutocompleteMatch& current_match,
-                     bool user_input_in_progress,
-                     base::string16& user_text,
-                     const AutocompleteResult& result,
-                     bool is_popup_open,
-                     bool has_focus) override {}
-  void OnInputAccepted(const AutocompleteMatch& match) override {}
-  void OnRevert() override {}
-  void OnURLOpenedFromOmnibox(OmniboxLog* log) override {}
-  void OnBookmarkLaunched() override {}
-  void DiscardNonCommittedNavigations() override {}
 
  private:
   Profile* profile_;
diff --git a/chrome/browser/ui/views/find_bar_views_interactive_uitest.cc b/chrome/browser/ui/views/find_bar_views_interactive_uitest.cc
index 497aa60f..aa13796b 100644
--- a/chrome/browser/ui/views/find_bar_views_interactive_uitest.cc
+++ b/chrome/browser/ui/views/find_bar_views_interactive_uitest.cc
@@ -85,6 +85,14 @@
     return details;
   }
 
+  FindNotificationDetails WaitForFinalFindResult() {
+    while (true) {
+      auto details = WaitForFindResult();
+      if (details.final_update())
+        return details;
+    }
+  }
+
  private:
   DISALLOW_COPY_AND_ASSIGN(FindInPageTest);
 };
@@ -183,28 +191,28 @@
 
   // Clicking the next and previous buttons should not alter the focused view.
   ClickOnView(next_button);
-  EXPECT_EQ(2, WaitForFindResult().active_match_ordinal());
+  EXPECT_EQ(2, WaitForFinalFindResult().active_match_ordinal());
   EXPECT_TRUE(IsViewFocused(browser(), VIEW_ID_FIND_IN_PAGE_TEXT_FIELD));
   ClickOnView(previous_button);
-  EXPECT_EQ(1, WaitForFindResult().active_match_ordinal());
+  EXPECT_EQ(1, WaitForFinalFindResult().active_match_ordinal());
   EXPECT_TRUE(IsViewFocused(browser(), VIEW_ID_FIND_IN_PAGE_TEXT_FIELD));
 
   // Tapping the next and previous buttons should not alter the focused view.
   TapOnView(next_button);
-  EXPECT_EQ(2, WaitForFindResult().active_match_ordinal());
+  EXPECT_EQ(2, WaitForFinalFindResult().active_match_ordinal());
   EXPECT_TRUE(IsViewFocused(browser(), VIEW_ID_FIND_IN_PAGE_TEXT_FIELD));
   TapOnView(previous_button);
-  EXPECT_EQ(1, WaitForFindResult().active_match_ordinal());
+  EXPECT_EQ(1, WaitForFinalFindResult().active_match_ordinal());
   EXPECT_TRUE(IsViewFocused(browser(), VIEW_ID_FIND_IN_PAGE_TEXT_FIELD));
 
   // The same should be true even when the previous button is focused.
   previous_button->RequestFocus();
   EXPECT_TRUE(IsViewFocused(browser(), VIEW_ID_FIND_IN_PAGE_PREVIOUS_BUTTON));
   ClickOnView(next_button);
-  EXPECT_EQ(2, WaitForFindResult().active_match_ordinal());
+  EXPECT_EQ(2, WaitForFinalFindResult().active_match_ordinal());
   EXPECT_TRUE(IsViewFocused(browser(), VIEW_ID_FIND_IN_PAGE_PREVIOUS_BUTTON));
   TapOnView(next_button);
-  EXPECT_EQ(3, WaitForFindResult().active_match_ordinal());
+  EXPECT_EQ(3, WaitForFinalFindResult().active_match_ordinal());
   EXPECT_TRUE(IsViewFocused(browser(), VIEW_ID_FIND_IN_PAGE_PREVIOUS_BUTTON));
 }
 
diff --git a/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc b/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc
index 8e1cd9d..6525d653 100644
--- a/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc
+++ b/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc
@@ -256,11 +256,7 @@
 
   visible_fraction_ = 0;
   browser_view_->top_container()->SetPaintToLayer();
-  // In mash the window manager (ash) also renders to the non-client area. In
-  // order to see the decorations drawn by ash the layer needs to be marked as
-  // not filling bounds opaquely.
-  if (ash_util::IsRunningInMash())
-    browser_view_->top_container()->layer()->SetFillsBoundsOpaquely(false);
+  browser_view_->top_container()->layer()->SetFillsBoundsOpaquely(false);
   LayoutBrowserRootView();
   CreateMashRevealWidget();
   for (Observer& observer : observers_)
diff --git a/chrome/browser/ui/views/new_back_shortcut_bubble.h b/chrome/browser/ui/views/new_back_shortcut_bubble.h
index 92eb074..88b2565 100644
--- a/chrome/browser/ui/views/new_back_shortcut_bubble.h
+++ b/chrome/browser/ui/views/new_back_shortcut_bubble.h
@@ -27,9 +27,8 @@
 
 // NewBackShortcutBubble shows a short-lived notification along the top of the
 // screen when the user presses the old Back/Forward shortcut, telling them how
-// to use the new shortcut. This will only be available for a few milestones to
-// let users adapt.
-// TODO(mgiuca): Remove this in M54 (https://crbug.com/610039).
+// to use the new shortcut. This notification only shows up the first few times
+// the user presses the old shortcut.
 class NewBackShortcutBubble : public gfx::AnimationDelegate {
  public:
   explicit NewBackShortcutBubble(ExclusiveAccessBubbleViewsContext* context);
diff --git a/chrome/browser/ui/views/payments/payment_request_credit_card_editor_interactive_uitest.cc b/chrome/browser/ui/views/payments/credit_card_editor_view_controller_browsertest.cc
similarity index 97%
rename from chrome/browser/ui/views/payments/payment_request_credit_card_editor_interactive_uitest.cc
rename to chrome/browser/ui/views/payments/credit_card_editor_view_controller_browsertest.cc
index 209437c..6d4bb54 100644
--- a/chrome/browser/ui/views/payments/payment_request_credit_card_editor_interactive_uitest.cc
+++ b/chrome/browser/ui/views/payments/credit_card_editor_view_controller_browsertest.cc
@@ -7,8 +7,8 @@
 #include "base/macros.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
+#include "chrome/browser/ui/views/payments/payment_request_browsertest_base.h"
 #include "chrome/browser/ui/views/payments/payment_request_dialog_view_ids.h"
-#include "chrome/browser/ui/views/payments/payment_request_interactive_uitest_base.h"
 #include "chrome/browser/ui/views/payments/validating_textfield.h"
 #include "components/autofill/core/browser/field_types.h"
 #include "components/autofill/core/browser/personal_data_manager.h"
@@ -28,10 +28,10 @@
 }  // namespace
 
 class PaymentRequestCreditCardEditorTest
-    : public PaymentRequestInteractiveTestBase {
+    : public PaymentRequestBrowserTestBase {
  protected:
   PaymentRequestCreditCardEditorTest()
-      : PaymentRequestInteractiveTestBase(
+      : PaymentRequestBrowserTestBase(
             "/payment_request_no_shipping_test.html") {}
 
   PersonalDataLoadedObserverMock personal_data_observer_;
@@ -297,11 +297,11 @@
 }
 
 class PaymentRequestCreditCardBasicCardTest
-    : public PaymentRequestInteractiveTestBase {
+    : public PaymentRequestBrowserTestBase {
  protected:
   PaymentRequestCreditCardBasicCardTest()
-      : PaymentRequestInteractiveTestBase(
-            "/payment_request_basic_card_test.html") {}
+      : PaymentRequestBrowserTestBase("/payment_request_basic_card_test.html") {
+  }
 
   void InvokePaymentRequestWithJs(const std::string& js) {
     ResetEventObserver(DialogEvent::DIALOG_OPENED);
diff --git a/chrome/browser/ui/views/payments/payment_method_view_controller_interactive_uitest.cc b/chrome/browser/ui/views/payments/payment_method_view_controller_browsertest.cc
similarity index 93%
rename from chrome/browser/ui/views/payments/payment_method_view_controller_interactive_uitest.cc
rename to chrome/browser/ui/views/payments/payment_method_view_controller_browsertest.cc
index 580e056..9d1e111 100644
--- a/chrome/browser/ui/views/payments/payment_method_view_controller_interactive_uitest.cc
+++ b/chrome/browser/ui/views/payments/payment_method_view_controller_browsertest.cc
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "chrome/browser/ui/views/payments/payment_request_browsertest_base.h"
 #include "chrome/browser/ui/views/payments/payment_request_dialog_view_ids.h"
-#include "chrome/browser/ui/views/payments/payment_request_interactive_uitest_base.h"
 #include "components/autofill/core/browser/autofill_test_utils.h"
 #include "components/autofill/core/browser/personal_data_manager.h"
 #include "components/payments/content/payment_request.h"
@@ -11,11 +11,10 @@
 
 namespace payments {
 
-class PaymentMethodViewControllerTest
-    : public PaymentRequestInteractiveTestBase {
+class PaymentMethodViewControllerTest : public PaymentRequestBrowserTestBase {
  protected:
   PaymentMethodViewControllerTest()
-      : PaymentRequestInteractiveTestBase(
+      : PaymentRequestBrowserTestBase(
             "/payment_request_no_shipping_test.html") {}
 
  private:
diff --git a/chrome/browser/ui/views/payments/payment_request_interactive_uitest.cc b/chrome/browser/ui/views/payments/payment_request_browsertest.cc
similarity index 88%
rename from chrome/browser/ui/views/payments/payment_request_interactive_uitest.cc
rename to chrome/browser/ui/views/payments/payment_request_browsertest.cc
index 1c707fe2..5cebdac 100644
--- a/chrome/browser/ui/views/payments/payment_request_interactive_uitest.cc
+++ b/chrome/browser/ui/views/payments/payment_request_browsertest.cc
@@ -7,8 +7,8 @@
 #include "base/macros.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/ui/browser_commands.h"
+#include "chrome/browser/ui/views/payments/payment_request_browsertest_base.h"
 #include "chrome/browser/ui/views/payments/payment_request_dialog_view_ids.h"
-#include "chrome/browser/ui/views/payments/payment_request_interactive_uitest_base.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/payments/content/payment_request.h"
 #include "components/payments/content/payment_request_web_contents_manager.h"
@@ -18,10 +18,10 @@
 namespace payments {
 
 class PaymentRequestWebContentsManagerTest
-    : public PaymentRequestInteractiveTestBase {
+    : public PaymentRequestBrowserTestBase {
  protected:
   PaymentRequestWebContentsManagerTest()
-      : PaymentRequestInteractiveTestBase(
+      : PaymentRequestBrowserTestBase(
             "/payment_request_multiple_requests.html") {}
 
  private:
@@ -35,10 +35,10 @@
   EXPECT_EQ(5U, payment_requests.size());
 }
 
-class PaymentRequestNoShippingTest : public PaymentRequestInteractiveTestBase {
+class PaymentRequestNoShippingTest : public PaymentRequestBrowserTestBase {
  protected:
   PaymentRequestNoShippingTest()
-      : PaymentRequestInteractiveTestBase(
+      : PaymentRequestBrowserTestBase(
             "/payment_request_no_shipping_test.html") {}
 
  private:
@@ -93,10 +93,10 @@
   WaitForObservedEvent();
 }
 
-class PaymentRequestAbortTest : public PaymentRequestInteractiveTestBase {
+class PaymentRequestAbortTest : public PaymentRequestBrowserTestBase {
  protected:
   PaymentRequestAbortTest()
-      : PaymentRequestInteractiveTestBase("/payment_request_abort_test.html") {}
+      : PaymentRequestBrowserTestBase("/payment_request_abort_test.html") {}
 
  private:
   DISALLOW_COPY_AND_ASSIGN(PaymentRequestAbortTest);
diff --git a/chrome/browser/ui/views/payments/payment_request_interactive_uitest_base.cc b/chrome/browser/ui/views/payments/payment_request_browsertest_base.cc
similarity index 75%
rename from chrome/browser/ui/views/payments/payment_request_interactive_uitest_base.cc
rename to chrome/browser/ui/views/payments/payment_request_browsertest_base.cc
index 86fa7e5..a30b17a 100644
--- a/chrome/browser/ui/views/payments/payment_request_interactive_uitest_base.cc
+++ b/chrome/browser/ui/views/payments/payment_request_browsertest_base.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/ui/views/payments/payment_request_interactive_uitest_base.h"
+#include "chrome/browser/ui/views/payments/payment_request_browsertest_base.h"
 
 #include <vector>
 
@@ -19,7 +19,6 @@
 #include "chrome/browser/ui/views/payments/validating_combobox.h"
 #include "chrome/browser/ui/views/payments/validating_textfield.h"
 #include "chrome/browser/ui/views/payments/view_stack.h"
-#include "chrome/test/base/interactive_test_utils.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/autofill/core/browser/autofill_profile.h"
 #include "components/autofill/core/browser/credit_card.h"
@@ -35,7 +34,10 @@
 #include "services/service_manager/public/cpp/interface_registry.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/base/test/ui_controls.h"
+#include "ui/events/base_event_utils.h"
+#include "ui/events/event.h"
 #include "ui/gfx/animation/test_animation_delegate.h"
+#include "ui/gfx/geometry/point.h"
 #include "ui/views/controls/button/button.h"
 #include "ui/views/controls/label.h"
 #include "ui/views/controls/styled_label.h"
@@ -45,13 +47,12 @@
 PersonalDataLoadedObserverMock::PersonalDataLoadedObserverMock() {}
 PersonalDataLoadedObserverMock::~PersonalDataLoadedObserverMock() {}
 
-PaymentRequestInteractiveTestBase::PaymentRequestInteractiveTestBase(
+PaymentRequestBrowserTestBase::PaymentRequestBrowserTestBase(
     const std::string& test_file_path)
-    : test_file_path_(test_file_path),
-      delegate_(nullptr) {}
-PaymentRequestInteractiveTestBase::~PaymentRequestInteractiveTestBase() {}
+    : test_file_path_(test_file_path), delegate_(nullptr) {}
+PaymentRequestBrowserTestBase::~PaymentRequestBrowserTestBase() {}
 
-void PaymentRequestInteractiveTestBase::SetUpCommandLine(
+void PaymentRequestBrowserTestBase::SetUpCommandLine(
     base::CommandLine* command_line) {
   InProcessBrowserTest::SetUpCommandLine(command_line);
   command_line->AppendSwitch(switches::kEnableExperimentalWebPlatformFeatures);
@@ -59,7 +60,7 @@
                                   features::kWebPayments.name);
 }
 
-void PaymentRequestInteractiveTestBase::SetUpOnMainThread() {
+void PaymentRequestBrowserTestBase::SetUpOnMainThread() {
   https_server_ = base::MakeUnique<net::EmbeddedTestServer>(
       net::EmbeddedTestServer::TYPE_HTTPS);
   ASSERT_TRUE(https_server_->InitializeAndListen());
@@ -76,48 +77,47 @@
   service_manager::InterfaceRegistry* registry =
       web_contents->GetMainFrame()->GetInterfaceRegistry();
   registry->RemoveInterface(payments::mojom::PaymentRequest::Name_);
-  registry->AddInterface(base::Bind(
-      &PaymentRequestInteractiveTestBase::CreatePaymentRequestForTest,
-      base::Unretained(this), web_contents));
+  registry->AddInterface(
+      base::Bind(&PaymentRequestBrowserTestBase::CreatePaymentRequestForTest,
+                 base::Unretained(this), web_contents));
 }
 
-void PaymentRequestInteractiveTestBase::OnDialogOpened() {
+void PaymentRequestBrowserTestBase::OnDialogOpened() {
   if (event_observer_)
     event_observer_->Observe(DialogEvent::DIALOG_OPENED);
 }
 
-void PaymentRequestInteractiveTestBase::OnOrderSummaryOpened() {
+void PaymentRequestBrowserTestBase::OnOrderSummaryOpened() {
   if (event_observer_)
     event_observer_->Observe(DialogEvent::ORDER_SUMMARY_OPENED);
 }
 
-void PaymentRequestInteractiveTestBase::OnPaymentMethodOpened() {
+void PaymentRequestBrowserTestBase::OnPaymentMethodOpened() {
   if (event_observer_)
     event_observer_->Observe(DialogEvent::PAYMENT_METHOD_OPENED);
 }
 
-void PaymentRequestInteractiveTestBase::OnCreditCardEditorOpened() {
+void PaymentRequestBrowserTestBase::OnCreditCardEditorOpened() {
   if (event_observer_)
     event_observer_->Observe(DialogEvent::CREDIT_CARD_EDITOR_OPENED);
 }
 
-void PaymentRequestInteractiveTestBase::OnBackNavigation() {
+void PaymentRequestBrowserTestBase::OnBackNavigation() {
   if (event_observer_)
     event_observer_->Observe(DialogEvent::BACK_NAVIGATION);
 }
 
-void PaymentRequestInteractiveTestBase::OnContactInfoOpened() {
+void PaymentRequestBrowserTestBase::OnContactInfoOpened() {
   if (event_observer_)
     event_observer_->Observe(DialogEvent::CONTACT_INFO_OPENED);
 }
 
-void PaymentRequestInteractiveTestBase::OnWidgetDestroyed(
-    views::Widget* widget) {
+void PaymentRequestBrowserTestBase::OnWidgetDestroyed(views::Widget* widget) {
   if (event_observer_)
     event_observer_->Observe(DialogEvent::DIALOG_CLOSED);
 }
 
-void PaymentRequestInteractiveTestBase::InvokePaymentRequestUI() {
+void PaymentRequestBrowserTestBase::InvokePaymentRequestUI() {
   ResetEventObserver(DialogEvent::DIALOG_OPENED);
 
   content::WebContents* web_contents = GetActiveWebContents();
@@ -133,31 +133,30 @@
   EXPECT_TRUE(web_contents_modal_dialog_manager->IsDialogActive());
 }
 
-void PaymentRequestInteractiveTestBase::OpenOrderSummaryScreen() {
+void PaymentRequestBrowserTestBase::OpenOrderSummaryScreen() {
   ResetEventObserver(DialogEvent::ORDER_SUMMARY_OPENED);
 
   ClickOnDialogViewAndWait(DialogViewID::PAYMENT_SHEET_SUMMARY_SECTION);
 }
 
-void PaymentRequestInteractiveTestBase::OpenPaymentMethodScreen() {
+void PaymentRequestBrowserTestBase::OpenPaymentMethodScreen() {
   ResetEventObserver(DialogEvent::PAYMENT_METHOD_OPENED);
 
   ClickOnDialogViewAndWait(DialogViewID::PAYMENT_SHEET_PAYMENT_METHOD_SECTION);
 }
 
-void PaymentRequestInteractiveTestBase::OpenCreditCardEditorScreen() {
+void PaymentRequestBrowserTestBase::OpenCreditCardEditorScreen() {
   ResetEventObserver(DialogEvent::CREDIT_CARD_EDITOR_OPENED);
 
   ClickOnDialogViewAndWait(DialogViewID::PAYMENT_METHOD_ADD_CARD_BUTTON);
 }
 
-content::WebContents*
-PaymentRequestInteractiveTestBase::GetActiveWebContents() {
+content::WebContents* PaymentRequestBrowserTestBase::GetActiveWebContents() {
   return browser()->tab_strip_model()->GetActiveWebContents();
 }
 
 const std::vector<PaymentRequest*>
-PaymentRequestInteractiveTestBase::GetPaymentRequests(
+PaymentRequestBrowserTestBase::GetPaymentRequests(
     content::WebContents* web_contents) {
   PaymentRequestWebContentsManager* manager =
       PaymentRequestWebContentsManager::GetOrCreateForWebContents(web_contents);
@@ -170,13 +169,12 @@
   return payment_requests_ptrs;
 }
 
-autofill::PersonalDataManager*
-PaymentRequestInteractiveTestBase::GetDataManager() {
+autofill::PersonalDataManager* PaymentRequestBrowserTestBase::GetDataManager() {
   return autofill::PersonalDataManagerFactory::GetForProfile(
       Profile::FromBrowserContext(GetActiveWebContents()->GetBrowserContext()));
 }
 
-void PaymentRequestInteractiveTestBase::AddAutofillProfile(
+void PaymentRequestBrowserTestBase::AddAutofillProfile(
     const autofill::AutofillProfile& profile) {
   autofill::PersonalDataManager* personal_data_manager = GetDataManager();
   size_t profile_count = personal_data_manager->GetProfiles().size();
@@ -193,7 +191,7 @@
   EXPECT_EQ(profile_count + 1, personal_data_manager->GetProfiles().size());
 }
 
-void PaymentRequestInteractiveTestBase::AddCreditCard(
+void PaymentRequestBrowserTestBase::AddCreditCard(
     const autofill::CreditCard& card) {
   autofill::PersonalDataManager* personal_data_manager = GetDataManager();
   size_t card_count = personal_data_manager->GetCreditCards().size();
@@ -210,7 +208,7 @@
   EXPECT_EQ(card_count + 1, personal_data_manager->GetCreditCards().size());
 }
 
-void PaymentRequestInteractiveTestBase::CreatePaymentRequestForTest(
+void PaymentRequestBrowserTestBase::CreatePaymentRequestForTest(
     content::WebContents* web_contents,
     mojo::InterfaceRequest<payments::mojom::PaymentRequest> request) {
   DCHECK(web_contents);
@@ -223,7 +221,7 @@
                              std::move(request));
 }
 
-void PaymentRequestInteractiveTestBase::ClickOnDialogViewAndWait(
+void PaymentRequestBrowserTestBase::ClickOnDialogViewAndWait(
     DialogViewID view_id) {
   views::View* view =
       delegate_->dialog_view()->GetViewByID(static_cast<int>(view_id));
@@ -231,21 +229,24 @@
   ClickOnDialogViewAndWait(view);
 }
 
-void PaymentRequestInteractiveTestBase::ClickOnDialogViewAndWait(
+void PaymentRequestBrowserTestBase::ClickOnDialogViewAndWait(
     views::View* view) {
   DCHECK(view);
-  base::RunLoop run_loop;
-  ui_test_utils::MoveMouseToCenterAndPress(
-      view, ui_controls::LEFT, ui_controls::DOWN | ui_controls::UP,
-      run_loop.QuitClosure());
-  run_loop.Run();
+  ui::MouseEvent pressed(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(),
+                         ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON,
+                         ui::EF_LEFT_MOUSE_BUTTON);
+  view->OnMousePressed(pressed);
+  ui::MouseEvent released_event = ui::MouseEvent(
+      ui::ET_MOUSE_RELEASED, gfx::Point(), gfx::Point(), ui::EventTimeForNow(),
+      ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
+  view->OnMouseReleased(released_event);
 
   WaitForAnimation();
 
   WaitForObservedEvent();
 }
 
-void PaymentRequestInteractiveTestBase::SetEditorTextfieldValue(
+void PaymentRequestBrowserTestBase::SetEditorTextfieldValue(
     const base::string16& value,
     autofill::ServerFieldType type) {
   ValidatingTextfield* textfield = static_cast<ValidatingTextfield*>(
@@ -256,7 +257,7 @@
   textfield->OnBlur();
 }
 
-void PaymentRequestInteractiveTestBase::SetComboboxValue(
+void PaymentRequestBrowserTestBase::SetComboboxValue(
     const base::string16& value,
     autofill::ServerFieldType type) {
   ValidatingCombobox* combobox = static_cast<ValidatingCombobox*>(
@@ -267,7 +268,7 @@
   combobox->OnBlur();
 }
 
-bool PaymentRequestInteractiveTestBase::IsEditorTextfieldInvalid(
+bool PaymentRequestBrowserTestBase::IsEditorTextfieldInvalid(
     autofill::ServerFieldType type) {
   ValidatingTextfield* textfield = static_cast<ValidatingTextfield*>(
       delegate_->dialog_view()->GetViewByID(static_cast<int>(type)));
@@ -275,7 +276,7 @@
   return textfield->invalid();
 }
 
-bool PaymentRequestInteractiveTestBase::IsEditorComboboxInvalid(
+bool PaymentRequestBrowserTestBase::IsEditorComboboxInvalid(
     autofill::ServerFieldType type) {
   ValidatingCombobox* combobox = static_cast<ValidatingCombobox*>(
       delegate_->dialog_view()->GetViewByID(static_cast<int>(type)));
@@ -283,7 +284,7 @@
   return combobox->invalid();
 }
 
-bool PaymentRequestInteractiveTestBase::IsPayButtonEnabled() {
+bool PaymentRequestBrowserTestBase::IsPayButtonEnabled() {
   views::Button* button =
       static_cast<views::Button*>(delegate_->dialog_view()->GetViewByID(
           static_cast<int>(DialogViewID::PAY_BUTTON)));
@@ -291,7 +292,7 @@
   return button->enabled();
 }
 
-void PaymentRequestInteractiveTestBase::WaitForAnimation() {
+void PaymentRequestBrowserTestBase::WaitForAnimation() {
   ViewStack* view_stack = dialog_view()->view_stack_for_testing();
   if (view_stack->slide_in_animator_->IsAnimating()) {
     view_stack->slide_in_animator_->SetAnimationDuration(1);
@@ -308,14 +309,14 @@
   }
 }
 
-const base::string16& PaymentRequestInteractiveTestBase::GetStyledLabelText(
+const base::string16& PaymentRequestBrowserTestBase::GetStyledLabelText(
     DialogViewID view_id) {
   views::View* view = dialog_view()->GetViewByID(static_cast<int>(view_id));
   DCHECK(view);
   return static_cast<views::StyledLabel*>(view)->text();
 }
 
-const base::string16& PaymentRequestInteractiveTestBase::GetErrorLabelForType(
+const base::string16& PaymentRequestBrowserTestBase::GetErrorLabelForType(
     autofill::ServerFieldType type) {
   views::View* view = dialog_view()->GetViewByID(
       static_cast<int>(DialogViewID::ERROR_LABEL_OFFSET) + type);
@@ -323,13 +324,12 @@
   return static_cast<views::Label*>(view)->text();
 }
 
-PaymentRequestInteractiveTestBase::DialogEventObserver::DialogEventObserver(
-    PaymentRequestInteractiveTestBase::DialogEvent event)
+PaymentRequestBrowserTestBase::DialogEventObserver::DialogEventObserver(
+    PaymentRequestBrowserTestBase::DialogEvent event)
     : event_(event), seen_(false) {}
-PaymentRequestInteractiveTestBase::DialogEventObserver::~DialogEventObserver() {
-}
+PaymentRequestBrowserTestBase::DialogEventObserver::~DialogEventObserver() {}
 
-void PaymentRequestInteractiveTestBase::DialogEventObserver::Wait() {
+void PaymentRequestBrowserTestBase::DialogEventObserver::Wait() {
   if (seen_)
     return;
 
@@ -337,8 +337,8 @@
   run_loop_.Run();
 }
 
-void PaymentRequestInteractiveTestBase::DialogEventObserver::Observe(
-    PaymentRequestInteractiveTestBase::DialogEvent event) {
+void PaymentRequestBrowserTestBase::DialogEventObserver::Observe(
+    PaymentRequestBrowserTestBase::DialogEvent event) {
   if (seen_)
     return;
 
@@ -348,11 +348,11 @@
     run_loop_.Quit();
 }
 
-void PaymentRequestInteractiveTestBase::ResetEventObserver(DialogEvent event) {
+void PaymentRequestBrowserTestBase::ResetEventObserver(DialogEvent event) {
   event_observer_ = base::MakeUnique<DialogEventObserver>(event);
 }
 
-void PaymentRequestInteractiveTestBase::WaitForObservedEvent() {
+void PaymentRequestBrowserTestBase::WaitForObservedEvent() {
   event_observer_->Wait();
 }
 
diff --git a/chrome/browser/ui/views/payments/payment_request_interactive_uitest_base.h b/chrome/browser/ui/views/payments/payment_request_browsertest_base.h
similarity index 92%
rename from chrome/browser/ui/views/payments/payment_request_interactive_uitest_base.h
rename to chrome/browser/ui/views/payments/payment_request_browsertest_base.h
index a7b619a7..718e8b3 100644
--- a/chrome/browser/ui/views/payments/payment_request_interactive_uitest_base.h
+++ b/chrome/browser/ui/views/payments/payment_request_browsertest_base.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_UI_VIEWS_PAYMENTS_PAYMENT_REQUEST_INTERACTIVE_UITEST_BASE_H_
-#define CHROME_BROWSER_UI_VIEWS_PAYMENTS_PAYMENT_REQUEST_INTERACTIVE_UITEST_BASE_H_
+#ifndef CHROME_BROWSER_UI_VIEWS_PAYMENTS_PAYMENT_REQUEST_BROWSERTEST_BASE_H_
+#define CHROME_BROWSER_UI_VIEWS_PAYMENTS_PAYMENT_REQUEST_BROWSERTEST_BASE_H_
 
 #include <vector>
 
@@ -58,15 +58,15 @@
 
 // Base class for any interactive PaymentRequest test that will need to open
 // the UI and interact with it.
-class PaymentRequestInteractiveTestBase
+class PaymentRequestBrowserTestBase
     : public InProcessBrowserTest,
       public PaymentRequestDialogView::ObserverForTest,
       public views::WidgetObserver {
  protected:
   // Test will open a browser window to |test_file_path| (relative to
   // chrome/test/data/payments).
-  explicit PaymentRequestInteractiveTestBase(const std::string& test_file_path);
-  ~PaymentRequestInteractiveTestBase() override;
+  explicit PaymentRequestBrowserTestBase(const std::string& test_file_path);
+  ~PaymentRequestBrowserTestBase() override;
 
   void SetUpCommandLine(base::CommandLine* command_line) override;
   void SetUpOnMainThread() override;
@@ -199,9 +199,9 @@
   // Weak, owned by the PaymentRequest object.
   TestChromePaymentRequestDelegate* delegate_;
 
-  DISALLOW_COPY_AND_ASSIGN(PaymentRequestInteractiveTestBase);
+  DISALLOW_COPY_AND_ASSIGN(PaymentRequestBrowserTestBase);
 };
 
 }  // namespace payments
 
-#endif  // CHROME_BROWSER_UI_VIEWS_PAYMENTS_PAYMENT_REQUEST_INTERACTIVE_UITEST_BASE_H_
+#endif  // CHROME_BROWSER_UI_VIEWS_PAYMENTS_PAYMENT_REQUEST_BROWSERTEST_BASE_H_
diff --git a/chrome/browser/ui/views/payments/payment_sheet_view_controller_interactive_uitest.cc b/chrome/browser/ui/views/payments/payment_sheet_view_controller_browsertest.cc
similarity index 95%
rename from chrome/browser/ui/views/payments/payment_sheet_view_controller_interactive_uitest.cc
rename to chrome/browser/ui/views/payments/payment_sheet_view_controller_browsertest.cc
index 67f9276..d8ecdb9 100644
--- a/chrome/browser/ui/views/payments/payment_sheet_view_controller_interactive_uitest.cc
+++ b/chrome/browser/ui/views/payments/payment_sheet_view_controller_browsertest.cc
@@ -3,8 +3,8 @@
 // found in the LICENSE file.
 
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/ui/views/payments/payment_request_browsertest_base.h"
 #include "chrome/browser/ui/views/payments/payment_request_dialog_view_ids.h"
-#include "chrome/browser/ui/views/payments/payment_request_interactive_uitest_base.h"
 #include "components/autofill/core/browser/autofill_profile.h"
 #include "components/autofill/core/browser/autofill_test_utils.h"
 #include "components/autofill/core/browser/credit_card.h"
@@ -16,10 +16,10 @@
 // A simple PaymentRequest which simply requests 'visa' or 'mastercard' and
 // nothing else.
 class PaymentSheetViewControllerNoShippingTest
-    : public PaymentRequestInteractiveTestBase {
+    : public PaymentRequestBrowserTestBase {
  protected:
   PaymentSheetViewControllerNoShippingTest()
-      : PaymentRequestInteractiveTestBase(
+      : PaymentRequestBrowserTestBase(
             "/payment_request_no_shipping_test.html") {}
 
  private:
@@ -70,10 +70,10 @@
 
 // Accepts 'visa' cards and requests the full contact details.
 class PaymentSheetViewControllerContactDetailsTest
-    : public PaymentRequestInteractiveTestBase {
+    : public PaymentRequestBrowserTestBase {
  protected:
   PaymentSheetViewControllerContactDetailsTest()
-      : PaymentRequestInteractiveTestBase(
+      : PaymentRequestBrowserTestBase(
             "/payment_request_contact_details_and_free_shipping_test.html") {}
 
  private:
diff --git a/chrome/browser/ui/views/payments/view_stack.h b/chrome/browser/ui/views/payments/view_stack.h
index 3699ef29..8b941041 100644
--- a/chrome/browser/ui/views/payments/view_stack.h
+++ b/chrome/browser/ui/views/payments/view_stack.h
@@ -10,7 +10,7 @@
 #include "ui/views/animation/bounds_animator_observer.h"
 
 namespace payments {
-class PaymentRequestInteractiveTestBase;
+class PaymentRequestBrowserTestBase;
 }  // namespace payments
 
 // This view represents a stack of views that slide in over one another from
@@ -47,7 +47,7 @@
   FRIEND_TEST_ALL_PREFIXES(ViewStackTest, TestPushStateAddsViewToChildren);
   FRIEND_TEST_ALL_PREFIXES(ViewStackTest, TestLayoutUpdatesAnimations);
   friend class ViewStackTest;
-  friend class payments::PaymentRequestInteractiveTestBase;
+  friend class payments::PaymentRequestBrowserTestBase;
 
   // Returns the top state of the stack, used in tests.
   views::View* top() { return stack_.back().get(); }
diff --git a/chrome/browser/ui/webui/app_launcher_login_handler.cc b/chrome/browser/ui/webui/app_launcher_login_handler.cc
index 25ea3be0..ee7a3f2 100644
--- a/chrome/browser/ui/webui/app_launcher_login_handler.cc
+++ b/chrome/browser/ui/webui/app_launcher_login_handler.cc
@@ -220,9 +220,9 @@
 #endif
   }
 
-  base::StringValue header_value(header);
-  base::StringValue sub_header_value(sub_header);
-  base::StringValue icon_url_value(icon_url);
+  base::Value header_value(header);
+  base::Value sub_header_value(sub_header);
+  base::Value icon_url_value(icon_url);
   base::Value is_user_signed_in(!username.empty());
   web_ui()->CallJavascriptFunctionUnsafe("ntp.updateLogin", header_value,
                                          sub_header_value, icon_url_value,
diff --git a/chrome/browser/ui/webui/bidi_checker_web_ui_test.cc b/chrome/browser/ui/webui/bidi_checker_web_ui_test.cc
index b4d9e47..3617800 100644
--- a/chrome/browser/ui/webui/bidi_checker_web_ui_test.cc
+++ b/chrome/browser/ui/webui/bidi_checker_web_ui_test.cc
@@ -103,8 +103,7 @@
 void WebUIBidiCheckerBrowserTest::RunBidiCheckerOnPage(
     const std::string& page_url, bool is_rtl) {
   ui_test_utils::NavigateToURL(browser(), GURL(page_url));
-  ASSERT_TRUE(RunJavascriptTest("runBidiChecker",
-                                new base::StringValue(page_url),
+  ASSERT_TRUE(RunJavascriptTest("runBidiChecker", new base::Value(page_url),
                                 new base::Value(is_rtl)));
 }
 
diff --git a/chrome/browser/ui/webui/chromeos/cryptohome_web_ui_handler.cc b/chrome/browser/ui/webui/chromeos/cryptohome_web_ui_handler.cc
index 87027399..0a7d931 100644
--- a/chrome/browser/ui/webui/chromeos/cryptohome_web_ui_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/cryptohome_web_ui_handler.cc
@@ -76,7 +76,7 @@
 void CryptohomeWebUIHandler::SetCryptohomeProperty(
     const std::string& destination_id,
     const base::Value& value) {
-  base::StringValue destination_id_value(destination_id);
+  base::Value destination_id_value(destination_id);
   web_ui()->CallJavascriptFunctionUnsafe("SetCryptohomeProperty",
                                          destination_id_value, value);
 }
diff --git a/chrome/browser/ui/webui/chromeos/drive_internals_ui.cc b/chrome/browser/ui/webui/chromeos/drive_internals_ui.cc
index 6c2ee6e5..37156b8 100644
--- a/chrome/browser/ui/webui/chromeos/drive_internals_ui.cc
+++ b/chrome/browser/ui/webui/chromeos/drive_internals_ui.cc
@@ -811,7 +811,7 @@
 
   if (error == drive::FILE_ERROR_OK) {
     DCHECK(entry.get());
-    const base::StringValue value(FormatEntry(path, *entry) + "\n");
+    const base::Value value(FormatEntry(path, *entry) + "\n");
     web_ui()->CallJavascriptFunctionUnsafe("updateFileSystemContents", value);
   }
 }
@@ -846,7 +846,7 @@
     // There may be pending ReadDirectoryByPath() calls, but we can update
     // the page with what we have now. This results in progressive
     // updates, which is good for a large file system.
-    const base::StringValue value(file_system_as_text);
+    const base::Value value(file_system_as_text);
     web_ui()->CallJavascriptFunctionUnsafe("updateFileSystemContents", value);
   }
 }
diff --git a/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.cc b/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.cc
index b356b01c..2b9c755f 100644
--- a/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.cc
@@ -123,8 +123,7 @@
   const std::string& property_name) {
   if (property_name == kPairedPropertyName) {
     owner_->web_ui()->CallJavascriptFunctionUnsafe(
-        kDevicePairedFromTrayJSCallback,
-        base::StringValue(object_path.value()));
+        kDevicePairedFromTrayJSCallback, base::Value(object_path.value()));
   }
 }
 
@@ -132,7 +131,7 @@
     const dbus::ObjectPath& object_path) {
   owner_->web_ui()->CallJavascriptFunctionUnsafe(
       kDeviceRemovedFromMainAdapterJSCallback,
-      base::StringValue(object_path.value()));
+      base::Value(object_path.value()));
 }
 
 class DeviceEmulatorMessageHandler::CrasAudioObserver
@@ -292,7 +291,7 @@
       props->address.value());
   if (!props->paired.value()) {
     web_ui()->CallJavascriptFunctionUnsafe(kPairFailedJSCallback,
-                                           base::StringValue(path));
+                                           base::Value(path));
   }
 }
 
diff --git a/chrome/browser/ui/webui/chromeos/first_run/first_run_handler.cc b/chrome/browser/ui/webui/chromeos/first_run/first_run_handler.cc
index 282c552f..fc01881 100644
--- a/chrome/browser/ui/webui/chromeos/first_run/first_run_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/first_run/first_run_handler.cc
@@ -43,7 +43,7 @@
 void FirstRunHandler::ShowStepPositioned(const std::string& name,
                                          const StepPosition& position) {
   web_ui()->CallJavascriptFunctionUnsafe(
-      "cr.FirstRun.showStep", base::StringValue(name), *position.AsValue());
+      "cr.FirstRun.showStep", base::Value(name), *position.AsValue());
 }
 
 void FirstRunHandler::ShowStepPointingTo(const std::string& name,
@@ -55,9 +55,8 @@
   point_with_offset.AppendInteger(x);
   point_with_offset.AppendInteger(y);
   point_with_offset.AppendInteger(offset);
-  web_ui()->CallJavascriptFunctionUnsafe("cr.FirstRun.showStep",
-                                         base::StringValue(name), *null,
-                                         point_with_offset);
+  web_ui()->CallJavascriptFunctionUnsafe(
+      "cr.FirstRun.showStep", base::Value(name), *null, point_with_offset);
 }
 
 void FirstRunHandler::HideCurrentStep() {
diff --git a/chrome/browser/ui/webui/chromeos/keyboard_overlay_ui.cc b/chrome/browser/ui/webui/chromeos/keyboard_overlay_ui.cc
index 26c0a3f..d47d282 100644
--- a/chrome/browser/ui/webui/chromeos/keyboard_overlay_ui.cc
+++ b/chrome/browser/ui/webui/chromeos/keyboard_overlay_ui.cc
@@ -380,7 +380,7 @@
       chromeos::input_method::InputMethodManager::Get();
   const chromeos::input_method::InputMethodDescriptor& descriptor =
       manager->GetActiveIMEState()->GetCurrentInputMethod();
-  base::StringValue param(descriptor.id());
+  base::Value param(descriptor.id());
   web_ui()->CallJavascriptFunctionUnsafe("initKeyboardOverlayId", param);
 }
 
diff --git a/chrome/browser/ui/webui/chromeos/login/app_launch_splash_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/app_launch_splash_screen_handler.cc
index 5dcdd4fc..865ceac 100644
--- a/chrome/browser/ui/webui/chromeos/login/app_launch_splash_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/app_launch_splash_screen_handler.cc
@@ -39,7 +39,8 @@
 AppLaunchSplashScreenHandler::AppLaunchSplashScreenHandler(
     const scoped_refptr<NetworkStateInformer>& network_state_informer,
     ErrorScreen* error_screen)
-    : network_state_informer_(network_state_informer),
+    : BaseScreenHandler(kScreenId),
+      network_state_informer_(network_state_informer),
       error_screen_(error_screen) {
   set_call_js_prefix(kJsScreenPath);
   network_state_informer_->AddObserver(this);
@@ -90,7 +91,7 @@
   data.Set("appInfo", app_info);
 
   SetLaunchText(l10n_util::GetStringUTF8(GetProgressMessageFromState(state_)));
-  ShowScreenWithData(OobeScreen::SCREEN_APP_LAUNCH_SPLASH, &data);
+  ShowScreenWithData(kScreenId, &data);
 }
 
 void AppLaunchSplashScreenHandler::RegisterMessages() {
@@ -176,7 +177,7 @@
   }
 
   if (GetCurrentScreen() != OobeScreen::SCREEN_ERROR_MESSAGE)
-    error_screen_->SetParentScreen(OobeScreen::SCREEN_APP_LAUNCH_SPLASH);
+    error_screen_->SetParentScreen(kScreenId);
   error_screen_->Show();
 }
 
diff --git a/chrome/browser/ui/webui/chromeos/login/arc_kiosk_splash_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/arc_kiosk_splash_screen_handler.cc
index 6533113..6b1ae2fd 100644
--- a/chrome/browser/ui/webui/chromeos/login/arc_kiosk_splash_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/arc_kiosk_splash_screen_handler.cc
@@ -24,7 +24,8 @@
 
 namespace chromeos {
 
-ArcKioskSplashScreenHandler::ArcKioskSplashScreenHandler() {
+ArcKioskSplashScreenHandler::ArcKioskSplashScreenHandler()
+    : BaseScreenHandler(kScreenId) {
   set_call_js_prefix(kJsScreenPath);
 }
 
@@ -61,7 +62,7 @@
       base::MakeUnique<base::DictionaryValue>();
   PopulateAppInfo(app_info.get());
   data.Set("appInfo", std::move(app_info));
-  ShowScreenWithData(OobeScreen::SCREEN_ARC_KIOSK_SPLASH, &data);
+  ShowScreenWithData(kScreenId, &data);
 }
 
 void ArcKioskSplashScreenHandler::RegisterMessages() {
diff --git a/chrome/browser/ui/webui/chromeos/login/arc_terms_of_service_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/arc_terms_of_service_screen_handler.cc
index 9622daf..2acd08b 100644
--- a/chrome/browser/ui/webui/chromeos/login/arc_terms_of_service_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/arc_terms_of_service_screen_handler.cc
@@ -26,7 +26,8 @@
 
 namespace chromeos {
 
-ArcTermsOfServiceScreenHandler::ArcTermsOfServiceScreenHandler() {
+ArcTermsOfServiceScreenHandler::ArcTermsOfServiceScreenHandler()
+    : BaseScreenHandler(kScreenId) {
   set_call_js_prefix(kJsScreenPath);
 }
 
@@ -159,7 +160,7 @@
 
   system::TimezoneSettings::GetInstance()->AddObserver(this);
 
-  ShowScreen(OobeScreen::SCREEN_ARC_TERMS_OF_SERVICE);
+  ShowScreen(kScreenId);
 
   UpdateTimeZone();
   pref_handler_.reset(new arc::ArcOptInPreferenceHandler(
diff --git a/chrome/browser/ui/webui/chromeos/login/auto_enrollment_check_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/auto_enrollment_check_screen_handler.cc
index 4c03bd98fd..0c3ce2c 100644
--- a/chrome/browser/ui/webui/chromeos/login/auto_enrollment_check_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/auto_enrollment_check_screen_handler.cc
@@ -16,7 +16,8 @@
 
 namespace chromeos {
 
-AutoEnrollmentCheckScreenHandler::AutoEnrollmentCheckScreenHandler() {
+AutoEnrollmentCheckScreenHandler::AutoEnrollmentCheckScreenHandler()
+    : BaseScreenHandler(kScreenId) {
   set_call_js_prefix(kJsScreenPath);
 }
 
@@ -30,7 +31,7 @@
     show_on_init_ = true;
     return;
   }
-  ShowScreen(OobeScreen::SCREEN_AUTO_ENROLLMENT_CHECK);
+  ShowScreen(kScreenId);
 }
 
 void AutoEnrollmentCheckScreenHandler::SetDelegate(Delegate* delegate) {
diff --git a/chrome/browser/ui/webui/chromeos/login/base_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/base_screen_handler.cc
index 56759473..8588ac9b 100644
--- a/chrome/browser/ui/webui/chromeos/login/base_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/base_screen_handler.cc
@@ -4,136 +4,11 @@
 
 #include "chrome/browser/ui/webui/chromeos/login/base_screen_handler.h"
 
-#include "base/logging.h"
-#include "base/memory/ptr_util.h"
-#include "base/values.h"
-#include "chrome/browser/chromeos/login/screens/base_screen.h"
-#include "chrome/browser/chromeos/login/ui/login_display_host.h"
-#include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
-#include "components/login/localized_values_builder.h"
-#include "content/public/browser/web_ui.h"
-
 namespace chromeos {
 
-namespace {
-const char kMethodContextChanged[] = "contextChanged";
-}  // namespace
+BaseScreenHandler::BaseScreenHandler(OobeScreen oobe_screen)
+    : oobe_screen_(oobe_screen) {}
 
-JSCallsContainer::JSCallsContainer() = default;
-
-JSCallsContainer::~JSCallsContainer() = default;
-
-BaseScreenHandler::BaseScreenHandler() = default;
-
-BaseScreenHandler::BaseScreenHandler(JSCallsContainer* js_calls_container)
-    : js_calls_container_(js_calls_container) {}
-
-BaseScreenHandler::~BaseScreenHandler() {
-  if (base_screen_)
-    base_screen_->set_model_view_channel(nullptr);
-}
-
-void BaseScreenHandler::InitializeBase() {
-  page_is_ready_ = true;
-  Initialize();
-  if (!pending_context_changes_.empty()) {
-    CommitContextChanges(pending_context_changes_);
-    pending_context_changes_.Clear();
-  }
-}
-
-void BaseScreenHandler::GetLocalizedStrings(base::DictionaryValue* dict) {
-  auto builder = base::MakeUnique<::login::LocalizedValuesBuilder>(dict);
-  DeclareLocalizedValues(builder.get());
-  GetAdditionalParameters(dict);
-}
-
-void BaseScreenHandler::RegisterMessages() {
-  AddPrefixedCallback("userActed",
-                      &BaseScreenHandler::HandleUserAction);
-  AddPrefixedCallback("contextChanged",
-                      &BaseScreenHandler::HandleContextChanged);
-  DeclareJSCallbacks();
-}
-
-void BaseScreenHandler::CommitContextChanges(
-    const base::DictionaryValue& diff) {
-  if (!page_is_ready())
-    pending_context_changes_.MergeDictionary(&diff);
-  else
-    CallJS(kMethodContextChanged, diff);
-}
-
-void BaseScreenHandler::GetAdditionalParameters(base::DictionaryValue* dict) {
-}
-
-void BaseScreenHandler::CallJS(const std::string& method) {
-  web_ui()->CallJavascriptFunctionUnsafe(FullMethodPath(method));
-}
-
-void BaseScreenHandler::ShowScreen(OobeScreen screen) {
-  ShowScreenWithData(screen, nullptr);
-}
-
-void BaseScreenHandler::ShowScreenWithData(OobeScreen screen,
-                                           const base::DictionaryValue* data) {
-  if (!web_ui())
-    return;
-  base::DictionaryValue screen_params;
-  screen_params.SetString("id", GetOobeScreenName(screen));
-  if (data)
-    screen_params.SetWithoutPathExpansion("data", data->DeepCopy());
-  web_ui()->CallJavascriptFunctionUnsafe("cr.ui.Oobe.showScreen",
-                                         screen_params);
-}
-
-OobeUI* BaseScreenHandler::GetOobeUI() const {
-  return static_cast<OobeUI*>(web_ui()->GetController());
-}
-
-OobeScreen BaseScreenHandler::GetCurrentScreen() const {
-  OobeUI* oobe_ui = GetOobeUI();
-  if (!oobe_ui)
-    return OobeScreen::SCREEN_UNKNOWN;
-  return oobe_ui->current_screen();
-}
-
-gfx::NativeWindow BaseScreenHandler::GetNativeWindow() {
-  return LoginDisplayHost::default_host()->GetNativeWindow();
-}
-
-void BaseScreenHandler::SetBaseScreen(BaseScreen* base_screen) {
-  if (base_screen_ == base_screen)
-    return;
-  if (base_screen_)
-    base_screen_->set_model_view_channel(nullptr);
-  base_screen_ = base_screen;
-  if (base_screen_)
-    base_screen_->set_model_view_channel(this);
-}
-
-std::string BaseScreenHandler::FullMethodPath(const std::string& method) const {
-  DCHECK(!method.empty());
-  return js_screen_path_prefix_ + method;
-}
-
-void BaseScreenHandler::HandleUserAction(const std::string& action_id) {
-  if (base_screen_)
-    base_screen_->OnUserAction(action_id);
-}
-
-void BaseScreenHandler::HandleContextChanged(
-    const base::DictionaryValue* diff) {
-  if (diff && base_screen_)
-    base_screen_->OnContextChanged(*diff);
-}
-
-void BaseScreenHandler::ExecuteDeferredJSCalls() {
-  DCHECK(!js_calls_container_->is_initialized());
-  js_calls_container_->mark_initialized();
-  for (const auto& deferred_js_call : js_calls_container_->deferred_js_calls())
-    deferred_js_call.Run();
-  js_calls_container_->deferred_js_calls().clear();
-}
+BaseScreenHandler::~BaseScreenHandler() {}
 
 }  // namespace chromeos
diff --git a/chrome/browser/ui/webui/chromeos/login/base_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/base_screen_handler.h
index 1fae31a..05916e7 100644
--- a/chrome/browser/ui/webui/chromeos/login/base_screen_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/base_screen_handler.h
@@ -5,261 +5,24 @@
 #ifndef CHROME_BROWSER_UI_WEBUI_CHROMEOS_LOGIN_BASE_SCREEN_HANDLER_H_
 #define CHROME_BROWSER_UI_WEBUI_CHROMEOS_LOGIN_BASE_SCREEN_HANDLER_H_
 
-#include <string>
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/callback.h"
 #include "base/macros.h"
 #include "chrome/browser/chromeos/login/oobe_screen.h"
-#include "chrome/browser/chromeos/login/screens/model_view_channel.h"
-#include "components/login/base_screen_handler_utils.h"
-#include "content/public/browser/web_ui.h"
-#include "content/public/browser/web_ui_message_handler.h"
-#include "ui/gfx/native_widget_types.h"
-
-namespace base {
-class DictionaryValue;
-class ListValue;
-}
-
-namespace login {
-class LocalizedValuesBuilder;
-}
+#include "chrome/browser/ui/webui/chromeos/login/base_webui_handler.h"
 
 namespace chromeos {
 
-class BaseScreen;
-class OobeUI;
-
-// A helper class to store deferred Javascript calls, shared by subclasses of
-// BaseScreenHandler.
-class JSCallsContainer {
+// Base class for the OOBE/Login WebUI handlers which provide methods specific
+// to a particular OobeScreen.
+class BaseScreenHandler : public BaseWebUIHandler {
  public:
-  JSCallsContainer();
-  ~JSCallsContainer();
-
-  // Used to decide whether the JS call should be deferred.
-  bool is_initialized() { return is_initialized_; }
-
-  // Used to mark the instance as intialized.
-  void mark_initialized() { is_initialized_ = true; }
-
-  // Used to add deferred calls to.
-  std::vector<base::Closure>& deferred_js_calls() { return deferred_js_calls_; }
-
- private:
-  // Whether the instance is initialized.
-  //
-  // The instance becomes initialized after the corresponding message is
-  // received from Javascript side.
-  bool is_initialized_ = false;
-
-  // Javascript calls that have been deferred while the instance was not
-  // initialized yet.
-  std::vector<base::Closure> deferred_js_calls_;
-};
-
-// Base class for the OOBE/Login WebUI handlers.
-class BaseScreenHandler : public content::WebUIMessageHandler,
-                          public ModelViewChannel {
- public:
-  BaseScreenHandler();
-  explicit BaseScreenHandler(JSCallsContainer* js_calls_container);
+  explicit BaseScreenHandler(OobeScreen oobe_screen);
   ~BaseScreenHandler() override;
 
-  // Gets localized strings to be used on the page.
-  void GetLocalizedStrings(
-      base::DictionaryValue* localized_strings);
-
-  // WebUIMessageHandler implementation:
-  void RegisterMessages() override;
-
-  // ModelViewChannel implementation:
-  void CommitContextChanges(const base::DictionaryValue& diff) override;
-
-  // This method is called when page is ready. It propagates to inherited class
-  // via virtual Initialize() method (see below).
-  void InitializeBase();
-
-  void set_async_assets_load_id(const std::string& async_assets_load_id) {
-    async_assets_load_id_ = async_assets_load_id;
-  }
-  const std::string& async_assets_load_id() const {
-    return async_assets_load_id_;
-  }
-
-  // Set the prefix used when running CallJs with a method. For example,
-  //    set_call_js_prefix("Oobe")
-  //    CallJs("lock") -> Invokes JS global named "Oobe.lock"
-  void set_call_js_prefix(const std::string& prefix) {
-    js_screen_path_prefix_ = prefix + ".";
-  }
-
- protected:
-  // All subclasses should implement this method to provide localized values.
-  virtual void DeclareLocalizedValues(
-      ::login::LocalizedValuesBuilder* builder) = 0;
-
-  // All subclasses should implement this method to register callbacks for JS
-  // messages.
-  //
-  // TODO (ygorshenin, crbug.com/433797): make this method purely vrtual when
-  // all screens will be switched to use ScreenContext.
-  virtual void DeclareJSCallbacks() {}
-
-  // Subclasses can override these methods to pass additional parameters
-  // to loadTimeData. Generally, it is a bad approach, and it should be replaced
-  // with Context at some point.
-  virtual void GetAdditionalParameters(base::DictionaryValue* parameters);
-
-  // Shortcut for calling JS methods on WebUI side.
-  void CallJS(const std::string& method);
-
-  template<typename A1>
-  void CallJS(const std::string& method, const A1& arg1) {
-    web_ui()->CallJavascriptFunctionUnsafe(FullMethodPath(method),
-                                           ::login::MakeValue(arg1));
-  }
-
-  template<typename A1, typename A2>
-  void CallJS(const std::string& method, const A1& arg1, const A2& arg2) {
-    web_ui()->CallJavascriptFunctionUnsafe(FullMethodPath(method),
-                                           ::login::MakeValue(arg1),
-                                           ::login::MakeValue(arg2));
-  }
-
-  template<typename A1, typename A2, typename A3>
-  void CallJS(const std::string& method,
-              const A1& arg1,
-              const A2& arg2,
-              const A3& arg3) {
-    web_ui()->CallJavascriptFunctionUnsafe(
-        FullMethodPath(method), ::login::MakeValue(arg1),
-        ::login::MakeValue(arg2), ::login::MakeValue(arg3));
-  }
-
-  template<typename A1, typename A2, typename A3, typename A4>
-  void CallJS(const std::string& method,
-              const A1& arg1,
-              const A2& arg2,
-              const A3& arg3,
-              const A4& arg4) {
-    web_ui()->CallJavascriptFunctionUnsafe(
-        FullMethodPath(method), ::login::MakeValue(arg1),
-        ::login::MakeValue(arg2), ::login::MakeValue(arg3),
-        ::login::MakeValue(arg4));
-  }
-
-  template <typename... Args>
-  void CallJSOrDefer(const std::string& function_name, const Args&... args) {
-    DCHECK(js_calls_container_);
-    if (js_calls_container_->is_initialized()) {
-      CallJS(function_name, args...);
-    } else {
-      // Note that std::conditional is used here in order to obtain a sequence
-      // of base::Value types with the length equal to sizeof...(Args); the C++
-      // template parameter pack expansion rules require that the name of the
-      // parameter pack appears in the pattern, even though the elements of the
-      // Args pack are not actually in this code.
-      js_calls_container_->deferred_js_calls().push_back(base::Bind(
-          &BaseScreenHandler::ExecuteDeferredJSCall<
-              typename std::conditional<true, base::Value, Args>::type...>,
-          base::Unretained(this), function_name,
-          base::Passed(::login::MakeValue(args).CreateDeepCopy())...));
-    }
-  }
-
-  // Executes Javascript calls that were deferred while the instance was not
-  // initialized yet.
-  void ExecuteDeferredJSCalls();
-
-  // Shortcut methods for adding WebUI callbacks.
-  template<typename T>
-  void AddRawCallback(const std::string& name,
-                      void (T::*method)(const base::ListValue* args)) {
-    web_ui()->RegisterMessageCallback(
-        name,
-        base::Bind(method, base::Unretained(static_cast<T*>(this))));
-  }
-
-  template<typename T, typename... Args>
-  void AddCallback(const std::string& name, void (T::*method)(Args...)) {
-    base::Callback<void(Args...)> callback =
-        base::Bind(method, base::Unretained(static_cast<T*>(this)));
-    web_ui()->RegisterMessageCallback(
-        name, base::Bind(&::login::CallbackWrapper<Args...>, callback));
-  }
-
-  template <typename Method>
-  void AddPrefixedCallback(const std::string& unprefixed_name,
-                           const Method& method) {
-    AddCallback(FullMethodPath(unprefixed_name), method);
-  }
-
-  // Called when the page is ready and handler can do initialization.
-  virtual void Initialize() = 0;
-
-  // Show selected WebUI |screen|.
-  void ShowScreen(OobeScreen screen);
-  // Show selected WebUI |screen|. Pass screen initialization using the |data|
-  // parameter.
-  void ShowScreenWithData(OobeScreen screen, const base::DictionaryValue* data);
-
-  // Returns the OobeUI instance.
-  OobeUI* GetOobeUI() const;
-
-  // Returns current visible OOBE screen.
-  OobeScreen GetCurrentScreen() const;
-
-  // Whether page is ready.
-  bool page_is_ready() const { return page_is_ready_; }
-
-  // Returns the window which shows us.
-  virtual gfx::NativeWindow GetNativeWindow();
-
-  void SetBaseScreen(BaseScreen* base_screen);
+  OobeScreen oobe_screen() const { return oobe_screen_; }
 
  private:
-  // Calls Javascript method.
-  //
-  // Note that the Args template parameter pack should consist of types
-  // convertible to base::Value.
-  template <typename... Args>
-  void ExecuteDeferredJSCall(const std::string& function_name,
-                             std::unique_ptr<Args>... args) {
-    CallJS(function_name, *args...);
-  }
-
-  // Returns full name of JS method based on screen and method
-  // names.
-  std::string FullMethodPath(const std::string& method) const;
-
-  // Handles user action.
-  void HandleUserAction(const std::string& action_id);
-
-  // Handles situation when screen context is changed.
-  void HandleContextChanged(const base::DictionaryValue* diff);
-
-  // Keeps whether page is ready.
-  bool page_is_ready_ = false;
-
-  BaseScreen* base_screen_ = nullptr;
-
-  // Full name of the corresponding JS screen object. Can be empty, if
-  // there are no corresponding screen object or several different
-  // objects.
-  std::string js_screen_path_prefix_;
-
-  // The string id used in the async asset load in JS. If it is set to a
-  // non empty value, the Initialize will be deferred until the underlying load
-  // is finished.
-  std::string async_assets_load_id_;
-
-  // Pending changes to context which will be sent when the page will be ready.
-  base::DictionaryValue pending_context_changes_;
-
-  JSCallsContainer* js_calls_container_ = nullptr;  // non-owning pointers.
+  // OobeScreen that this handler corresponds to.
+  OobeScreen oobe_screen_ = OobeScreen::SCREEN_UNKNOWN;
 
   DISALLOW_COPY_AND_ASSIGN(BaseScreenHandler);
 };
diff --git a/chrome/browser/ui/webui/chromeos/login/base_webui_handler.cc b/chrome/browser/ui/webui/chromeos/login/base_webui_handler.cc
new file mode 100644
index 0000000..3bae474c
--- /dev/null
+++ b/chrome/browser/ui/webui/chromeos/login/base_webui_handler.cc
@@ -0,0 +1,135 @@
+// Copyright 2017 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 "chrome/browser/ui/webui/chromeos/login/base_webui_handler.h"
+
+#include "base/logging.h"
+#include "base/memory/ptr_util.h"
+#include "base/values.h"
+#include "chrome/browser/chromeos/login/screens/base_screen.h"
+#include "chrome/browser/chromeos/login/ui/login_display_host.h"
+#include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
+#include "components/login/localized_values_builder.h"
+#include "content/public/browser/web_ui.h"
+
+namespace chromeos {
+
+namespace {
+const char kMethodContextChanged[] = "contextChanged";
+}  // namespace
+
+JSCallsContainer::JSCallsContainer() = default;
+
+JSCallsContainer::~JSCallsContainer() = default;
+
+BaseWebUIHandler::BaseWebUIHandler() = default;
+
+BaseWebUIHandler::BaseWebUIHandler(JSCallsContainer* js_calls_container)
+    : js_calls_container_(js_calls_container) {}
+
+BaseWebUIHandler::~BaseWebUIHandler() {
+  if (base_screen_)
+    base_screen_->set_model_view_channel(nullptr);
+}
+
+void BaseWebUIHandler::InitializeBase() {
+  page_is_ready_ = true;
+  Initialize();
+  if (!pending_context_changes_.empty()) {
+    CommitContextChanges(pending_context_changes_);
+    pending_context_changes_.Clear();
+  }
+}
+
+void BaseWebUIHandler::GetLocalizedStrings(base::DictionaryValue* dict) {
+  auto builder = base::MakeUnique<::login::LocalizedValuesBuilder>(dict);
+  DeclareLocalizedValues(builder.get());
+  GetAdditionalParameters(dict);
+}
+
+void BaseWebUIHandler::RegisterMessages() {
+  AddPrefixedCallback("userActed", &BaseScreenHandler::HandleUserAction);
+  AddPrefixedCallback("contextChanged",
+                      &BaseScreenHandler::HandleContextChanged);
+  DeclareJSCallbacks();
+}
+
+void BaseWebUIHandler::CommitContextChanges(const base::DictionaryValue& diff) {
+  if (!page_is_ready())
+    pending_context_changes_.MergeDictionary(&diff);
+  else
+    CallJS(kMethodContextChanged, diff);
+}
+
+void BaseWebUIHandler::GetAdditionalParameters(base::DictionaryValue* dict) {}
+
+void BaseWebUIHandler::CallJS(const std::string& method) {
+  web_ui()->CallJavascriptFunctionUnsafe(FullMethodPath(method));
+}
+
+void BaseWebUIHandler::ShowScreen(OobeScreen screen) {
+  ShowScreenWithData(screen, nullptr);
+}
+
+void BaseWebUIHandler::ShowScreenWithData(OobeScreen screen,
+                                          const base::DictionaryValue* data) {
+  if (!web_ui())
+    return;
+  base::DictionaryValue screen_params;
+  screen_params.SetString("id", GetOobeScreenName(screen));
+  if (data)
+    screen_params.SetWithoutPathExpansion("data", data->DeepCopy());
+  web_ui()->CallJavascriptFunctionUnsafe("cr.ui.Oobe.showScreen",
+                                         screen_params);
+}
+
+OobeUI* BaseWebUIHandler::GetOobeUI() const {
+  return static_cast<OobeUI*>(web_ui()->GetController());
+}
+
+OobeScreen BaseWebUIHandler::GetCurrentScreen() const {
+  OobeUI* oobe_ui = GetOobeUI();
+  if (!oobe_ui)
+    return OobeScreen::SCREEN_UNKNOWN;
+  return oobe_ui->current_screen();
+}
+
+gfx::NativeWindow BaseWebUIHandler::GetNativeWindow() {
+  return LoginDisplayHost::default_host()->GetNativeWindow();
+}
+
+void BaseWebUIHandler::SetBaseScreen(BaseScreen* base_screen) {
+  if (base_screen_ == base_screen)
+    return;
+  if (base_screen_)
+    base_screen_->set_model_view_channel(nullptr);
+  base_screen_ = base_screen;
+  if (base_screen_)
+    base_screen_->set_model_view_channel(this);
+}
+
+std::string BaseWebUIHandler::FullMethodPath(const std::string& method) const {
+  DCHECK(!method.empty());
+  return js_screen_path_prefix_ + method;
+}
+
+void BaseWebUIHandler::HandleUserAction(const std::string& action_id) {
+  if (base_screen_)
+    base_screen_->OnUserAction(action_id);
+}
+
+void BaseWebUIHandler::HandleContextChanged(const base::DictionaryValue* diff) {
+  if (diff && base_screen_)
+    base_screen_->OnContextChanged(*diff);
+}
+
+void BaseWebUIHandler::ExecuteDeferredJSCalls() {
+  DCHECK(!js_calls_container_->is_initialized());
+  js_calls_container_->mark_initialized();
+  for (const auto& deferred_js_call : js_calls_container_->deferred_js_calls())
+    deferred_js_call.Run();
+  js_calls_container_->deferred_js_calls().clear();
+}
+
+}  // namespace chromeos
diff --git a/chrome/browser/ui/webui/chromeos/login/base_webui_handler.h b/chrome/browser/ui/webui/chromeos/login/base_webui_handler.h
new file mode 100644
index 0000000..aae5b26
--- /dev/null
+++ b/chrome/browser/ui/webui/chromeos/login/base_webui_handler.h
@@ -0,0 +1,274 @@
+// Copyright 2017 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 CHROME_BROWSER_UI_WEBUI_CHROMEOS_LOGIN_BASE_WEBUI_HANDLER_H_
+#define CHROME_BROWSER_UI_WEBUI_CHROMEOS_LOGIN_BASE_WEBUI_HANDLER_H_
+
+#include <string>
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/callback.h"
+#include "base/macros.h"
+#include "chrome/browser/chromeos/login/oobe_screen.h"
+#include "chrome/browser/chromeos/login/screens/model_view_channel.h"
+#include "components/login/base_screen_handler_utils.h"
+#include "content/public/browser/web_ui.h"
+#include "content/public/browser/web_ui_message_handler.h"
+#include "ui/gfx/native_widget_types.h"
+
+namespace base {
+class DictionaryValue;
+class ListValue;
+}
+
+namespace login {
+class LocalizedValuesBuilder;
+}
+
+namespace chromeos {
+
+class BaseScreen;
+class OobeUI;
+
+// A helper class to store deferred Javascript calls, shared by subclasses of
+// BaseWebUIHandler.
+class JSCallsContainer {
+ public:
+  JSCallsContainer();
+  ~JSCallsContainer();
+
+  // Used to decide whether the JS call should be deferred.
+  bool is_initialized() { return is_initialized_; }
+
+  // Used to mark the instance as intialized.
+  void mark_initialized() { is_initialized_ = true; }
+
+  // Used to add deferred calls to.
+  std::vector<base::Closure>& deferred_js_calls() { return deferred_js_calls_; }
+
+ private:
+  // Whether the instance is initialized.
+  //
+  // The instance becomes initialized after the corresponding message is
+  // received from Javascript side.
+  bool is_initialized_ = false;
+
+  // Javascript calls that have been deferred while the instance was not
+  // initialized yet.
+  std::vector<base::Closure> deferred_js_calls_;
+};
+
+// Base class for all oobe/login WebUI handlers. These handlers are the binding
+// layer that allow the C++ and JavaScript code to communicate.
+//
+// If the deriving type is associated with a specific OobeScreen, it should
+// derive from BaseScreenHandler instead of BaseWebUIHandler.
+//
+// TODO(jdufault): Move all OobeScreen related concepts out of BaseWebUIHandler
+// and into BaseScreenHandler.
+class BaseWebUIHandler : public content::WebUIMessageHandler,
+                         public ModelViewChannel {
+ public:
+  BaseWebUIHandler();
+  explicit BaseWebUIHandler(JSCallsContainer* js_calls_container);
+  ~BaseWebUIHandler() override;
+
+  // Gets localized strings to be used on the page.
+  void GetLocalizedStrings(base::DictionaryValue* localized_strings);
+
+  // WebUIMessageHandler implementation:
+  void RegisterMessages() override;
+
+  // ModelViewChannel implementation:
+  void CommitContextChanges(const base::DictionaryValue& diff) override;
+
+  // This method is called when page is ready. It propagates to inherited class
+  // via virtual Initialize() method (see below).
+  void InitializeBase();
+
+  // Set the prefix used when running CallJs with a method. For example,
+  //    set_call_js_prefix("Oobe")
+  //    CallJs("lock") -> Invokes JS global named "Oobe.lock"
+  void set_call_js_prefix(const std::string& prefix) {
+    js_screen_path_prefix_ = prefix + ".";
+  }
+
+  void set_async_assets_load_id(const std::string& async_assets_load_id) {
+    async_assets_load_id_ = async_assets_load_id;
+  }
+  const std::string& async_assets_load_id() const {
+    return async_assets_load_id_;
+  }
+
+ protected:
+  // All subclasses should implement this method to provide localized values.
+  virtual void DeclareLocalizedValues(
+      ::login::LocalizedValuesBuilder* builder) = 0;
+
+  // All subclasses should implement this method to register callbacks for JS
+  // messages.
+  //
+  // TODO (ygorshenin, crbug.com/433797): make this method purely vrtual when
+  // all screens will be switched to use ScreenContext.
+  virtual void DeclareJSCallbacks() {}
+
+  // Subclasses can override these methods to pass additional parameters
+  // to loadTimeData. Generally, it is a bad approach, and it should be replaced
+  // with Context at some point.
+  virtual void GetAdditionalParameters(base::DictionaryValue* parameters);
+
+  // Shortcut for calling JS methods on WebUI side.
+  void CallJS(const std::string& method);
+
+  template <typename A1>
+  void CallJS(const std::string& method, const A1& arg1) {
+    web_ui()->CallJavascriptFunctionUnsafe(FullMethodPath(method),
+                                           ::login::MakeValue(arg1));
+  }
+
+  template <typename A1, typename A2>
+  void CallJS(const std::string& method, const A1& arg1, const A2& arg2) {
+    web_ui()->CallJavascriptFunctionUnsafe(FullMethodPath(method),
+                                           ::login::MakeValue(arg1),
+                                           ::login::MakeValue(arg2));
+  }
+
+  template <typename A1, typename A2, typename A3>
+  void CallJS(const std::string& method,
+              const A1& arg1,
+              const A2& arg2,
+              const A3& arg3) {
+    web_ui()->CallJavascriptFunctionUnsafe(
+        FullMethodPath(method), ::login::MakeValue(arg1),
+        ::login::MakeValue(arg2), ::login::MakeValue(arg3));
+  }
+
+  template <typename A1, typename A2, typename A3, typename A4>
+  void CallJS(const std::string& method,
+              const A1& arg1,
+              const A2& arg2,
+              const A3& arg3,
+              const A4& arg4) {
+    web_ui()->CallJavascriptFunctionUnsafe(
+        FullMethodPath(method), ::login::MakeValue(arg1),
+        ::login::MakeValue(arg2), ::login::MakeValue(arg3),
+        ::login::MakeValue(arg4));
+  }
+
+  template <typename... Args>
+  void CallJSOrDefer(const std::string& function_name, const Args&... args) {
+    DCHECK(js_calls_container_);
+    if (js_calls_container_->is_initialized()) {
+      CallJS(function_name, args...);
+    } else {
+      // Note that std::conditional is used here in order to obtain a sequence
+      // of base::Value types with the length equal to sizeof...(Args); the C++
+      // template parameter pack expansion rules require that the name of the
+      // parameter pack appears in the pattern, even though the elements of the
+      // Args pack are not actually in this code.
+      js_calls_container_->deferred_js_calls().push_back(base::Bind(
+          &BaseWebUIHandler::ExecuteDeferredJSCall<
+              typename std::conditional<true, base::Value, Args>::type...>,
+          base::Unretained(this), function_name,
+          base::Passed(::login::MakeValue(args).CreateDeepCopy())...));
+    }
+  }
+
+  // Executes Javascript calls that were deferred while the instance was not
+  // initialized yet.
+  void ExecuteDeferredJSCalls();
+
+  // Shortcut methods for adding WebUI callbacks.
+  template <typename T>
+  void AddRawCallback(const std::string& name,
+                      void (T::*method)(const base::ListValue* args)) {
+    web_ui()->RegisterMessageCallback(
+        name, base::Bind(method, base::Unretained(static_cast<T*>(this))));
+  }
+
+  template <typename T, typename... Args>
+  void AddCallback(const std::string& name, void (T::*method)(Args...)) {
+    base::Callback<void(Args...)> callback =
+        base::Bind(method, base::Unretained(static_cast<T*>(this)));
+    web_ui()->RegisterMessageCallback(
+        name, base::Bind(&::login::CallbackWrapper<Args...>, callback));
+  }
+
+  template <typename Method>
+  void AddPrefixedCallback(const std::string& unprefixed_name,
+                           const Method& method) {
+    AddCallback(FullMethodPath(unprefixed_name), method);
+  }
+
+  // Called when the page is ready and handler can do initialization.
+  virtual void Initialize() = 0;
+
+  // Show selected WebUI |screen|.
+  void ShowScreen(OobeScreen screen);
+  // Show selected WebUI |screen|. Pass screen initialization using the |data|
+  // parameter.
+  void ShowScreenWithData(OobeScreen screen, const base::DictionaryValue* data);
+
+  // Returns the OobeUI instance.
+  OobeUI* GetOobeUI() const;
+
+  // Returns current visible OOBE screen.
+  OobeScreen GetCurrentScreen() const;
+
+  // Whether page is ready.
+  bool page_is_ready() const { return page_is_ready_; }
+
+  // Returns the window which shows us.
+  virtual gfx::NativeWindow GetNativeWindow();
+
+  void SetBaseScreen(BaseScreen* base_screen);
+
+ private:
+  // Calls Javascript method.
+  //
+  // Note that the Args template parameter pack should consist of types
+  // convertible to base::Value.
+  template <typename... Args>
+  void ExecuteDeferredJSCall(const std::string& function_name,
+                             std::unique_ptr<Args>... args) {
+    CallJS(function_name, *args...);
+  }
+
+  // Returns full name of JS method based on screen and method
+  // names.
+  std::string FullMethodPath(const std::string& method) const;
+
+  // Handles user action.
+  void HandleUserAction(const std::string& action_id);
+
+  // Handles situation when screen context is changed.
+  void HandleContextChanged(const base::DictionaryValue* diff);
+
+  // Keeps whether page is ready.
+  bool page_is_ready_ = false;
+
+  BaseScreen* base_screen_ = nullptr;
+
+  // Full name of the corresponding JS screen object. Can be empty, if
+  // there are no corresponding screen object or several different
+  // objects.
+  std::string js_screen_path_prefix_;
+
+  // The string id used in the async asset load in JS. If it is set to a
+  // non empty value, the Initialize will be deferred until the underlying load
+  // is finished.
+  std::string async_assets_load_id_;
+
+  // Pending changes to context which will be sent when the page will be ready.
+  base::DictionaryValue pending_context_changes_;
+
+  JSCallsContainer* js_calls_container_ = nullptr;  // non-owning pointers.
+
+  DISALLOW_COPY_AND_ASSIGN(BaseWebUIHandler);
+};
+
+}  // namespace chromeos
+
+#endif  // CHROME_BROWSER_UI_WEBUI_CHROMEOS_LOGIN_BASE_WEBUI_HANDLER_H_
diff --git a/chrome/browser/ui/webui/chromeos/login/controller_pairing_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/controller_pairing_screen_handler.cc
index e77bfc9..a2c7493 100644
--- a/chrome/browser/ui/webui/chromeos/login/controller_pairing_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/controller_pairing_screen_handler.cc
@@ -30,7 +30,8 @@
 
 }  // namespace
 
-ControllerPairingScreenHandler::ControllerPairingScreenHandler() {
+ControllerPairingScreenHandler::ControllerPairingScreenHandler()
+    : BaseScreenHandler(kScreenId) {
   set_call_js_prefix(kJsScreenPath);
 }
 
@@ -150,7 +151,7 @@
     show_on_init_ = true;
     return;
   }
-  ShowScreen(OobeScreen::SCREEN_OOBE_CONTROLLER_PAIRING);
+  ShowScreen(kScreenId);
 }
 
 void ControllerPairingScreenHandler::Hide() {
diff --git a/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc b/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc
index 15d635e1..db15811 100644
--- a/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc
@@ -57,7 +57,7 @@
 // OOBE UI is not visible by default.
 CoreOobeHandler::CoreOobeHandler(OobeUI* oobe_ui,
                                  JSCallsContainer* js_calls_container)
-    : BaseScreenHandler(js_calls_container),
+    : BaseWebUIHandler(js_calls_container),
       oobe_ui_(oobe_ui),
       version_info_updater_(this) {
   DCHECK(js_calls_container);
diff --git a/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.h b/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.h
index 33a11e9..2e53a077 100644
--- a/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.h
@@ -16,7 +16,7 @@
 #include "chrome/browser/chromeos/login/demo_mode/demo_mode_detector.h"
 #include "chrome/browser/chromeos/login/screens/core_oobe_view.h"
 #include "chrome/browser/chromeos/login/version_info_updater.h"
-#include "chrome/browser/ui/webui/chromeos/login/base_screen_handler.h"
+#include "chrome/browser/ui/webui/chromeos/login/base_webui_handler.h"
 #include "ui/events/event_source.h"
 #include "ui/keyboard/scoped_keyboard_disabler.h"
 
@@ -34,7 +34,7 @@
 class OobeUI;
 
 // The core handler for Javascript messages related to the "oobe" view.
-class CoreOobeHandler : public BaseScreenHandler,
+class CoreOobeHandler : public BaseWebUIHandler,
                         public VersionInfoUpdater::Delegate,
                         public CoreOobeView,
                         public ui::EventSource {
diff --git a/chrome/browser/ui/webui/chromeos/login/device_disabled_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/device_disabled_screen_handler.cc
index cc8bc9e..6211c4fd4 100644
--- a/chrome/browser/ui/webui/chromeos/login/device_disabled_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/device_disabled_screen_handler.cc
@@ -17,7 +17,8 @@
 
 namespace chromeos {
 
-DeviceDisabledScreenHandler::DeviceDisabledScreenHandler() {
+DeviceDisabledScreenHandler::DeviceDisabledScreenHandler()
+    : BaseScreenHandler(kScreenId) {
   set_call_js_prefix(kJsScreenPath);
 }
 
@@ -36,7 +37,7 @@
     CallJS("setEnrollmentDomain", delegate_->GetEnrollmentDomain());
     CallJS("setMessage", delegate_->GetMessage());
   }
-  ShowScreen(OobeScreen::SCREEN_DEVICE_DISABLED);
+  ShowScreen(kScreenId);
 }
 
 void DeviceDisabledScreenHandler::Hide() {
diff --git a/chrome/browser/ui/webui/chromeos/login/enable_debugging_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/enable_debugging_screen_handler.cc
index 3d7ed28..e1234fe 100644
--- a/chrome/browser/ui/webui/chromeos/login/enable_debugging_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/enable_debugging_screen_handler.cc
@@ -35,7 +35,7 @@
 namespace chromeos {
 
 EnableDebuggingScreenHandler::EnableDebuggingScreenHandler()
-    : weak_ptr_factory_(this) {
+    : BaseScreenHandler(kScreenId), weak_ptr_factory_(this) {
   set_call_js_prefix(kJsScreenPath);
 }
 
@@ -45,7 +45,7 @@
 }
 
 void EnableDebuggingScreenHandler::ShowWithParams() {
-  ShowScreen(OobeScreen::SCREEN_OOBE_ENABLE_DEBUGGING);
+  ShowScreen(kScreenId);
 
   UpdateUIState(UI_STATE_WAIT);
 
diff --git a/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.cc
index 00ae028..f516642 100644
--- a/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.cc
@@ -123,13 +123,13 @@
 EnrollmentScreenHandler::EnrollmentScreenHandler(
     const scoped_refptr<NetworkStateInformer>& network_state_informer,
     ErrorScreen* error_screen)
-    : network_state_informer_(network_state_informer),
+    : BaseScreenHandler(kScreenId),
+      network_state_informer_(network_state_informer),
       error_screen_(error_screen),
       histogram_helper_(new ErrorScreensHistogramHelper("Enrollment")),
       weak_ptr_factory_(this) {
   set_call_js_prefix(kJsScreenPath);
-  set_async_assets_load_id(
-      GetOobeScreenName(OobeScreen::SCREEN_OOBE_ENROLLMENT));
+  set_async_assets_load_id(GetOobeScreenName(kScreenId));
   DCHECK(network_state_informer_.get());
   DCHECK(error_screen_);
   network_state_informer_->AddObserver(this);
@@ -414,13 +414,12 @@
 }
 
 bool EnrollmentScreenHandler::IsOnEnrollmentScreen() const {
-  return (GetCurrentScreen() == OobeScreen::SCREEN_OOBE_ENROLLMENT);
+  return (GetCurrentScreen() == kScreenId);
 }
 
 bool EnrollmentScreenHandler::IsEnrollmentScreenHiddenByError() const {
   return (GetCurrentScreen() == OobeScreen::SCREEN_ERROR_MESSAGE &&
-          error_screen_->GetParentScreen() ==
-              OobeScreen::SCREEN_OOBE_ENROLLMENT);
+          error_screen_->GetParentScreen() == kScreenId);
 }
 
 void EnrollmentScreenHandler::UpdateState(NetworkError::ErrorReason reason) {
@@ -500,7 +499,7 @@
   if (GetCurrentScreen() != OobeScreen::SCREEN_ERROR_MESSAGE) {
     const std::string network_type = network_state_informer_->network_type();
     error_screen_->SetUIState(NetworkError::UI_STATE_SIGNIN);
-    error_screen_->SetParentScreen(OobeScreen::SCREEN_OOBE_ENROLLMENT);
+    error_screen_->SetParentScreen(kScreenId);
     error_screen_->SetHideCallback(base::Bind(&EnrollmentScreenHandler::DoShow,
                                               weak_ptr_factory_.GetWeakPtr()));
     error_screen_->Show();
diff --git a/chrome/browser/ui/webui/chromeos/login/error_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/error_screen_handler.cc
index 5f0d589..e93b4ddc 100644
--- a/chrome/browser/ui/webui/chromeos/login/error_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/error_screen_handler.cc
@@ -21,7 +21,8 @@
 
 namespace chromeos {
 
-ErrorScreenHandler::ErrorScreenHandler() : weak_ptr_factory_(this) {
+ErrorScreenHandler::ErrorScreenHandler()
+    : BaseScreenHandler(kScreenId), weak_ptr_factory_(this) {
   set_call_js_prefix(kJsScreenPath);
 }
 
@@ -35,7 +36,7 @@
     show_on_init_ = true;
     return;
   }
-  BaseScreenHandler::ShowScreen(OobeScreen::SCREEN_ERROR_MESSAGE);
+  BaseScreenHandler::ShowScreen(kScreenId);
   if (screen_)
     screen_->OnShow();
   showing_ = true;
diff --git a/chrome/browser/ui/webui/chromeos/login/eula_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/eula_screen_handler.cc
index 134245c..a223d46 100644
--- a/chrome/browser/ui/webui/chromeos/login/eula_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/eula_screen_handler.cc
@@ -83,7 +83,7 @@
 namespace chromeos {
 
 EulaScreenHandler::EulaScreenHandler(CoreOobeView* core_oobe_view)
-    : core_oobe_view_(core_oobe_view) {
+    : BaseScreenHandler(kScreenId), core_oobe_view_(core_oobe_view) {
   set_call_js_prefix(kJsScreenPath);
 }
 
@@ -97,7 +97,7 @@
     show_on_init_ = true;
     return;
   }
-  ShowScreen(OobeScreen::SCREEN_OOBE_EULA);
+  ShowScreen(kScreenId);
 }
 
 void EulaScreenHandler::Hide() {
diff --git a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
index 13c9224..d847e257 100644
--- a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
@@ -228,7 +228,8 @@
 GaiaScreenHandler::GaiaScreenHandler(
     CoreOobeView* core_oobe_view,
     const scoped_refptr<NetworkStateInformer>& network_state_informer)
-    : network_state_informer_(network_state_informer),
+    : BaseScreenHandler(kScreenId),
+      network_state_informer_(network_state_informer),
       core_oobe_view_(core_oobe_view),
       weak_factory_(this) {
   DCHECK(network_state_informer_.get());
@@ -461,7 +462,7 @@
   if (offline_login_is_active() ||
       IsOnline(captive_portal_status_) == IsOnline(previous_status) ||
       disable_restrictive_proxy_check_for_test_ ||
-      GetCurrentScreen() != OobeScreen::SCREEN_GAIA_SIGNIN)
+      GetCurrentScreen() != kScreenId)
     return;
 
   LoadAuthExtension(true /* force */, false /* offline */);
diff --git a/chrome/browser/ui/webui/chromeos/login/hid_detection_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/hid_detection_screen_handler.cc
index 1aaa7ec..26b7f92 100644
--- a/chrome/browser/ui/webui/chromeos/login/hid_detection_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/hid_detection_screen_handler.cc
@@ -30,7 +30,7 @@
 
 HIDDetectionScreenHandler::HIDDetectionScreenHandler(
     CoreOobeView* core_oobe_view)
-    : core_oobe_view_(core_oobe_view) {
+    : BaseScreenHandler(kScreenId), core_oobe_view_(core_oobe_view) {
   set_call_js_prefix(kJsScreenPath);
 }
 
@@ -52,7 +52,7 @@
   local_state->SetInteger(prefs::kTimesHIDDialogShown,
                           num_of_times_dialog_was_shown + 1);
 
-  ShowScreen(OobeScreen::SCREEN_OOBE_HID_DETECTION);
+  ShowScreen(kScreenId);
 }
 
 void HIDDetectionScreenHandler::Hide() {
diff --git a/chrome/browser/ui/webui/chromeos/login/host_pairing_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/host_pairing_screen_handler.cc
index 0dc1b55..1f378848 100644
--- a/chrome/browser/ui/webui/chromeos/login/host_pairing_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/host_pairing_screen_handler.cc
@@ -26,7 +26,8 @@
 
 }  // namespace
 
-HostPairingScreenHandler::HostPairingScreenHandler() {
+HostPairingScreenHandler::HostPairingScreenHandler()
+    : BaseScreenHandler(kScreenId) {
   set_call_js_prefix(kJsScreenPath);
 }
 
@@ -95,7 +96,7 @@
     show_on_init_ = true;
     return;
   }
-  ShowScreen(OobeScreen::SCREEN_OOBE_HOST_PAIRING);
+  ShowScreen(kScreenId);
 }
 
 void HostPairingScreenHandler::Hide() {
diff --git a/chrome/browser/ui/webui/chromeos/login/kiosk_app_menu_handler.cc b/chrome/browser/ui/webui/chromeos/login/kiosk_app_menu_handler.cc
index 4e74d7f3..480c624 100644
--- a/chrome/browser/ui/webui/chromeos/login/kiosk_app_menu_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/kiosk_app_menu_handler.cc
@@ -180,7 +180,7 @@
   bool new_kiosk_ui = EnableNewKioskUI();
   web_ui()->CallJavascriptFunctionUnsafe(
       new_kiosk_ui ? kKioskShowErrorNewAPI : kKioskShowErrorOldAPI,
-      base::StringValue(error_message));
+      base::Value(error_message));
 }
 
 void KioskAppMenuHandler::OnKioskAppsSettingsChanged() {
diff --git a/chrome/browser/ui/webui/chromeos/login/kiosk_autolaunch_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/kiosk_autolaunch_screen_handler.cc
index 50d8b97..d2d341d 100644
--- a/chrome/browser/ui/webui/chromeos/login/kiosk_autolaunch_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/kiosk_autolaunch_screen_handler.cc
@@ -32,7 +32,8 @@
 
 namespace chromeos {
 
-KioskAutolaunchScreenHandler::KioskAutolaunchScreenHandler() {
+KioskAutolaunchScreenHandler::KioskAutolaunchScreenHandler()
+    : BaseScreenHandler(kScreenId) {
   set_call_js_prefix(kJsScreenPath);
   KioskAppManager::Get()->AddObserver(this);
 }
@@ -50,7 +51,7 @@
     return;
   }
   UpdateKioskApp();
-  ShowScreen(OobeScreen::SCREEN_KIOSK_AUTOLAUNCH);
+  ShowScreen(kScreenId);
 }
 
 void KioskAutolaunchScreenHandler::SetDelegate(Delegate* delegate) {
diff --git a/chrome/browser/ui/webui/chromeos/login/kiosk_enable_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/kiosk_enable_screen_handler.cc
index f2c86d7..16d9eb7c 100644
--- a/chrome/browser/ui/webui/chromeos/login/kiosk_enable_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/kiosk_enable_screen_handler.cc
@@ -24,7 +24,8 @@
 
 namespace chromeos {
 
-KioskEnableScreenHandler::KioskEnableScreenHandler() : weak_ptr_factory_(this) {
+KioskEnableScreenHandler::KioskEnableScreenHandler()
+    : BaseScreenHandler(kScreenId), weak_ptr_factory_(this) {
   set_call_js_prefix(kJsScreenPath);
 }
 
@@ -54,7 +55,7 @@
     return;
   }
 
-  ShowScreen(OobeScreen::SCREEN_KIOSK_ENABLE);
+  ShowScreen(kScreenId);
 
   content::NotificationService::current()->Notify(
       chrome::NOTIFICATION_KIOSK_ENABLE_WARNING_VISIBLE,
diff --git a/chrome/browser/ui/webui/chromeos/login/network_dropdown.cc b/chrome/browser/ui/webui/chromeos/login/network_dropdown.cc
index 9b6bd696..150cd0c 100644
--- a/chrome/browser/ui/webui/chromeos/login/network_dropdown.cc
+++ b/chrome/browser/ui/webui/chromeos/login/network_dropdown.cc
@@ -200,8 +200,8 @@
   std::string icon_str;
   if (!icon_image.isNull())
     icon_str = webui::GetBitmapDataUrl(icon_bitmap);
-  base::StringValue title(text);
-  base::StringValue icon(icon_str);
+  base::Value title(text);
+  base::Value icon(icon_str);
   web_ui_->CallJavascriptFunctionUnsafe("cr.ui.DropDown.updateNetworkTitle",
                                         title, icon);
 }
diff --git a/chrome/browser/ui/webui/chromeos/login/network_dropdown_handler.h b/chrome/browser/ui/webui/chromeos/login/network_dropdown_handler.h
index 4c0c64a..9e0841d 100644
--- a/chrome/browser/ui/webui/chromeos/login/network_dropdown_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/network_dropdown_handler.h
@@ -10,12 +10,12 @@
 
 #include "base/macros.h"
 #include "base/observer_list.h"
-#include "chrome/browser/ui/webui/chromeos/login/base_screen_handler.h"
+#include "chrome/browser/ui/webui/chromeos/login/base_webui_handler.h"
 #include "chrome/browser/ui/webui/chromeos/login/network_dropdown.h"
 
 namespace chromeos {
 
-class NetworkDropdownHandler : public BaseScreenHandler,
+class NetworkDropdownHandler : public BaseWebUIHandler,
                                public NetworkDropdown::View {
  public:
   class Observer {
diff --git a/chrome/browser/ui/webui/chromeos/login/network_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/network_screen_handler.cc
index 00427f8..e20720e8 100644
--- a/chrome/browser/ui/webui/chromeos/login/network_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/network_screen_handler.cc
@@ -55,7 +55,7 @@
 // NetworkScreenHandler, public: -----------------------------------------------
 
 NetworkScreenHandler::NetworkScreenHandler(CoreOobeView* core_oobe_view)
-    : core_oobe_view_(core_oobe_view) {
+    : BaseScreenHandler(kScreenId), core_oobe_view_(core_oobe_view) {
   set_call_js_prefix(kJsScreenPath);
   DCHECK(core_oobe_view_);
 }
@@ -97,7 +97,7 @@
   network_screen_params.SetBoolean("isDeveloperMode",
       base::CommandLine::ForCurrentProcess()->HasSwitch(
           chromeos::switches::kSystemDevMode));
-  ShowScreenWithData(OobeScreen::SCREEN_OOBE_NETWORK, &network_screen_params);
+  ShowScreenWithData(kScreenId, &network_screen_params);
   core_oobe_view_->InitDemoModeDetection();
 }
 
diff --git a/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc b/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc
index 281702d..84e4b4f 100644
--- a/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc
+++ b/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc
@@ -218,46 +218,27 @@
   auto core_handler =
       base::MakeUnique<CoreOobeHandler>(this, js_calls_container.get());
   core_handler_ = core_handler.get();
-  AddScreenHandler(std::move(core_handler));
+  AddWebUIHandler(std::move(core_handler));
   core_handler_->SetDelegate(this);
 
   auto network_dropdown_handler = base::MakeUnique<NetworkDropdownHandler>();
   network_dropdown_handler_ = network_dropdown_handler.get();
-  AddScreenHandler(std::move(network_dropdown_handler));
+  AddWebUIHandler(std::move(network_dropdown_handler));
 
-  auto update_screen_handler = base::MakeUnique<UpdateScreenHandler>();
-  update_view_ = update_screen_handler.get();
-  AddScreenHandler(std::move(update_screen_handler));
+  AddScreenHandler(base::MakeUnique<UpdateScreenHandler>());
 
-  if (display_type_ == kOobeDisplay) {
-    auto network_screen_handler =
-        base::MakeUnique<NetworkScreenHandler>(core_handler_);
-    network_view_ = network_screen_handler.get();
-    AddScreenHandler(std::move(network_screen_handler));
-  }
+  if (display_type_ == kOobeDisplay)
+    AddScreenHandler(base::MakeUnique<NetworkScreenHandler>(core_handler_));
 
-  auto debugging_screen_handler =
-      base::MakeUnique<EnableDebuggingScreenHandler>();
-  debugging_screen_view_ = debugging_screen_handler.get();
-  AddScreenHandler(std::move(debugging_screen_handler));
+  AddScreenHandler(base::MakeUnique<EnableDebuggingScreenHandler>());
 
-  auto eula_screen_handler = base::MakeUnique<EulaScreenHandler>(core_handler_);
-  eula_view_ = eula_screen_handler.get();
-  AddScreenHandler(std::move(eula_screen_handler));
+  AddScreenHandler(base::MakeUnique<EulaScreenHandler>(core_handler_));
 
-  auto reset_screen_handler = base::MakeUnique<ResetScreenHandler>();
-  reset_view_ = reset_screen_handler.get();
-  AddScreenHandler(std::move(reset_screen_handler));
+  AddScreenHandler(base::MakeUnique<ResetScreenHandler>());
 
-  auto autolaunch_screen_handler =
-      base::MakeUnique<KioskAutolaunchScreenHandler>();
-  autolaunch_screen_view_ = autolaunch_screen_handler.get();
-  AddScreenHandler(std::move(autolaunch_screen_handler));
+  AddScreenHandler(base::MakeUnique<KioskAutolaunchScreenHandler>());
 
-  auto kiosk_enable_screen_handler =
-      base::MakeUnique<KioskEnableScreenHandler>();
-  kiosk_enable_screen_view_ = kiosk_enable_screen_handler.get();
-  AddScreenHandler(std::move(kiosk_enable_screen_handler));
+  AddScreenHandler(base::MakeUnique<KioskEnableScreenHandler>());
 
   auto supervised_user_creation_screen_handler =
       base::MakeUnique<SupervisedUserCreationScreenHandler>();
@@ -265,89 +246,51 @@
       supervised_user_creation_screen_handler.get();
   AddScreenHandler(std::move(supervised_user_creation_screen_handler));
 
-  auto wrong_hwid_screen_handler = base::MakeUnique<WrongHWIDScreenHandler>();
-  wrong_hwid_screen_view_ = wrong_hwid_screen_handler.get();
-  AddScreenHandler(std::move(wrong_hwid_screen_handler));
+  AddScreenHandler(base::MakeUnique<WrongHWIDScreenHandler>());
 
-  auto auto_enrollment_check_screen_handler =
-      base::MakeUnique<AutoEnrollmentCheckScreenHandler>();
-  auto_enrollment_check_screen_view_ =
-      auto_enrollment_check_screen_handler.get();
-  AddScreenHandler(std::move(auto_enrollment_check_screen_handler));
+  AddScreenHandler(base::MakeUnique<AutoEnrollmentCheckScreenHandler>());
 
-  auto hid_detection_screen_handler =
-      base::MakeUnique<HIDDetectionScreenHandler>(core_handler_);
-  hid_detection_view_ = hid_detection_screen_handler.get();
-  AddScreenHandler(std::move(hid_detection_screen_handler));
+  AddScreenHandler(base::MakeUnique<HIDDetectionScreenHandler>(core_handler_));
 
-  auto error_screen_handler = base::MakeUnique<ErrorScreenHandler>();
-  error_screen_handler_ = error_screen_handler.get();
-  AddScreenHandler(std::move(error_screen_handler));
-  network_dropdown_handler_->AddObserver(error_screen_handler_);
+  AddScreenHandler(base::MakeUnique<ErrorScreenHandler>());
+  network_dropdown_handler_->AddObserver(GetView<ErrorScreenHandler>());
 
-  error_screen_.reset(new ErrorScreen(nullptr, error_screen_handler_));
+  error_screen_.reset(new ErrorScreen(nullptr, GetView<ErrorScreenHandler>()));
   ErrorScreen* error_screen = error_screen_.get();
 
-  auto enrollment_screen_handler = base::MakeUnique<EnrollmentScreenHandler>(
-      network_state_informer_, error_screen);
-  enrollment_screen_view_ = enrollment_screen_handler.get();
-  AddScreenHandler(std::move(enrollment_screen_handler));
+  AddScreenHandler(base::MakeUnique<EnrollmentScreenHandler>(
+      network_state_informer_, error_screen));
 
-  auto terms_of_service_screen_handler =
-      base::MakeUnique<TermsOfServiceScreenHandler>(core_handler_);
-  terms_of_service_screen_view_ = terms_of_service_screen_handler.get();
-  AddScreenHandler(std::move(terms_of_service_screen_handler));
+  AddScreenHandler(
+      base::MakeUnique<TermsOfServiceScreenHandler>(core_handler_));
 
-  auto arc_terms_of_service_screen_handler =
-      base::MakeUnique<ArcTermsOfServiceScreenHandler>();
-  arc_terms_of_service_screen_view_ = arc_terms_of_service_screen_handler.get();
-  AddScreenHandler(std::move(arc_terms_of_service_screen_handler));
+  AddScreenHandler(base::MakeUnique<ArcTermsOfServiceScreenHandler>());
 
-  auto user_image_screen_handler = base::MakeUnique<UserImageScreenHandler>();
-  user_image_view_ = user_image_screen_handler.get();
-  AddScreenHandler(std::move(user_image_screen_handler));
+  AddScreenHandler(base::MakeUnique<UserImageScreenHandler>());
 
-  auto user_board_screen_handler = base::MakeUnique<UserBoardScreenHandler>();
-  user_board_screen_handler_ = user_board_screen_handler.get();
-  AddScreenHandler(std::move(user_board_screen_handler));
+  AddScreenHandler(base::MakeUnique<UserBoardScreenHandler>());
 
-  auto gaia_screen_handler = base::MakeUnique<GaiaScreenHandler>(
-      core_handler_, network_state_informer_);
-  gaia_screen_handler_ = gaia_screen_handler.get();
-  AddScreenHandler(std::move(gaia_screen_handler));
+  AddScreenHandler(base::MakeUnique<GaiaScreenHandler>(
+      core_handler_, network_state_informer_));
 
   auto signin_screen_handler = base::MakeUnique<SigninScreenHandler>(
       network_state_informer_, error_screen, core_handler_,
-      gaia_screen_handler_, js_calls_container.get());
+      GetView<GaiaScreenHandler>(), js_calls_container.get());
   signin_screen_handler_ = signin_screen_handler.get();
-  AddScreenHandler(std::move(signin_screen_handler));
+  AddWebUIHandler(std::move(signin_screen_handler));
 
-  auto app_launch_splash_screen_handler =
-      base::MakeUnique<AppLaunchSplashScreenHandler>(network_state_informer_,
-                                                     error_screen);
-  app_launch_splash_screen_view_ = app_launch_splash_screen_handler.get();
-  AddScreenHandler(std::move(app_launch_splash_screen_handler));
+  AddScreenHandler(base::MakeUnique<AppLaunchSplashScreenHandler>(
+      network_state_informer_, error_screen));
 
-  auto arc_kiosk_splash_screen_handler =
-      base::MakeUnique<ArcKioskSplashScreenHandler>();
-  arc_kiosk_splash_screen_view_ = arc_kiosk_splash_screen_handler.get();
-  AddScreenHandler(std::move(arc_kiosk_splash_screen_handler));
+  AddScreenHandler(base::MakeUnique<ArcKioskSplashScreenHandler>());
 
   if (display_type_ == kOobeDisplay) {
-    auto controller_pairing_handler =
-        base::MakeUnique<ControllerPairingScreenHandler>();
-    controller_pairing_screen_view_ = controller_pairing_handler.get();
-    AddScreenHandler(std::move(controller_pairing_handler));
+    AddScreenHandler(base::MakeUnique<ControllerPairingScreenHandler>());
 
-    auto host_pairing_handler = base::MakeUnique<HostPairingScreenHandler>();
-    host_pairing_screen_view_ = host_pairing_handler.get();
-    AddScreenHandler(std::move(host_pairing_handler));
+    AddScreenHandler(base::MakeUnique<HostPairingScreenHandler>());
   }
 
-  auto device_disabled_screen_handler =
-      base::MakeUnique<DeviceDisabledScreenHandler>();
-  device_disabled_screen_view_ = device_disabled_screen_handler.get();
-  AddScreenHandler(std::move(device_disabled_screen_handler));
+  AddScreenHandler(base::MakeUnique<DeviceDisabledScreenHandler>());
 
   // Initialize KioskAppMenuHandler. Note that it is NOT a screen handler.
   auto kiosk_app_menu_handler =
@@ -386,7 +329,7 @@
 
 OobeUI::~OobeUI() {
   core_handler_->SetDelegate(nullptr);
-  network_dropdown_handler_->RemoveObserver(error_screen_handler_);
+  network_dropdown_handler_->RemoveObserver(GetView<ErrorScreenHandler>());
   if (ash_util::IsRunningInMash()) {
     // TODO: Ash needs to expose screen dimming api. See
     // http://crbug.com/646034.
@@ -399,71 +342,71 @@
 }
 
 NetworkView* OobeUI::GetNetworkView() {
-  return network_view_;
+  return GetView<NetworkScreenHandler>();
 }
 
 EulaView* OobeUI::GetEulaView() {
-  return eula_view_;
+  return GetView<EulaScreenHandler>();
 }
 
 UpdateView* OobeUI::GetUpdateView() {
-  return update_view_;
+  return GetView<UpdateScreenHandler>();
 }
 
 EnableDebuggingScreenView* OobeUI::GetEnableDebuggingScreenView() {
-  return debugging_screen_view_;
+  return GetView<EnableDebuggingScreenHandler>();
 }
 
 EnrollmentScreenView* OobeUI::GetEnrollmentScreenView() {
-  return enrollment_screen_view_;
+  return GetView<EnrollmentScreenHandler>();
 }
 
 ResetView* OobeUI::GetResetView() {
-  return reset_view_;
+  return GetView<ResetScreenHandler>();
 }
 
 KioskAutolaunchScreenView* OobeUI::GetKioskAutolaunchScreenView() {
-  return autolaunch_screen_view_;
+  return GetView<KioskAutolaunchScreenHandler>();
 }
 
 KioskEnableScreenView* OobeUI::GetKioskEnableScreenView() {
-  return kiosk_enable_screen_view_;
+  return GetView<KioskEnableScreenHandler>();
 }
 
 TermsOfServiceScreenView* OobeUI::GetTermsOfServiceScreenView() {
-  return terms_of_service_screen_view_;
+  return GetView<TermsOfServiceScreenHandler>();
 }
 
 ArcTermsOfServiceScreenView* OobeUI::GetArcTermsOfServiceScreenView() {
-  return arc_terms_of_service_screen_view_;
+  return GetView<ArcTermsOfServiceScreenHandler>();
 }
 
 WrongHWIDScreenView* OobeUI::GetWrongHWIDScreenView() {
-  return wrong_hwid_screen_view_;
+  return GetView<WrongHWIDScreenHandler>();
 }
 
 AutoEnrollmentCheckScreenView* OobeUI::GetAutoEnrollmentCheckScreenView() {
-  return auto_enrollment_check_screen_view_;
+  return GetView<AutoEnrollmentCheckScreenHandler>();
 }
 
 HIDDetectionView* OobeUI::GetHIDDetectionView() {
-  return hid_detection_view_;
+  return GetView<HIDDetectionScreenHandler>();
 }
 
 ControllerPairingScreenView* OobeUI::GetControllerPairingScreenView() {
-  return controller_pairing_screen_view_;
+  return GetView<ControllerPairingScreenHandler>();
 }
 
 HostPairingScreenView* OobeUI::GetHostPairingScreenView() {
-  return host_pairing_screen_view_;
+  return GetView<HostPairingScreenHandler>();
 }
 
 DeviceDisabledScreenView* OobeUI::GetDeviceDisabledScreenView() {
-  return device_disabled_screen_view_;
+  return GetView<DeviceDisabledScreenHandler>();
 }
 
 UserImageView* OobeUI::GetUserImageView() {
-  return user_image_view_;
+  return GetView<UserImageScreenHandler>();
 }
 
 ErrorScreen* OobeUI::GetErrorScreen() {
@@ -476,11 +419,11 @@
 }
 
 GaiaView* OobeUI::GetGaiaScreenView() {
-  return gaia_screen_handler_;
+  return GetView<GaiaScreenHandler>();
 }
 
 UserBoardView* OobeUI::GetUserBoardView() {
-  return user_board_screen_handler_;
+  return GetView<UserBoardScreenHandler>();
 }
 
 void OobeUI::OnShutdownPolicyChanged(bool reboot_on_shutdown) {
@@ -488,18 +431,16 @@
 }
 
 AppLaunchSplashScreenView* OobeUI::GetAppLaunchSplashScreenView() {
-  return app_launch_splash_screen_view_;
+  return GetView<AppLaunchSplashScreenHandler>();
 }
 
 ArcKioskSplashScreenView* OobeUI::GetArcKioskSplashScreenView() {
-  return arc_kiosk_splash_screen_view_;
+  return GetView<ArcKioskSplashScreenHandler>();
 }
 
 void OobeUI::GetLocalizedStrings(base::DictionaryValue* localized_strings) {
-  // Note, handlers_[0] is a GenericHandler used by the WebUI.
-  for (size_t i = 0; i < handlers_.size(); ++i) {
-    handlers_[i]->GetLocalizedStrings(localized_strings);
-  }
+  for (BaseWebUIHandler* handler : webui_handlers_)
+    handler->GetLocalizedStrings(localized_strings);
   const std::string& app_locale = g_browser_process->GetApplicationLocale();
   webui::SetLoadTimeDataDefaults(app_locale, localized_strings);
   kiosk_app_menu_handler_->GetLocalizedStrings(localized_strings);
@@ -531,8 +472,14 @@
   localized_strings->SetString("newOobeUI", oobe_ui_md_mode_ ? "on" : "off");
 }
 
+void OobeUI::AddWebUIHandler(std::unique_ptr<BaseWebUIHandler> handler) {
+  webui_handlers_.push_back(handler.get());
+  web_ui()->AddMessageHandler(std::move(handler));
+}
+
 void OobeUI::AddScreenHandler(std::unique_ptr<BaseScreenHandler> handler) {
-  handlers_.push_back(handler.get());
+  webui_handlers_.push_back(handler.get());
+  screen_handlers_.push_back(handler.get());
   web_ui()->AddMessageHandler(std::move(handler));
 }
 
@@ -543,9 +490,9 @@
   ready_callbacks_.clear();
 
   // Notify 'initialize' for synchronously loaded screens.
-  for (size_t i = 0; i < handlers_.size(); ++i) {
-    if (handlers_[i]->async_assets_load_id().empty())
-      handlers_[i]->InitializeBase();
+  for (BaseWebUIHandler* handler : webui_handlers_) {
+    if (handler->async_assets_load_id().empty())
+      handler->InitializeBase();
   }
 
   // Instantiate the ShutdownPolicyHandler.
@@ -559,9 +506,9 @@
 void OobeUI::OnScreenAssetsLoaded(const std::string& async_assets_load_id) {
   DCHECK(!async_assets_load_id.empty());
 
-  for (size_t i = 0; i < handlers_.size(); ++i) {
-    if (handlers_[i]->async_assets_load_id() == async_assets_load_id)
-      handlers_[i]->InitializeBase();
+  for (BaseWebUIHandler* handler : webui_handlers_) {
+    if (handler->async_assets_load_id() == async_assets_load_id)
+      handler->InitializeBase();
   }
 }
 
diff --git a/chrome/browser/ui/webui/chromeos/login/oobe_ui.h b/chrome/browser/ui/webui/chromeos/login/oobe_ui.h
index 73748fe..b7d9be0 100644
--- a/chrome/browser/ui/webui/chromeos/login/oobe_ui.h
+++ b/chrome/browser/ui/webui/chromeos/login/oobe_ui.h
@@ -16,6 +16,7 @@
 #include "base/observer_list.h"
 #include "chrome/browser/chromeos/login/oobe_screen.h"
 #include "chrome/browser/chromeos/settings/shutdown_policy_handler.h"
+#include "chrome/browser/ui/webui/chromeos/login/base_screen_handler.h"
 #include "chrome/browser/ui/webui/chromeos/login/core_oobe_handler.h"
 #include "content/public/browser/web_ui_controller.h"
 
@@ -40,9 +41,7 @@
 class EnrollmentScreenView;
 class EulaView;
 class ErrorScreen;
-class ErrorScreenHandler;
 class GaiaView;
-class GaiaScreenHandler;
 class HIDDetectionView;
 class HostPairingScreenView;
 class KioskAppMenuHandler;
@@ -58,7 +57,6 @@
 class SupervisedUserCreationScreenHandler;
 class ResetView;
 class TermsOfServiceScreenView;
-class UserBoardScreenHandler;
 class UserBoardView;
 class UserImageView;
 class UpdateView;
@@ -169,6 +167,21 @@
   void UpdateLocalizedStringsIfNeeded();
 
  private:
+  // Lookup a view by its statically registered OobeScreen.
+  template <typename TView>
+  TView* GetView() {
+    OobeScreen expected_screen = TView::kScreenId;
+    for (BaseScreenHandler* handler : screen_handlers_) {
+      if (expected_screen == handler->oobe_screen())
+        return static_cast<TView*>(handler);
+    }
+
+    NOTREACHED() << "Unable to find handler for screen "
+                 << GetOobeScreenName(expected_screen);
+    return nullptr;
+  }
+
+  void AddWebUIHandler(std::unique_ptr<BaseWebUIHandler> handler);
   void AddScreenHandler(std::unique_ptr<BaseScreenHandler> handler);
 
   // CoreOobeHandler::Delegate implementation:
@@ -188,47 +201,14 @@
   // network dropdown.
   NetworkDropdownHandler* network_dropdown_handler_ = nullptr;
 
-  // Screens views. Note, OobeUI owns them via |handlers_|, not directly here.
-  UpdateView* update_view_ = nullptr;
-  NetworkView* network_view_ = nullptr;
-  EnableDebuggingScreenView* debugging_screen_view_ = nullptr;
-  EulaView* eula_view_ = nullptr;
-  EnrollmentScreenView* enrollment_screen_view_ = nullptr;
-  ResetView* reset_view_ = nullptr;
-  HIDDetectionView* hid_detection_view_ = nullptr;
-  KioskAutolaunchScreenView* autolaunch_screen_view_ = nullptr;
-  KioskEnableScreenView* kiosk_enable_screen_view_ = nullptr;
-  WrongHWIDScreenView* wrong_hwid_screen_view_ = nullptr;
-  AutoEnrollmentCheckScreenView* auto_enrollment_check_screen_view_ = nullptr;
   SupervisedUserCreationScreenHandler* supervised_user_creation_screen_view_ =
       nullptr;
-  AppLaunchSplashScreenView* app_launch_splash_screen_view_ = nullptr;
-  ArcKioskSplashScreenView* arc_kiosk_splash_screen_view_ = nullptr;
-  ControllerPairingScreenView* controller_pairing_screen_view_ = nullptr;
-  HostPairingScreenView* host_pairing_screen_view_ = nullptr;
-  DeviceDisabledScreenView* device_disabled_screen_view_ = nullptr;
-
-  // Reference to ErrorScreenHandler that handles error screen
-  // requests and forward calls from native code to JS side.
-  ErrorScreenHandler* error_screen_handler_ = nullptr;
-
-  // Reference to GaiaScreenHandler that handles gaia screen requests and
-  // forwards calls from native code to JS side.
-  GaiaScreenHandler* gaia_screen_handler_ = nullptr;
-
-  // Reference to UserBoardScreenHandler, that allows to pick user on device
-  // and attempt authentication.
-  UserBoardScreenHandler* user_board_screen_handler_ = nullptr;
-
   // Reference to SigninScreenHandler that handles sign-in screen requests and
   // forwards calls from native code to JS side.
   SigninScreenHandler* signin_screen_handler_ = nullptr;
 
-  TermsOfServiceScreenView* terms_of_service_screen_view_ = nullptr;
-  ArcTermsOfServiceScreenView* arc_terms_of_service_screen_view_ = nullptr;
-  UserImageView* user_image_view_ = nullptr;
-
-  std::vector<BaseScreenHandler*> handlers_;  // Non-owning pointers.
+  std::vector<BaseWebUIHandler*> webui_handlers_;    // Non-owning pointers.
+  std::vector<BaseScreenHandler*> screen_handlers_;  // Non-owning pointers.
 
   KioskAppMenuHandler* kiosk_app_menu_handler_ =
       nullptr;  // Non-owning pointers.
diff --git a/chrome/browser/ui/webui/chromeos/login/reset_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/reset_screen_handler.cc
index 3906059..38a49d3 100644
--- a/chrome/browser/ui/webui/chromeos/login/reset_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/reset_screen_handler.cc
@@ -27,7 +27,7 @@
 
 namespace chromeos {
 
-ResetScreenHandler::ResetScreenHandler() {
+ResetScreenHandler::ResetScreenHandler() : BaseScreenHandler(kScreenId) {
   set_call_js_prefix(kJsScreenPath);
 }
 
@@ -41,7 +41,7 @@
     show_on_init_ = true;
     return;
   }
-  ShowScreen(OobeScreen::SCREEN_OOBE_RESET);
+  ShowScreen(kScreenId);
 }
 
 void ResetScreenHandler::Hide() {
diff --git a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
index 06367218..c03f474 100644
--- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
@@ -293,7 +293,7 @@
     CoreOobeView* core_oobe_view,
     GaiaScreenHandler* gaia_screen_handler,
     JSCallsContainer* js_calls_container)
-    : BaseScreenHandler(js_calls_container),
+    : BaseWebUIHandler(js_calls_container),
       network_state_informer_(network_state_informer),
       error_screen_(error_screen),
       core_oobe_view_(core_oobe_view),
diff --git a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h
index 861ac63..d64b327 100644
--- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h
@@ -21,7 +21,7 @@
 #include "chrome/browser/chromeos/login/signin_specifics.h"
 #include "chrome/browser/chromeos/login/ui/login_display.h"
 #include "chrome/browser/chromeos/settings/cros_settings.h"
-#include "chrome/browser/ui/webui/chromeos/login/base_screen_handler.h"
+#include "chrome/browser/ui/webui/chromeos/login/base_webui_handler.h"
 #include "chrome/browser/ui/webui/chromeos/login/network_state_informer.h"
 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
 #include "chromeos/dbus/power_manager_client.h"
@@ -218,7 +218,7 @@
 // A class that handles the WebUI hooks in sign-in screen in OobeUI and
 // LoginDisplay.
 class SigninScreenHandler
-    : public BaseScreenHandler,
+    : public BaseWebUIHandler,
       public LoginDisplayWebUIHandler,
       public content::NotificationObserver,
       public NetworkStateInformer::NetworkStateInformerObserver,
diff --git a/chrome/browser/ui/webui/chromeos/login/supervised_user_creation_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/supervised_user_creation_screen_handler.cc
index 8f6221dd..0ac53b7 100644
--- a/chrome/browser/ui/webui/chromeos/login/supervised_user_creation_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/supervised_user_creation_screen_handler.cc
@@ -36,7 +36,8 @@
 
 namespace chromeos {
 
-SupervisedUserCreationScreenHandler::SupervisedUserCreationScreenHandler() {
+SupervisedUserCreationScreenHandler::SupervisedUserCreationScreenHandler()
+    : BaseScreenHandler(OobeScreen::SCREEN_CREATE_SUPERVISED_USER_FLOW) {
   set_call_js_prefix(kJsScreenPath);
   ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
   media::SoundsManager* manager = media::SoundsManager::Get();
diff --git a/chrome/browser/ui/webui/chromeos/login/terms_of_service_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/terms_of_service_screen_handler.cc
index 351a685a..e927f9b 100644
--- a/chrome/browser/ui/webui/chromeos/login/terms_of_service_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/terms_of_service_screen_handler.cc
@@ -38,7 +38,7 @@
 
 TermsOfServiceScreenHandler::TermsOfServiceScreenHandler(
     CoreOobeView* core_oobe_view)
-    : core_oobe_view_(core_oobe_view) {
+    : BaseScreenHandler(kScreenId), core_oobe_view_(core_oobe_view) {
   set_call_js_prefix(kJsScreenPath);
 }
 
@@ -169,7 +169,7 @@
   // Update the UI to show an error message or the Terms of Service.
   UpdateTermsOfServiceInUI();
 
-  ShowScreen(OobeScreen::SCREEN_TERMS_OF_SERVICE);
+  ShowScreen(kScreenId);
 }
 
 void TermsOfServiceScreenHandler::UpdateDomainInUI() {
diff --git a/chrome/browser/ui/webui/chromeos/login/update_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/update_screen_handler.cc
index 24be021c..a1ca651 100644
--- a/chrome/browser/ui/webui/chromeos/login/update_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/update_screen_handler.cc
@@ -21,7 +21,7 @@
 
 namespace chromeos {
 
-UpdateScreenHandler::UpdateScreenHandler() {
+UpdateScreenHandler::UpdateScreenHandler() : BaseScreenHandler(kScreenId) {
   set_call_js_prefix(kJsScreenPath);
 }
 
@@ -70,7 +70,7 @@
     show_on_init_ = true;
     return;
   }
-  ShowScreen(OobeScreen::SCREEN_OOBE_UPDATE);
+  ShowScreen(kScreenId);
 }
 
 void UpdateScreenHandler::Hide() {
diff --git a/chrome/browser/ui/webui/chromeos/login/user_board_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/user_board_screen_handler.cc
index aa9ce9be..16e83af 100644
--- a/chrome/browser/ui/webui/chromeos/login/user_board_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/user_board_screen_handler.cc
@@ -9,7 +9,8 @@
 
 namespace chromeos {
 
-UserBoardScreenHandler::UserBoardScreenHandler() : weak_factory_(this) {}
+UserBoardScreenHandler::UserBoardScreenHandler()
+    : BaseScreenHandler(kScreenId), weak_factory_(this) {}
 
 UserBoardScreenHandler::~UserBoardScreenHandler() {
 }
@@ -90,17 +91,17 @@
     proximity_auth::ScreenlockBridge::LockHandler::AuthType auth_type,
     const base::string16& initial_value) {
   CallJS("login.AccountPickerScreen.setAuthType", account_id,
-         static_cast<int>(auth_type), base::StringValue(initial_value));
+         static_cast<int>(auth_type), base::Value(initial_value));
 }
 
 void UserBoardScreenHandler::Bind(UserSelectionScreen* screen) {
   screen_ = screen;
-  BaseScreenHandler::SetBaseScreen(screen_);
+  BaseWebUIHandler::SetBaseScreen(screen_);
 }
 
 void UserBoardScreenHandler::Unbind() {
   screen_ = nullptr;
-  BaseScreenHandler::SetBaseScreen(nullptr);
+  BaseWebUIHandler::SetBaseScreen(nullptr);
 }
 
 base::WeakPtr<UserBoardView> UserBoardScreenHandler::GetWeakPtr() {
diff --git a/chrome/browser/ui/webui/chromeos/login/user_image_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/user_image_screen_handler.cc
index c1d4841..d313a59 100644
--- a/chrome/browser/ui/webui/chromeos/login/user_image_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/user_image_screen_handler.cc
@@ -38,7 +38,8 @@
 
 namespace chromeos {
 
-UserImageScreenHandler::UserImageScreenHandler() {
+UserImageScreenHandler::UserImageScreenHandler()
+    : BaseScreenHandler(kScreenId) {
   set_call_js_prefix(kJsScreenPath);
   ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
   media::SoundsManager* manager = media::SoundsManager::Get();
@@ -76,7 +77,7 @@
     return;
   }
   screen_show_time_ = base::Time::Now();
-  ShowScreen(OobeScreen::SCREEN_USER_IMAGE_PICKER);
+  ShowScreen(kScreenId);
 
   // When shown, query camera presence.
   if (screen_ && is_ready_)
diff --git a/chrome/browser/ui/webui/chromeos/login/wrong_hwid_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/wrong_hwid_screen_handler.cc
index e38c74c4..87b1920 100644
--- a/chrome/browser/ui/webui/chromeos/login/wrong_hwid_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/wrong_hwid_screen_handler.cc
@@ -16,7 +16,8 @@
 
 namespace chromeos {
 
-WrongHWIDScreenHandler::WrongHWIDScreenHandler() {
+WrongHWIDScreenHandler::WrongHWIDScreenHandler()
+    : BaseScreenHandler(kScreenId) {
   set_call_js_prefix(kJsScreenPath);
 }
 
@@ -30,7 +31,7 @@
     show_on_init_ = true;
     return;
   }
-  ShowScreen(OobeScreen::SCREEN_WRONG_HWID);
+  ShowScreen(kScreenId);
 }
 
 void WrongHWIDScreenHandler::Hide() {
diff --git a/chrome/browser/ui/webui/chromeos/set_time_ui.cc b/chrome/browser/ui/webui/chromeos/set_time_ui.cc
index 00cfbff..154c9ed8 100644
--- a/chrome/browser/ui/webui/chromeos/set_time_ui.cc
+++ b/chrome/browser/ui/webui/chromeos/set_time_ui.cc
@@ -65,8 +65,7 @@
 
   // system::TimezoneSettings::Observer:
   void TimezoneChanged(const icu::TimeZone& timezone) override {
-    base::StringValue timezone_id(
-        system::TimezoneSettings::GetTimezoneID(timezone));
+    base::Value timezone_id(system::TimezoneSettings::GetTimezoneID(timezone));
     web_ui()->CallJavascriptFunctionUnsafe("settime.TimeSetter.setTimezone",
                                            timezone_id);
   }
diff --git a/chrome/browser/ui/webui/crashes_ui.cc b/chrome/browser/ui/webui/crashes_ui.cc
index 175dd11..e2d64ce 100644
--- a/chrome/browser/ui/webui/crashes_ui.cc
+++ b/chrome/browser/ui/webui/crashes_ui.cc
@@ -191,9 +191,9 @@
   base::Value enabled(crash_reporting_enabled);
   base::Value dynamic_backend(system_crash_reporter);
   base::Value manual_uploads(support_manual_uploads);
-  base::StringValue version(version_info::GetVersionNumber());
-  base::StringValue os_string(base::SysInfo::OperatingSystemName() + " " +
-                              base::SysInfo::OperatingSystemVersion());
+  base::Value version(version_info::GetVersionNumber());
+  base::Value os_string(base::SysInfo::OperatingSystemName() + " " +
+                        base::SysInfo::OperatingSystemVersion());
 
   std::vector<const base::Value*> args;
   args.push_back(&enabled);
diff --git a/chrome/browser/ui/webui/device_log_ui.cc b/chrome/browser/ui/webui/device_log_ui.cc
index 915f932..aead8776 100644
--- a/chrome/browser/ui/webui/device_log_ui.cc
+++ b/chrome/browser/ui/webui/device_log_ui.cc
@@ -38,7 +38,7 @@
 
  private:
   void GetLog(const base::ListValue* value) const {
-    base::StringValue data(device_event_log::GetAsString(
+    base::Value data(device_event_log::GetAsString(
         device_event_log::NEWEST_FIRST, "json", "",
         device_event_log::LOG_LEVEL_DEBUG, 0));
     web_ui()->CallJavascriptFunctionUnsafe("DeviceLogUI.getLogCallback", data);
diff --git a/chrome/browser/ui/webui/extensions/chromeos/kiosk_apps_handler.cc b/chrome/browser/ui/webui/extensions/chromeos/kiosk_apps_handler.cc
index c7fc87d3..95d9805 100644
--- a/chrome/browser/ui/webui/extensions/chromeos/kiosk_apps_handler.cc
+++ b/chrome/browser/ui/webui/extensions/chromeos/kiosk_apps_handler.cc
@@ -369,7 +369,7 @@
 }
 
 void KioskAppsHandler::ShowError(const std::string& app_id) {
-  base::StringValue app_id_value(app_id);
+  base::Value app_id_value(app_id);
   web_ui()->CallJavascriptFunctionUnsafe(
       "extensions.KioskAppsOverlay.showError", app_id_value);
 
diff --git a/chrome/browser/ui/webui/extensions/extension_loader_handler.cc b/chrome/browser/ui/webui/extensions/extension_loader_handler.cc
index 88c7485..e2e40ce 100644
--- a/chrome/browser/ui/webui/extensions/extension_loader_handler.cc
+++ b/chrome/browser/ui/webui/extensions/extension_loader_handler.cc
@@ -197,9 +197,8 @@
   highlighter.SetHighlightedRegions(manifest_value.get());
 
   std::unique_ptr<base::DictionaryValue> failure(new base::DictionaryValue());
-  failure->Set("path",
-               new base::StringValue(prettified_path.LossyDisplayName()));
-  failure->Set("error", new base::StringValue(base::UTF8ToUTF16(error)));
+  failure->Set("path", new base::Value(prettified_path.LossyDisplayName()));
+  failure->Set("error", new base::Value(base::UTF8ToUTF16(error)));
   failure->Set("manifest", manifest_value.release());
   failures_.Append(std::move(failure));
 
diff --git a/chrome/browser/ui/webui/help/help_handler.cc b/chrome/browser/ui/webui/help/help_handler.cc
index de91108..7b697b3 100644
--- a/chrome/browser/ui/webui/help/help_handler.cc
+++ b/chrome/browser/ui/webui/help/help_handler.cc
@@ -483,7 +483,7 @@
   base::Time build_time = base::SysInfo::GetLsbReleaseTime();
   base::string16 build_date = base::TimeFormatFriendlyDate(build_time);
   web_ui()->CallJavascriptFunctionUnsafe("help.HelpPage.setBuildDate",
-                                         base::StringValue(build_date));
+                                         base::Value(build_date));
 #endif  // defined(OS_CHROMEOS)
 
   RefreshUpdateStatus();
@@ -637,8 +637,8 @@
   }
 
   web_ui()->CallJavascriptFunctionUnsafe("help.HelpPage.setUpdateStatus",
-                                         base::StringValue(status_str),
-                                         base::StringValue(message));
+                                         base::Value(status_str),
+                                         base::Value(message));
 
   if (status == VersionUpdater::UPDATING) {
     web_ui()->CallJavascriptFunctionUnsafe("help.HelpPage.setProgress",
@@ -652,7 +652,7 @@
     if (!types_msg.empty()) {
       web_ui()->CallJavascriptFunctionUnsafe(
           "help.HelpPage.setAndShowAllowedConnectionTypesMsg",
-          base::StringValue(types_msg));
+          base::Value(types_msg));
     } else {
       web_ui()->CallJavascriptFunctionUnsafe(
           "help.HelpPage.showAllowedConnectionTypesMsg", base::Value(false));
@@ -681,34 +681,34 @@
   }
 
   web_ui()->CallJavascriptFunctionUnsafe("help.HelpPage.setPromotionState",
-                                         base::StringValue(state_str));
+                                         base::Value(state_str));
 }
 #endif  // defined(OS_MACOSX)
 
 #if defined(OS_CHROMEOS)
 void HelpHandler::OnOSVersion(const std::string& version) {
   web_ui()->CallJavascriptFunctionUnsafe("help.HelpPage.setOSVersion",
-                                         base::StringValue(version));
+                                         base::Value(version));
 }
 
 void HelpHandler::OnARCVersion(const std::string& firmware) {
   web_ui()->CallJavascriptFunctionUnsafe("help.HelpPage.setARCVersion",
-                                         base::StringValue(firmware));
+                                         base::Value(firmware));
 }
 
 void HelpHandler::OnOSFirmware(const std::string& firmware) {
   web_ui()->CallJavascriptFunctionUnsafe("help.HelpPage.setOSFirmware",
-                                         base::StringValue(firmware));
+                                         base::Value(firmware));
 }
 
 void HelpHandler::OnCurrentChannel(const std::string& channel) {
   web_ui()->CallJavascriptFunctionUnsafe("help.HelpPage.updateCurrentChannel",
-                                         base::StringValue(channel));
+                                         base::Value(channel));
 }
 
 void HelpHandler::OnTargetChannel(const std::string& channel) {
   web_ui()->CallJavascriptFunctionUnsafe("help.HelpPage.updateTargetChannel",
-                                         base::StringValue(channel));
+                                         base::Value(channel));
 }
 
 void HelpHandler::OnRegulatoryLabelDirFound(const base::FilePath& path) {
@@ -730,14 +730,14 @@
   std::string url = std::string("chrome://") + chrome::kChromeOSAssetHost +
       "/" + path.MaybeAsASCII();
   web_ui()->CallJavascriptFunctionUnsafe("help.HelpPage.setRegulatoryLabelPath",
-                                         base::StringValue(url));
+                                         base::Value(url));
 }
 
 void HelpHandler::OnRegulatoryLabelTextRead(const std::string& text) {
   // Remove unnecessary whitespace.
   web_ui()->CallJavascriptFunctionUnsafe(
       "help.HelpPage.setRegulatoryLabelText",
-      base::StringValue(base::CollapseWhitespaceASCII(text, true)));
+      base::Value(base::CollapseWhitespaceASCII(text, true)));
 }
 
 void HelpHandler::OnEolStatus(update_engine::EndOfLifeStatus status) {
@@ -748,13 +748,13 @@
   }
 
   if (status == update_engine::EndOfLifeStatus::kSupported) {
-    web_ui()->CallJavascriptFunctionUnsafe(
-        "help.HelpPage.updateEolMessage", base::StringValue("device_supported"),
-        base::StringValue(""));
+    web_ui()->CallJavascriptFunctionUnsafe("help.HelpPage.updateEolMessage",
+                                           base::Value("device_supported"),
+                                           base::Value(""));
   } else {
     web_ui()->CallJavascriptFunctionUnsafe(
-        "help.HelpPage.updateEolMessage", base::StringValue("device_endoflife"),
-        base::StringValue(l10n_util::GetStringUTF16(IDS_ABOUT_PAGE_EOL_EOL)));
+        "help.HelpPage.updateEolMessage", base::Value("device_endoflife"),
+        base::Value(l10n_util::GetStringUTF16(IDS_ABOUT_PAGE_EOL_EOL)));
   }
 }
 
diff --git a/chrome/browser/ui/webui/inspect_ui.cc b/chrome/browser/ui/webui/inspect_ui.cc
index fdebd22..287e230d 100644
--- a/chrome/browser/ui/webui/inspect_ui.cc
+++ b/chrome/browser/ui/webui/inspect_ui.cc
@@ -607,8 +607,8 @@
 
 void InspectUI::PopulateTargets(const std::string& source,
                                 const base::ListValue& targets) {
-  web_ui()->CallJavascriptFunctionUnsafe("populateTargets",
-                                         base::StringValue(source), targets);
+  web_ui()->CallJavascriptFunctionUnsafe("populateTargets", base::Value(source),
+                                         targets);
 }
 
 void InspectUI::PopulateAdditionalTargets(const base::ListValue& targets) {
diff --git a/chrome/browser/ui/webui/inspect_ui_browsertest.cc b/chrome/browser/ui/webui/inspect_ui_browsertest.cc
index e0c14b5..2d9d4064 100644
--- a/chrome/browser/ui/webui/inspect_ui_browsertest.cc
+++ b/chrome/browser/ui/webui/inspect_ui_browsertest.cc
@@ -39,10 +39,9 @@
 IN_PROC_BROWSER_TEST_F(InspectUITest, InspectUIPage) {
   ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIInspectURL));
   ASSERT_TRUE(WebUIBrowserTest::RunJavascriptAsyncTest(
-      "testTargetListed",
-      new base::StringValue("#pages"),
-      new base::StringValue("populateWebContentsTargets"),
-      new base::StringValue(chrome::kChromeUIInspectURL)));
+      "testTargetListed", new base::Value("#pages"),
+      new base::Value("populateWebContentsTargets"),
+      new base::Value(chrome::kChromeUIInspectURL)));
 }
 
 IN_PROC_BROWSER_TEST_F(InspectUITest, SharedWorker) {
@@ -56,16 +55,14 @@
       ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
 
   ASSERT_TRUE(WebUIBrowserTest::RunJavascriptAsyncTest(
-      "testTargetListed",
-      new base::StringValue("#workers"),
-      new base::StringValue("populateWorkerTargets"),
-      new base::StringValue(kSharedWorkerJs)));
+      "testTargetListed", new base::Value("#workers"),
+      new base::Value("populateWorkerTargets"),
+      new base::Value(kSharedWorkerJs)));
 
   ASSERT_TRUE(WebUIBrowserTest::RunJavascriptAsyncTest(
-      "testTargetListed",
-      new base::StringValue("#pages"),
-      new base::StringValue("populateWebContentsTargets"),
-      new base::StringValue(kSharedWorkerTestPage)));
+      "testTargetListed", new base::Value("#pages"),
+      new base::Value("populateWebContentsTargets"),
+      new base::Value(kSharedWorkerTestPage)));
 }
 
 // Flaky due to failure to bind a hardcoded port. crbug.com/566057
diff --git a/chrome/browser/ui/webui/instant_ui.cc b/chrome/browser/ui/webui/instant_ui.cc
index f5dbf44..9466b86f 100644
--- a/chrome/browser/ui/webui/instant_ui.cc
+++ b/chrome/browser/ui/webui/instant_ui.cc
@@ -103,10 +103,10 @@
   std::string pref_name;
   if (!args->GetString(0, &pref_name)) return;
 
-  base::StringValue pref_name_value(pref_name);
+  base::Value pref_name_value(pref_name);
   if (pref_name == prefs::kInstantUIZeroSuggestUrlPrefix) {
     PrefService* prefs = Profile::FromWebUI(web_ui())->GetPrefs();
-    base::StringValue arg(prefs->GetString(pref_name.c_str()));
+    base::Value arg(prefs->GetString(pref_name.c_str()));
     web_ui()->CallJavascriptFunctionUnsafe(
         "instantConfig.getPreferenceValueResult", pref_name_value, arg);
   }
diff --git a/chrome/browser/ui/webui/invalidations_message_handler.cc b/chrome/browser/ui/webui/invalidations_message_handler.cc
index e6cf9d9..7415064 100644
--- a/chrome/browser/ui/webui/invalidations_message_handler.cc
+++ b/chrome/browser/ui/webui/invalidations_message_handler.cc
@@ -89,7 +89,7 @@
     const base::Time& last_changed_timestamp) {
   std::string state(syncer::InvalidatorStateToString(new_state));
   web_ui()->CallJavascriptFunctionUnsafe(
-      "chrome.invalidations.updateInvalidatorState", base::StringValue(state),
+      "chrome.invalidations.updateInvalidatorState", base::Value(state),
       base::Value(last_changed_timestamp.ToJsTime()));
 }
 
@@ -107,7 +107,7 @@
     list_of_objects.Append(std::move(dic));
   }
   web_ui()->CallJavascriptFunctionUnsafe("chrome.invalidations.updateIds",
-                                         base::StringValue(handler_name),
+                                         base::Value(handler_name),
                                          list_of_objects);
 }
 void InvalidationsMessageHandler::OnDebugMessage(
diff --git a/chrome/browser/ui/webui/local_discovery/local_discovery_ui_handler.cc b/chrome/browser/ui/webui/local_discovery/local_discovery_ui_handler.cc
index 5ec61e34..f55ba74f 100644
--- a/chrome/browser/ui/webui/local_discovery/local_discovery_ui_handler.cc
+++ b/chrome/browser/ui/webui/local_discovery/local_discovery_ui_handler.cc
@@ -350,7 +350,7 @@
 
   base::DictionaryValue info;
 
-  base::StringValue service_key(kKeyPrefixMDns + name);
+  base::Value service_key(kKeyPrefixMDns + name);
 
   if (description.id.empty()) {
     info.SetString(kDictionaryKeyServiceName, name);
@@ -372,7 +372,7 @@
 void LocalDiscoveryUIHandler::DeviceRemoved(const std::string& name) {
   device_descriptions_.erase(name);
   std::unique_ptr<base::Value> null_value = base::Value::CreateNullValue();
-  base::StringValue name_value(kKeyPrefixMDns + name);
+  base::Value name_value(kKeyPrefixMDns + name);
 
   web_ui()->CallJavascriptFunctionUnsafe(
       "local_discovery.onUnregisteredDeviceUpdate", name_value, *null_value);
@@ -600,7 +600,7 @@
         l10n_util::GetStringUTF16(IDS_GOOGLE_CLOUD_PRINT),
         base::UTF8ToUTF16(email));
   }
-  base::StringValue label(label_str);
+  base::Value label(label_str);
 
   web_ui()->CallJavascriptFunctionUnsafe(
       "local_discovery.setupCloudPrintConnectorSection", disabled, label,
diff --git a/chrome/browser/ui/webui/local_state/local_state_ui.cc b/chrome/browser/ui/webui/local_state/local_state_ui.cc
index 42a27aa..0ebad38 100644
--- a/chrome/browser/ui/webui/local_state/local_state_ui.cc
+++ b/chrome/browser/ui/webui/local_state/local_state_ui.cc
@@ -76,7 +76,7 @@
     json = "Error loading Local State file.";
 
   web_ui()->CallJavascriptFunctionUnsafe("localState.setLocalState",
-                                         base::StringValue(json));
+                                         base::Value(json));
 }
 
 // Returns true if |pref_name| starts with one of the |valid_prefixes|.
diff --git a/chrome/browser/ui/webui/local_state/local_state_ui_unittest.cc b/chrome/browser/ui/webui/local_state/local_state_ui_unittest.cc
index 2fc8de3..4d179340 100644
--- a/chrome/browser/ui/webui/local_state/local_state_ui_unittest.cc
+++ b/chrome/browser/ui/webui/local_state/local_state_ui_unittest.cc
@@ -19,7 +19,7 @@
 
   base::DictionaryValue prefs;
   for (const std::string& key : all_pref_keys) {
-    prefs.Set(key, new base::StringValue(key + "_value"));
+    prefs.Set(key, new base::Value(key + "_value"));
   }
 
   internal::FilterPrefs(prefixes, &prefs);
diff --git a/chrome/browser/ui/webui/media/webrtc_logs_ui.cc b/chrome/browser/ui/webui/media/webrtc_logs_ui.cc
index 4ce45f6..5a3355f 100644
--- a/chrome/browser/ui/webui/media/webrtc_logs_ui.cc
+++ b/chrome/browser/ui/webui/media/webrtc_logs_ui.cc
@@ -202,7 +202,7 @@
     upload_list.Append(std::move(upload));
   }
 
-  base::StringValue version(version_info::GetVersionNumber());
+  base::Value version(version_info::GetVersionNumber());
 
   web_ui()->CallJavascriptFunctionUnsafe("updateWebRtcLogsList", upload_list,
                                          version);
diff --git a/chrome/browser/ui/webui/media_router/media_router_ui.cc b/chrome/browser/ui/webui/media_router/media_router_ui.cc
index 8e8e9740..705823e7 100644
--- a/chrome/browser/ui/webui/media_router/media_router_ui.cc
+++ b/chrome/browser/ui/webui/media_router/media_router_ui.cc
@@ -533,7 +533,7 @@
   const base::ListValue* origins =
       Profile::FromWebUI(web_ui())->GetPrefs()->GetList(
           prefs::kMediaRouterTabMirroringSources);
-  return origins->Find(base::StringValue(GetSerializedInitiatorOrigin())) !=
+  return origins->Find(base::Value(GetSerializedInitiatorOrigin())) !=
          origins->end();
 }
 
@@ -543,12 +543,11 @@
 
   switch (cast_mode) {
     case MediaCastMode::DEFAULT:
-      update->Remove(base::StringValue(GetSerializedInitiatorOrigin()),
-                     nullptr);
+      update->Remove(base::Value(GetSerializedInitiatorOrigin()), nullptr);
       break;
     case MediaCastMode::TAB_MIRROR:
       update->AppendIfNotPresent(
-          base::MakeUnique<base::StringValue>(GetSerializedInitiatorOrigin()));
+          base::MakeUnique<base::Value>(GetSerializedInitiatorOrigin()));
       break;
     case MediaCastMode::DESKTOP_MIRROR:
       // Desktop mirroring isn't domain-specific, so we don't record the
diff --git a/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.cc b/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.cc
index 7d398e7..5c223c57 100644
--- a/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.cc
+++ b/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.cc
@@ -282,12 +282,12 @@
     std::unique_ptr<base::DictionaryValue> route_value(RouteToValue(
         *route, false, media_router_ui_->GetRouteProviderExtensionId(),
         incognito_, current_cast_mode));
-    web_ui()->CallJavascriptFunctionUnsafe(
-        kOnCreateRouteResponseReceived, base::StringValue(sink_id),
-        *route_value, base::Value(route->for_display()));
+    web_ui()->CallJavascriptFunctionUnsafe(kOnCreateRouteResponseReceived,
+                                           base::Value(sink_id), *route_value,
+                                           base::Value(route->for_display()));
   } else {
     web_ui()->CallJavascriptFunctionUnsafe(
-        kOnCreateRouteResponseReceived, base::StringValue(sink_id),
+        kOnCreateRouteResponseReceived, base::Value(sink_id),
         *base::Value::CreateNullValue(), base::Value(false));
   }
 }
@@ -296,7 +296,7 @@
     const std::string& sink_id) {
   DVLOG(2) << "ReturnSearchResult";
   web_ui()->CallJavascriptFunctionUnsafe(kReceiveSearchResult,
-                                         base::StringValue(sink_id));
+                                         base::Value(sink_id));
 }
 
 void MediaRouterWebUIMessageHandler::UpdateIssue(const Issue& issue) {
diff --git a/chrome/browser/ui/webui/media_router/media_router_webui_message_handler_unittest.cc b/chrome/browser/ui/webui/media_router/media_router_webui_message_handler_unittest.cc
index 626961b4..5d53704 100644
--- a/chrome/browser/ui/webui/media_router/media_router_webui_message_handler_unittest.cc
+++ b/chrome/browser/ui/webui/media_router/media_router_webui_message_handler_unittest.cc
@@ -457,7 +457,7 @@
   EXPECT_EQ("media_router.ui.onCreateRouteResponseReceived",
             call_data.function_name());
   const base::Value* arg1 = call_data.arg1();
-  const base::StringValue* sink_id_value = nullptr;
+  const base::Value* sink_id_value = nullptr;
   ASSERT_TRUE(arg1->GetAsString(&sink_id_value));
   EXPECT_EQ(sink_id, sink_id_value->GetString());
 
@@ -512,7 +512,7 @@
   EXPECT_EQ("media_router.ui.onCreateRouteResponseReceived",
             call_data.function_name());
   const base::Value* arg1 = call_data.arg1();
-  const base::StringValue* sink_id_value = nullptr;
+  const base::Value* sink_id_value = nullptr;
   ASSERT_TRUE(arg1->GetAsString(&sink_id_value));
   EXPECT_EQ(sink_id, sink_id_value->GetString());
 
diff --git a/chrome/browser/ui/webui/net_internals/net_internals_ui.cc b/chrome/browser/ui/webui/net_internals/net_internals_ui.cc
index 268d526..21441c4d 100644
--- a/chrome/browser/ui/webui/net_internals/net_internals_ui.cc
+++ b/chrome/browser/ui/webui/net_internals/net_internals_ui.cc
@@ -89,7 +89,7 @@
 #include "components/user_manager/user.h"
 #endif
 
-using base::StringValue;
+using base::Value;
 using content::BrowserThread;
 using content::WebContents;
 using content::WebUIMessageHandler;
@@ -484,7 +484,7 @@
 void NetInternalsMessageHandler::SendJavascriptCommand(
     const std::string& command,
     std::unique_ptr<base::Value> arg) {
-  std::unique_ptr<base::Value> command_value(new base::StringValue(command));
+  std::unique_ptr<base::Value> command_value(new base::Value(command));
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   if (arg) {
     web_ui()->CallJavascriptFunctionUnsafe("g_browser.receive",
@@ -845,7 +845,7 @@
   if (!user) {
     std::string error = "User not found.";
     SendJavascriptCommand("receivedONCFileParse",
-                          base::MakeUnique<base::StringValue>(error));
+                          base::MakeUnique<base::Value>(error));
     return;
   }
 
@@ -887,7 +887,7 @@
     error += "Some certificates couldn't be imported. ";
 
   SendJavascriptCommand("receivedONCFileParse",
-                        base::MakeUnique<base::StringValue>(error));
+                        base::MakeUnique<base::Value>(error));
 }
 
 void NetInternalsMessageHandler::OnImportONCFile(
@@ -909,9 +909,8 @@
 void NetInternalsMessageHandler::OnStoreDebugLogs(const base::ListValue* list) {
   DCHECK(list);
 
-  SendJavascriptCommand(
-      "receivedStoreDebugLogs",
-      base::MakeUnique<base::StringValue>("Creating log file..."));
+  SendJavascriptCommand("receivedStoreDebugLogs",
+                        base::MakeUnique<base::Value>("Creating log file..."));
   Profile* profile = Profile::FromWebUI(web_ui());
   const DownloadPrefs* const prefs = DownloadPrefs::FromBrowserContext(profile);
   base::FilePath path = prefs->DownloadPath();
@@ -932,7 +931,7 @@
   else
     status = "Failed to create log file";
   SendJavascriptCommand("receivedStoreDebugLogs",
-                        base::MakeUnique<base::StringValue>(status));
+                        base::MakeUnique<base::Value>(status));
 }
 
 void NetInternalsMessageHandler::OnSetNetworkDebugMode(
@@ -956,7 +955,7 @@
                                  : "Failed to change debug mode to ";
   status += subsystem;
   SendJavascriptCommand("receivedSetNetworkDebugMode",
-                        base::MakeUnique<base::StringValue>(status));
+                        base::MakeUnique<base::Value>(status));
 }
 #endif  // defined(OS_CHROMEOS)
 
diff --git a/chrome/browser/ui/webui/net_internals/net_internals_ui_browsertest.cc b/chrome/browser/ui/webui/net_internals/net_internals_ui_browsertest.cc
index c5853e0..7f40719 100644
--- a/chrome/browser/ui/webui/net_internals/net_internals_ui_browsertest.cc
+++ b/chrome/browser/ui/webui/net_internals/net_internals_ui_browsertest.cc
@@ -103,6 +103,12 @@
  private:
   void RegisterMessages() override;
 
+  void RegisterMessage(const std::string& message,
+                       const content::WebUI::MessageCallback& handler);
+
+  void HandleMessage(const content::WebUI::MessageCallback& handler,
+                     const base::ListValue* data);
+
   // Runs NetInternalsTest.callback with the given value.
   void RunJavascriptCallback(base::Value* value);
 
@@ -158,35 +164,56 @@
 }
 
 void NetInternalsTest::MessageHandler::RegisterMessages() {
-  web_ui()->RegisterMessageCallback("getTestServerURL",
+  RegisterMessage(
+      "getTestServerURL",
       base::Bind(&NetInternalsTest::MessageHandler::GetTestServerURL,
                  base::Unretained(this)));
-  web_ui()->RegisterMessageCallback("addCacheEntry",
-      base::Bind(&NetInternalsTest::MessageHandler::AddCacheEntry,
-                 base::Unretained(this)));
-  web_ui()->RegisterMessageCallback("loadPage",
-      base::Bind(&NetInternalsTest::MessageHandler::LoadPage,
-                  base::Unretained(this)));
-  web_ui()->RegisterMessageCallback("prerenderPage",
-      base::Bind(&NetInternalsTest::MessageHandler::PrerenderPage,
-                  base::Unretained(this)));
-  web_ui()->RegisterMessageCallback("navigateToPrerender",
+  RegisterMessage("addCacheEntry",
+                  base::Bind(&NetInternalsTest::MessageHandler::AddCacheEntry,
+                             base::Unretained(this)));
+  RegisterMessage("loadPage",
+                  base::Bind(&NetInternalsTest::MessageHandler::LoadPage,
+                             base::Unretained(this)));
+  RegisterMessage("prerenderPage",
+                  base::Bind(&NetInternalsTest::MessageHandler::PrerenderPage,
+                             base::Unretained(this)));
+  RegisterMessage(
+      "navigateToPrerender",
       base::Bind(&NetInternalsTest::MessageHandler::NavigateToPrerender,
                  base::Unretained(this)));
-  web_ui()->RegisterMessageCallback("createIncognitoBrowser",
+  RegisterMessage(
+      "createIncognitoBrowser",
       base::Bind(&NetInternalsTest::MessageHandler::CreateIncognitoBrowser,
                  base::Unretained(this)));
-  web_ui()->RegisterMessageCallback("closeIncognitoBrowser",
+  RegisterMessage(
+      "closeIncognitoBrowser",
       base::Bind(&NetInternalsTest::MessageHandler::CloseIncognitoBrowser,
                  base::Unretained(this)));
-  web_ui()->RegisterMessageCallback("getNetLogFileContents",
-      base::Bind(
-          &NetInternalsTest::MessageHandler::GetNetLogFileContents,
-          base::Unretained(this)));
-  web_ui()->RegisterMessageCallback("enableDataReductionProxy",
-      base::Bind(
-          &NetInternalsTest::MessageHandler::EnableDataReductionProxy,
-          base::Unretained(this)));
+  RegisterMessage(
+      "getNetLogFileContents",
+      base::Bind(&NetInternalsTest::MessageHandler::GetNetLogFileContents,
+                 base::Unretained(this)));
+  RegisterMessage(
+      "enableDataReductionProxy",
+      base::Bind(&NetInternalsTest::MessageHandler::EnableDataReductionProxy,
+                 base::Unretained(this)));
+}
+
+void NetInternalsTest::MessageHandler::RegisterMessage(
+    const std::string& message,
+    const content::WebUI::MessageCallback& handler) {
+  web_ui()->RegisterMessageCallback(
+      message, base::Bind(&NetInternalsTest::MessageHandler::HandleMessage,
+                          base::Unretained(this), handler));
+}
+
+void NetInternalsTest::MessageHandler::HandleMessage(
+    const content::WebUI::MessageCallback& handler,
+    const base::ListValue* data) {
+  // The handler might run a nested loop to wait for something.
+  base::MessageLoop::ScopedNestableTaskAllower nestable_task_allower(
+      base::MessageLoop::current());
+  handler.Run(data);
 }
 
 void NetInternalsTest::MessageHandler::RunJavascriptCallback(
@@ -200,7 +227,7 @@
   std::string path;
   ASSERT_TRUE(list_value->GetString(0, &path));
   GURL url = net_internals_test_->embedded_test_server()->GetURL(path);
-  std::unique_ptr<base::Value> url_value(new base::StringValue(url.spec()));
+  std::unique_ptr<base::Value> url_value(new base::Value(url.spec()));
   RunJavascriptCallback(url_value.get());
 }
 
@@ -261,7 +288,7 @@
   incognito_browser_ = net_internals_test_->CreateIncognitoBrowser();
 
   // Tell the test harness that creation is complete.
-  base::StringValue command_value("onIncognitoBrowserCreatedForTest");
+  base::Value command_value("onIncognitoBrowserCreatedForTest");
   web_ui()->CallJavascriptFunctionUnsafe("g_browser.receive", command_value);
 }
 
@@ -305,7 +332,7 @@
   ASSERT_GT(log_contents.length(), 0u);
 
   std::unique_ptr<base::Value> log_contents_value(
-      new base::StringValue(log_contents));
+      new base::Value(log_contents));
   RunJavascriptCallback(log_contents_value.get());
 }
 
diff --git a/chrome/browser/ui/webui/ntp/app_launcher_handler.cc b/chrome/browser/ui/webui/ntp/app_launcher_handler.cc
index fae9d149..488ace9 100644
--- a/chrome/browser/ui/webui/ntp/app_launcher_handler.cc
+++ b/chrome/browser/ui/webui/ntp/app_launcher_handler.cc
@@ -379,8 +379,8 @@
   if (!app_page_names || !app_page_names->GetSize()) {
     ListPrefUpdate update(prefs, prefs::kNtpAppPageNames);
     base::ListValue* list = update.Get();
-    list->Set(0, new base::StringValue(
-        l10n_util::GetStringUTF16(IDS_APP_DEFAULT_PAGE_NAME)));
+    list->Set(0, new base::Value(
+                     l10n_util::GetStringUTF16(IDS_APP_DEFAULT_PAGE_NAME)));
     dictionary->Set("appPageNames",
                     static_cast<base::ListValue*>(list->DeepCopy()));
   } else {
@@ -691,7 +691,7 @@
   PrefService* prefs = Profile::FromWebUI(web_ui())->GetPrefs();
   ListPrefUpdate update(prefs, prefs::kNtpAppPageNames);
   base::ListValue* list = update.Get();
-  list->Set(static_cast<size_t>(page_index), new base::StringValue(name));
+  list->Set(static_cast<size_t>(page_index), new base::Value(name));
 }
 
 void AppLauncherHandler::HandleGenerateAppForLink(const base::ListValue* args) {
@@ -781,7 +781,7 @@
   if (highlight_app_id_.empty())
     return;
 
-  base::StringValue app_id(highlight_app_id_);
+  base::Value app_id(highlight_app_id_);
   web_ui()->CallJavascriptFunctionUnsafe("ntp.setAppToBeHighlighted", app_id);
   highlight_app_id_.clear();
 }
@@ -829,7 +829,7 @@
   // If we don't launch the app asynchronously, then the app's disabled
   // icon disappears but isn't replaced by the enabled icon, making a poor
   // visual experience.
-  base::StringValue app_id(extension_id_prompting_);
+  base::Value app_id(extension_id_prompting_);
   web_ui()->CallJavascriptFunctionUnsafe("ntp.launchAppAfterEnable", app_id);
 
   extension_enable_flow_.reset();
diff --git a/chrome/browser/ui/webui/ntp/new_tab_ui.cc b/chrome/browser/ui/webui/ntp/new_tab_ui.cc
index c5db07c..aa82c605 100644
--- a/chrome/browser/ui/webui/ntp/new_tab_ui.cc
+++ b/chrome/browser/ui/webui/ntp/new_tab_ui.cc
@@ -89,9 +89,10 @@
 NewTabUI::~NewTabUI() {}
 
 void NewTabUI::OnShowBookmarkBarChanged() {
-  base::StringValue attached(
-      GetProfile()->GetPrefs()->GetBoolean(bookmarks::prefs::kShowBookmarkBar) ?
-          "true" : "false");
+  base::Value attached(
+      GetProfile()->GetPrefs()->GetBoolean(bookmarks::prefs::kShowBookmarkBar)
+          ? "true"
+          : "false");
   web_ui()->CallJavascriptFunctionUnsafe("ntp.setBookmarkBarAttached",
                                          attached);
 }
diff --git a/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc b/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc
index cbbf9ea..a6ab0c5 100644
--- a/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc
+++ b/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc
@@ -90,27 +90,6 @@
     "https://support.google.com/chrome/?p=ui_guest";
 #endif
 
-std::string SkColorToRGBAString(SkColor color) {
-  // We convert the alpha using DoubleToString because StringPrintf will use
-  // locale specific formatters (e.g., use , instead of . in German).
-  return base::StringPrintf(
-      "rgba(%d,%d,%d,%s)",
-      SkColorGetR(color),
-      SkColorGetG(color),
-      SkColorGetB(color),
-      base::DoubleToString(SkColorGetA(color) / 255.0).c_str());
-}
-
-// Creates an rgb string for an SkColor, but leaves the alpha blank so that the
-// css can fill it in.
-std::string SkColorToRGBComponents(SkColor color) {
-  return base::StringPrintf(
-      "%d,%d,%d",
-      SkColorGetR(color),
-      SkColorGetG(color),
-      SkColorGetB(color));
-}
-
 SkColor GetThemeColor(const ui::ThemeProvider& tp, int id) {
   SkColor color = tp.GetColor(id);
   // If web contents are being inverted because the system is in high-contrast
@@ -520,7 +499,8 @@
       profile_->GetPrefs()->GetString(prefs::kCurrentThemeID);
 
   // Colors.
-  substitutions["colorBackground"] = SkColorToRGBAString(color_background);
+  substitutions["colorBackground"] =
+      color_utils::SkColorToRgbaString(color_background);
   substitutions["backgroundBarDetached"] = GetNewTabBackgroundCSS(tp, false);
   substitutions["backgroundBarAttached"] = GetNewTabBackgroundCSS(tp, true);
   substitutions["backgroundTiling"] = GetNewTabBackgroundTilingCSS(tp);
@@ -572,15 +552,17 @@
       profile_->GetPrefs()->GetString(prefs::kCurrentThemeID);
 
   // Colors.
-  substitutions["colorBackground"] = SkColorToRGBAString(color_background);
+  substitutions["colorBackground"] =
+      color_utils::SkColorToRgbaString(color_background);
   substitutions["backgroundBarDetached"] = GetNewTabBackgroundCSS(tp, false);
   substitutions["backgroundBarAttached"] = GetNewTabBackgroundCSS(tp, true);
   substitutions["backgroundTiling"] = GetNewTabBackgroundTilingCSS(tp);
-  substitutions["colorTextRgba"] = SkColorToRGBAString(color_text);
-  substitutions["colorTextLight"] = SkColorToRGBAString(color_text_light);
+  substitutions["colorTextRgba"] = color_utils::SkColorToRgbaString(color_text);
+  substitutions["colorTextLight"] =
+      color_utils::SkColorToRgbaString(color_text_light);
   substitutions["colorSectionBorder"] =
-      SkColorToRGBComponents(color_section_border);
-  substitutions["colorText"] = SkColorToRGBComponents(color_text);
+      color_utils::SkColorToRgbString(color_section_border);
+  substitutions["colorText"] = color_utils::SkColorToRgbString(color_text);
 
   // For themes that right-align the background, we flip the attribution to the
   // left to avoid conflicts.
diff --git a/chrome/browser/ui/webui/offline/offline_internals_ui_message_handler.cc b/chrome/browser/ui/webui/offline/offline_internals_ui_message_handler.cc
index f114a17..77de128 100644
--- a/chrome/browser/ui/webui/offline/offline_internals_ui_message_handler.cc
+++ b/chrome/browser/ui/webui/offline/offline_internals_ui_message_handler.cc
@@ -115,17 +115,16 @@
 void OfflineInternalsUIMessageHandler::HandleDeletedPagesCallback(
     std::string callback_id,
     offline_pages::DeletePageResult result) {
-  ResolveJavascriptCallback(
-      base::StringValue(callback_id),
-      base::StringValue(GetStringFromDeletePageResult(result)));
+  ResolveJavascriptCallback(base::Value(callback_id),
+                            base::Value(GetStringFromDeletePageResult(result)));
 }
 
 void OfflineInternalsUIMessageHandler::HandleDeletedRequestsCallback(
     std::string callback_id,
     const offline_pages::MultipleItemStatuses& results) {
   ResolveJavascriptCallback(
-      base::StringValue(callback_id),
-      base::StringValue(GetStringFromDeleteRequestResults(results)));
+      base::Value(callback_id),
+      base::Value(GetStringFromDeleteRequestResults(results)));
 }
 
 void OfflineInternalsUIMessageHandler::HandleStoredPagesCallback(
@@ -146,7 +145,7 @@
     offline_page->SetInteger("accessCount", page.access_count);
     offline_page->SetString("originalUrl", page.original_url.spec());
   }
-  ResolveJavascriptCallback(base::StringValue(callback_id), results);
+  ResolveJavascriptCallback(base::Value(callback_id), results);
 }
 
 void OfflineInternalsUIMessageHandler::HandleRequestQueueCallback(
@@ -171,7 +170,7 @@
                                    request->original_url().spec());
     }
   }
-  ResolveJavascriptCallback(base::StringValue(callback_id), save_page_requests);
+  ResolveJavascriptCallback(base::Value(callback_id), save_page_requests);
 }
 
 void OfflineInternalsUIMessageHandler::HandleGetRequestQueue(
@@ -186,7 +185,7 @@
         weak_ptr_factory_.GetWeakPtr(), callback_id));
   } else {
     base::ListValue results;
-    ResolveJavascriptCallback(base::StringValue(callback_id), results);
+    ResolveJavascriptCallback(base::Value(callback_id), results);
   }
 }
 
@@ -202,7 +201,7 @@
                    weak_ptr_factory_.GetWeakPtr(), callback_id));
   } else {
     base::ListValue results;
-    ResolveJavascriptCallback(base::StringValue(callback_id), results);
+    ResolveJavascriptCallback(base::Value(callback_id), results);
   }
 }
 
@@ -221,8 +220,8 @@
 
   ResolveJavascriptCallback(
       *callback_id,
-      base::StringValue(net::NetworkChangeNotifier::IsOffline() ? "Offline"
-                                                                : "Online"));
+      base::Value(net::NetworkChangeNotifier::IsOffline() ? "Offline"
+                                                          : "Online"));
 }
 
 void OfflineInternalsUIMessageHandler::HandleSetRecordRequestQueue(
diff --git a/chrome/browser/ui/webui/options/browser_options_handler.cc b/chrome/browser/ui/webui/options/browser_options_handler.cc
index c711347..bc01b90 100644
--- a/chrome/browser/ui/webui/options/browser_options_handler.cc
+++ b/chrome/browser/ui/webui/options/browser_options_handler.cc
@@ -1312,9 +1312,8 @@
 }
 
 void BrowserOptionsHandler::SetDefaultBrowserUIString(int status_string_id) {
-  base::StringValue status_string(
-      l10n_util::GetStringFUTF16(status_string_id,
-                                 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)));
+  base::Value status_string(l10n_util::GetStringFUTF16(
+      status_string_id, l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)));
 
   base::Value is_default(status_string_id ==
                          IDS_OPTIONS_DEFAULTBROWSER_DEFAULT);
@@ -1559,7 +1558,7 @@
   if (!email.empty()) {
     web_ui()->CallJavascriptFunctionUnsafe(
         "BrowserOptions.updateAccountPicture");
-    base::StringValue email_value(email);
+    base::Value email_value(email);
     web_ui()->CallJavascriptFunctionUnsafe(
         "BrowserOptions.updateAccountPicture", email_value);
     web_ui()->CallJavascriptFunctionUnsafe(
@@ -1827,7 +1826,7 @@
   bool visible = logging_enabled && success;
   web_ui()->CallJavascriptFunctionUnsafe(
       "BrowserOptions.setAudioHistorySectionVisible", base::Value(visible),
-      base::StringValue(audio_history_state));
+      base::Value(audio_history_state));
 }
 
 void BrowserOptionsHandler::HandleRequestGoogleNowAvailable(
@@ -1934,10 +1933,10 @@
     } else {
       base::string16 hotword_help_url =
           base::ASCIIToUTF16(chrome::kHotwordLearnMoreURL);
-      base::StringValue error_message(l10n_util::GetStringUTF16(error));
+      base::Value error_message(l10n_util::GetStringUTF16(error));
       if (error == IDS_HOTWORD_GENERIC_ERROR_MESSAGE) {
-        error_message = base::StringValue(
-            l10n_util::GetStringFUTF16(error, hotword_help_url));
+        error_message =
+            base::Value(l10n_util::GetStringFUTF16(error, hotword_help_url));
       }
       web_ui()->CallJavascriptFunctionUnsafe(function_name, error_message);
     }
diff --git a/chrome/browser/ui/webui/options/certificate_manager_browsertest.cc b/chrome/browser/ui/webui/options/certificate_manager_browsertest.cc
index 3d1545b..ed0ae53 100644
--- a/chrome/browser/ui/webui/options/certificate_manager_browsertest.cc
+++ b/chrome/browser/ui/webui/options/certificate_manager_browsertest.cc
@@ -53,7 +53,7 @@
     policy.Set(policy::key::kOpenNetworkConfiguration,
                policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER,
                policy::POLICY_SOURCE_CLOUD,
-               base::MakeUnique<base::StringValue>(user_policy_blob), nullptr);
+               base::MakeUnique<base::Value>(user_policy_blob), nullptr);
     provider_.UpdateChromePolicy(policy);
     content::RunAllPendingInMessageLoop();
   }
diff --git a/chrome/browser/ui/webui/options/certificate_manager_handler.cc b/chrome/browser/ui/webui/options/certificate_manager_handler.cc
index 799151c..eda33f4 100644
--- a/chrome/browser/ui/webui/options/certificate_manager_handler.cc
+++ b/chrome/browser/ui/webui/options/certificate_manager_handler.cc
@@ -1011,7 +1011,7 @@
 
   // TODO(mattm): check here if root_cert is not a CA cert and show error.
 
-  base::StringValue cert_name(root_cert->subject().GetDisplayName());
+  base::Value cert_name(root_cert->subject().GetDisplayName());
   web_ui()->CallJavascriptFunctionUnsafe(
       "CertificateEditCaTrustOverlay.showImport", cert_name);
 }
@@ -1191,10 +1191,10 @@
 
 void CertificateManagerHandler::ShowError(const std::string& title,
                                           const std::string& error) const {
-  auto title_value = base::MakeUnique<base::StringValue>(title);
-  auto error_value = base::MakeUnique<base::StringValue>(error);
+  auto title_value = base::MakeUnique<base::Value>(title);
+  auto error_value = base::MakeUnique<base::Value>(error);
   auto ok_title_value =
-      base::MakeUnique<base::StringValue>(l10n_util::GetStringUTF8(IDS_OK));
+      base::MakeUnique<base::Value>(l10n_util::GetStringUTF8(IDS_OK));
   auto cancel_title_value = base::Value::CreateNullValue();
   auto ok_callback_value = base::Value::CreateNullValue();
   auto cancel_callback_value = base::Value::CreateNullValue();
@@ -1226,8 +1226,8 @@
     cert_error_list.Append(std::move(dict));
   }
 
-  base::StringValue title_value(title);
-  base::StringValue error_value(error);
+  base::Value title_value(title);
+  base::Value error_value(error);
   web_ui()->CallJavascriptFunctionUnsafe("CertificateImportErrorOverlay.show",
                                          title_value, error_value,
                                          cert_error_list);
diff --git a/chrome/browser/ui/webui/options/chromeos/accounts_options_browsertest.cc b/chrome/browser/ui/webui/options/chromeos/accounts_options_browsertest.cc
index d03da55..34ea81b1 100644
--- a/chrome/browser/ui/webui/options/chromeos/accounts_options_browsertest.cc
+++ b/chrome/browser/ui/webui/options/chromeos/accounts_options_browsertest.cc
@@ -44,8 +44,7 @@
         stub_settings_provider_(base::MakeUnique<StubCrosSettingsProvider>()),
         stub_settings_provider_ptr_(static_cast<StubCrosSettingsProvider*>(
             stub_settings_provider_.get())) {
-    stub_settings_provider_->Set(kDeviceOwner,
-                                 base::StringValue(kTestUsers[0]));
+    stub_settings_provider_->Set(kDeviceOwner, base::Value(kTestUsers[0]));
     for (size_t i = 0; i < arraysize(kTestUsers); ++i) {
       test_users_.push_back(AccountId::FromUserEmail(kTestUsers[i]));
     }
diff --git a/chrome/browser/ui/webui/options/chromeos/accounts_options_handler.cc b/chrome/browser/ui/webui/options/chromeos/accounts_options_handler.cc
index 6a09c111..dfca5fd 100644
--- a/chrome/browser/ui/webui/options/chromeos/accounts_options_handler.cc
+++ b/chrome/browser/ui/webui/options/chromeos/accounts_options_handler.cc
@@ -42,7 +42,7 @@
   if (CrosSettings::Get()->FindEmailInList(kAccountsPrefUsers, username, NULL))
     return false;
   if (service) {
-    base::StringValue username_value(username);
+    base::Value username_value(username);
     service->AppendToList(kAccountsPrefUsers, username_value);
   }
   return true;
@@ -127,7 +127,7 @@
 
   ProfileMetrics::LogProfileDeleteUser(ProfileMetrics::DELETE_PROFILE_SETTINGS);
 
-  base::StringValue canonical_email(gaia::CanonicalizeEmail(email));
+  base::Value canonical_email(gaia::CanonicalizeEmail(email));
   if (OwnerSettingsServiceChromeOS* service =
           OwnerSettingsServiceChromeOS::FromWebUI(web_ui())) {
     service->RemoveFromList(kAccountsPrefUsers, canonical_email);
@@ -168,8 +168,8 @@
   const user_manager::UserList& users =
       user_manager::UserManager::Get()->GetUsers();
   for (const auto* user : users) {
-    new_list->AppendIfNotPresent(base::MakeUnique<base::StringValue>(
-        user->GetAccountId().GetUserEmail()));
+    new_list->AppendIfNotPresent(
+        base::MakeUnique<base::Value>(user->GetAccountId().GetUserEmail()));
   }
 
   if (OwnerSettingsServiceChromeOS* service =
diff --git a/chrome/browser/ui/webui/options/chromeos/change_picture_options_handler.cc b/chrome/browser/ui/webui/options/chromeos/change_picture_options_handler.cc
index 73df723..d1796b1 100644
--- a/chrome/browser/ui/webui/options/chromeos/change_picture_options_handler.cc
+++ b/chrome/browser/ui/webui/options/chromeos/change_picture_options_handler.cc
@@ -285,7 +285,7 @@
       if (previous_image_index_ >=
           default_user_image::kFirstDefaultImageIndex) {
         // User has image from the current set of default images.
-        base::StringValue image_url(
+        base::Value image_url(
             default_user_image::GetDefaultImageUrl(previous_image_index_));
         web_ui()->CallJavascriptFunctionUnsafe(
             "ChangePictureOptions.setSelectedImage", image_url);
@@ -301,7 +301,7 @@
 
 void ChangePictureOptionsHandler::SendProfileImage(const gfx::ImageSkia& image,
                                                    bool should_select) {
-  base::StringValue data_url(webui::GetBitmapDataUrl(*image.bitmap()));
+  base::Value data_url(webui::GetBitmapDataUrl(*image.bitmap()));
   base::Value select(should_select);
   web_ui()->CallJavascriptFunctionUnsafe("ChangePictureOptions.setProfileImage",
                                          data_url, select);
@@ -321,7 +321,7 @@
 
 void ChangePictureOptionsHandler::SendOldImage(const std::string& image_url) {
   previous_image_url_ = image_url;
-  base::StringValue url(image_url);
+  base::Value url(image_url);
   web_ui()->CallJavascriptFunctionUnsafe("ChangePictureOptions.setOldImage",
                                          url);
 }
diff --git a/chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.cc b/chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.cc
index 1133bfc..36f99585 100644
--- a/chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.cc
+++ b/chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.cc
@@ -254,7 +254,7 @@
   if (proxy_cros_settings_parser::IsProxyPref(pref_name)) {
     proxy_cros_settings_parser::SetProxyPrefValue(
         network_guid_, pref_name, value, GetUiProxyConfigService());
-    base::StringValue proxy_type(pref_name);
+    base::Value proxy_type(pref_name);
     web_ui()->CallJavascriptFunctionUnsafe(
         "options.internet.DetailsInternetPage.updateProxySettings", proxy_type);
     ProcessUserMetric(value, metric);
diff --git a/chrome/browser/ui/webui/options/chromeos/pointer_handler.cc b/chrome/browser/ui/webui/options/chromeos/pointer_handler.cc
index 8845d65..a4ee792b 100644
--- a/chrome/browser/ui/webui/options/chromeos/pointer_handler.cc
+++ b/chrome/browser/ui/webui/options/chromeos/pointer_handler.cc
@@ -79,7 +79,7 @@
   } else {
     label = has_mouse_ ? "pointerOverlayTitleMouseOnly" : "";
   }
-  base::StringValue val(label);
+  base::Value val(label);
   web_ui()->CallJavascriptFunctionUnsafe("PointerOverlay.setTitle", val);
 }
 
diff --git a/chrome/browser/ui/webui/options/chromeos/power_handler.cc b/chrome/browser/ui/webui/options/chromeos/power_handler.cc
index 0411e30..8cd2cb2 100644
--- a/chrome/browser/ui/webui/options/chromeos/power_handler.cc
+++ b/chrome/browser/ui/webui/options/chromeos/power_handler.cc
@@ -87,7 +87,7 @@
 void PowerHandler::OnPowerStatusChanged() {
   web_ui()->CallJavascriptFunctionUnsafe(
       "options.PowerOverlay.setBatteryStatusText",
-      base::StringValue(GetStatusValue()));
+      base::Value(GetStatusValue()));
   UpdatePowerSources();
 }
 
@@ -165,7 +165,7 @@
 
   web_ui()->CallJavascriptFunctionUnsafe(
       "options.PowerOverlay.setPowerSources", sources_list,
-      base::StringValue(status->GetCurrentPowerSourceID()),
+      base::Value(status->GetCurrentPowerSourceID()),
       base::Value(status->IsUsbChargerConnected()),
       base::Value(status->IsBatteryTimeBeingCalculated()));
 }
diff --git a/chrome/browser/ui/webui/options/chromeos/shared_options_browsertest.cc b/chrome/browser/ui/webui/options/chromeos/shared_options_browsertest.cc
index 5943771c..7e7b7fa 100644
--- a/chrome/browser/ui/webui/options/chromeos/shared_options_browsertest.cc
+++ b/chrome/browser/ui/webui/options/chromeos/shared_options_browsertest.cc
@@ -102,7 +102,7 @@
             stub_settings_provider_.get())),
         test_owner_account_id_(AccountId::FromUserEmail(kTestOwner)),
         test_non_owner_account_id_(AccountId::FromUserEmail(kTestNonOwner)) {
-    stub_settings_provider_->Set(kDeviceOwner, base::StringValue(kTestOwner));
+    stub_settings_provider_->Set(kDeviceOwner, base::Value(kTestOwner));
   }
 
   ~SharedOptionsTest() override {}
diff --git a/chrome/browser/ui/webui/options/chromeos/storage_manager_handler.cc b/chrome/browser/ui/webui/options/chromeos/storage_manager_handler.cc
index 411fe5e7..98da03ec 100644
--- a/chrome/browser/ui/webui/options/chromeos/storage_manager_handler.cc
+++ b/chrome/browser/ui/webui/options/chromeos/storage_manager_handler.cc
@@ -261,7 +261,7 @@
   updating_downloads_size_ = false;
   web_ui()->CallJavascriptFunctionUnsafe(
       "options.StorageManager.setDownloadsSize",
-      base::StringValue(ui::FormatBytes(size)));
+      base::Value(ui::FormatBytes(size)));
 }
 
 void StorageManagerHandler::UpdateDriveCacheSize() {
@@ -286,7 +286,7 @@
   updating_drive_cache_size_ = false;
   web_ui()->CallJavascriptFunctionUnsafe(
       "options.StorageManager.setDriveCacheSize",
-      base::StringValue(ui::FormatBytes(size)));
+      base::Value(ui::FormatBytes(size)));
 }
 
 void StorageManagerHandler::UpdateBrowsingDataSize() {
@@ -357,8 +357,7 @@
     }
     updating_browsing_data_size_ = false;
     web_ui()->CallJavascriptFunctionUnsafe(
-        "options.StorageManager.setBrowsingDataSize",
-        base::StringValue(size_string));
+        "options.StorageManager.setBrowsingDataSize", base::Value(size_string));
   }
 }
 
@@ -385,7 +384,7 @@
     updating_other_users_size_ = false;
     web_ui()->CallJavascriptFunctionUnsafe(
         "options.StorageManager.setOtherUsersSize",
-        base::StringValue(ui::FormatBytes(0)));
+        base::Value(ui::FormatBytes(0)));
   }
 }
 
@@ -403,8 +402,7 @@
     }
     updating_other_users_size_ = false;
     web_ui()->CallJavascriptFunctionUnsafe(
-        "options.StorageManager.setOtherUsersSize",
-        base::StringValue(size_string));
+        "options.StorageManager.setOtherUsersSize", base::Value(size_string));
   }
 }
 
@@ -443,7 +441,7 @@
   }
   updating_arc_size_ = false;
   web_ui()->CallJavascriptFunctionUnsafe("options.StorageManager.setArcSize",
-                                         base::StringValue(size_string));
+                                         base::Value(size_string));
 }
 
 void StorageManagerHandler::OnClearDriveCacheDone(bool success) {
diff --git a/chrome/browser/ui/webui/options/clear_browser_data_handler.cc b/chrome/browser/ui/webui/options/clear_browser_data_handler.cc
index 4037188..157d1b6 100644
--- a/chrome/browser/ui/webui/options/clear_browser_data_handler.cc
+++ b/chrome/browser/ui/webui/options/clear_browser_data_handler.cc
@@ -145,7 +145,7 @@
   }
 
   web_ui()->CallJavascriptFunctionUnsafe(
-      "ClearBrowserDataOverlay.setBannerText", base::StringValue(text));
+      "ClearBrowserDataOverlay.setBannerText", base::Value(text));
 }
 
 void ClearBrowserDataHandler::OnPageOpened(const base::ListValue* value) {
@@ -386,8 +386,8 @@
   DCHECK(AreCountersEnabled());
   web_ui()->CallJavascriptFunctionUnsafe(
       "ClearBrowserDataOverlay.updateCounter",
-      base::StringValue(result->source()->GetPrefName()),
-      base::StringValue(GetChromeCounterTextFromResult(result.get())));
+      base::Value(result->source()->GetPrefName()),
+      base::Value(GetChromeCounterTextFromResult(result.get())));
 }
 
 void ClearBrowserDataHandler::OnStateChanged(syncer::SyncService* sync) {
diff --git a/chrome/browser/ui/webui/options/content_settings_handler.cc b/chrome/browser/ui/webui/options/content_settings_handler.cc
index f51ac23..491cb0b1 100644
--- a/chrome/browser/ui/webui/options/content_settings_handler.cc
+++ b/chrome/browser/ui/webui/options/content_settings_handler.cc
@@ -876,7 +876,7 @@
     }
   }
 
-  base::StringValue type_string(site_settings::ContentSettingsTypeToGroupName(
+  base::Value type_string(site_settings::ContentSettingsTypeToGroupName(
       CONTENT_SETTINGS_TYPE_GEOLOCATION));
   web_ui()->CallJavascriptFunctionUnsafe("ContentSettings.setExceptions",
                                          type_string, exceptions);
@@ -916,7 +916,7 @@
                                         i->source));
   }
 
-  base::StringValue type_string(site_settings::ContentSettingsTypeToGroupName(
+  base::Value type_string(site_settings::ContentSettingsTypeToGroupName(
       CONTENT_SETTINGS_TYPE_NOTIFICATIONS));
   web_ui()->CallJavascriptFunctionUnsafe("ContentSettings.setExceptions",
                                          type_string, exceptions);
@@ -990,7 +990,7 @@
   base::ListValue exceptions;
   site_settings::GetChooserExceptionsFromProfile(
       Profile::FromWebUI(web_ui()), false, chooser_type, &exceptions);
-  base::StringValue type_string(chooser_type.name);
+  base::Value type_string(chooser_type.name);
   web_ui()->CallJavascriptFunctionUnsafe("ContentSettings.setExceptions",
                                          type_string, exceptions);
 
@@ -1005,7 +1005,7 @@
   base::ListValue exceptions;
   site_settings::GetChooserExceptionsFromProfile(
       Profile::FromWebUI(web_ui()), true, chooser_type, &exceptions);
-  base::StringValue type_string(chooser_type.name);
+  base::Value type_string(chooser_type.name);
   web_ui()->CallJavascriptFunctionUnsafe("ContentSettings.setOTRExceptions",
                                          type_string, exceptions);
 }
@@ -1070,7 +1070,7 @@
     zoom_levels_exceptions.Append(std::move(exception));
   }
 
-  base::StringValue type_string(kZoomContentType);
+  base::Value type_string(kZoomContentType);
   web_ui()->CallJavascriptFunctionUnsafe("ContentSettings.setExceptions",
                                          type_string, zoom_levels_exceptions);
 }
@@ -1085,8 +1085,7 @@
   site_settings::GetExceptionsFromHostContentSettingsMap(
       settings_map, type, extension_registry, web_ui(), /*incognito=*/false,
       /*filter=*/nullptr, &exceptions);
-  base::StringValue type_string(
-      site_settings::ContentSettingsTypeToGroupName(type));
+  base::Value type_string(site_settings::ContentSettingsTypeToGroupName(type));
   web_ui()->CallJavascriptFunctionUnsafe("ContentSettings.setExceptions",
                                          type_string, exceptions);
 
@@ -1115,8 +1114,7 @@
   site_settings::GetExceptionsFromHostContentSettingsMap(
       otr_settings_map, type, extension_registry, web_ui(), /*incognito=*/true,
       /*filter=*/nullptr, &exceptions);
-  base::StringValue type_string(
-      site_settings::ContentSettingsTypeToGroupName(type));
+  base::Value type_string(site_settings::ContentSettingsTypeToGroupName(type));
   web_ui()->CallJavascriptFunctionUnsafe("ContentSettings.setOTRExceptions",
                                          type_string, exceptions);
 }
@@ -1350,9 +1348,9 @@
       ContentSettingsPattern::FromString(pattern_string);
 
   web_ui()->CallJavascriptFunctionUnsafe(
-      "ContentSettings.patternValidityCheckComplete",
-      base::StringValue(type_string), base::StringValue(mode_string),
-      base::StringValue(pattern_string), base::Value(pattern.IsValid()));
+      "ContentSettings.patternValidityCheckComplete", base::Value(type_string),
+      base::Value(mode_string), base::Value(pattern_string),
+      base::Value(pattern.IsValid()));
 }
 
 Profile* ContentSettingsHandler::GetProfile() {
@@ -1413,11 +1411,10 @@
   if (show_link != show) {
     web_ui()->CallJavascriptFunctionUnsafe(
         "ContentSettings.showMediaPepperFlashLink",
-        base::StringValue(link_type == DEFAULT_SETTING ? "default"
-                                                       : "exceptions"),
-        base::StringValue(content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
-                              ? "mic"
-                              : "camera"),
+        base::Value(link_type == DEFAULT_SETTING ? "default" : "exceptions"),
+        base::Value(content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
+                        ? "mic"
+                        : "camera"),
         base::Value(show));
     show_link = show;
   }
@@ -1475,7 +1472,7 @@
 
   web_ui()->CallJavascriptFunctionUnsafe(
       "ContentSettings.setDevicesMenuVisibility",
-      base::StringValue(site_settings::ContentSettingsTypeToGroupName(type)),
+      base::Value(site_settings::ContentSettingsTypeToGroupName(type)),
       base::Value(!settings.policy_disable));
 }
 
diff --git a/chrome/browser/ui/webui/options/core_options_handler.cc b/chrome/browser/ui/webui/options/core_options_handler.cc
index 5735164..4ab5062 100644
--- a/chrome/browser/ui/webui/options/core_options_handler.cc
+++ b/chrome/browser/ui/webui/options/core_options_handler.cc
@@ -579,7 +579,7 @@
         return;
       }
       GURL fixed = url_formatter::FixupURL(original, std::string());
-      temp_value.reset(new base::StringValue(fixed.spec()));
+      temp_value.reset(new base::Value(fixed.spec()));
       value = temp_value.get();
       break;
     }
diff --git a/chrome/browser/ui/webui/options/create_profile_handler.cc b/chrome/browser/ui/webui/options/create_profile_handler.cc
index 800471a..f820a99 100644
--- a/chrome/browser/ui/webui/options/create_profile_handler.cc
+++ b/chrome/browser/ui/webui/options/create_profile_handler.cc
@@ -230,8 +230,7 @@
   profile_creation_type_ = NO_CREATION_IN_PROGRESS;
   profile_path_being_created_.clear();
   web_ui()->CallJavascriptFunctionUnsafe(
-      GetJavascriptMethodName(PROFILE_CREATION_ERROR),
-      base::StringValue(error));
+      GetJavascriptMethodName(PROFILE_CREATION_ERROR), base::Value(error));
   // The ProfileManager calls us back with a NULL profile in some cases.
   if (profile) {
     webui::DeleteProfileAtPath(profile->GetPath(),
@@ -434,7 +433,7 @@
     const base::string16& warning) {
   DCHECK_EQ(SUPERVISED_PROFILE_CREATION, profile_creation_type_);
   web_ui()->CallJavascriptFunctionUnsafe(
-      "BrowserOptions.showCreateProfileWarning", base::StringValue(warning));
+      "BrowserOptions.showCreateProfileWarning", base::Value(warning));
 }
 
 void CreateProfileHandler::RecordSupervisedProfileCreationMetrics(
diff --git a/chrome/browser/ui/webui/options/easy_unlock_handler.cc b/chrome/browser/ui/webui/options/easy_unlock_handler.cc
index 5349133..ff3cf2dd 100644
--- a/chrome/browser/ui/webui/options/easy_unlock_handler.cc
+++ b/chrome/browser/ui/webui/options/easy_unlock_handler.cc
@@ -91,8 +91,7 @@
       break;
   }
   web_ui()->CallJavascriptFunctionUnsafe(
-      "EasyUnlockTurnOffOverlay.updateUIState",
-      base::StringValue(status_string));
+      "EasyUnlockTurnOffOverlay.updateUIState", base::Value(status_string));
 }
 
 void EasyUnlockHandler::HandleGetTurnOffFlowStatus(
diff --git a/chrome/browser/ui/webui/options/font_settings_handler.cc b/chrome/browser/ui/webui/options/font_settings_handler.cc
index f57a800..5eeb8a2 100644
--- a/chrome/browser/ui/webui/options/font_settings_handler.cc
+++ b/chrome/browser/ui/webui/options/font_settings_handler.cc
@@ -206,7 +206,7 @@
 }
 
 void FontSettingsHandler::SetUpStandardFontSample() {
-  base::StringValue font_value(
+  base::Value font_value(
       FontSettingsUtilities::ResolveFontList(standard_font_.GetValue()));
   base::Value size_value(default_font_size_.GetValue());
   web_ui()->CallJavascriptFunctionUnsafe("FontSettings.setUpStandardFontSample",
@@ -214,7 +214,7 @@
 }
 
 void FontSettingsHandler::SetUpSerifFontSample() {
-  base::StringValue font_value(
+  base::Value font_value(
       FontSettingsUtilities::ResolveFontList(serif_font_.GetValue()));
   base::Value size_value(default_font_size_.GetValue());
   web_ui()->CallJavascriptFunctionUnsafe("FontSettings.setUpSerifFontSample",
@@ -222,7 +222,7 @@
 }
 
 void FontSettingsHandler::SetUpSansSerifFontSample() {
-  base::StringValue font_value(
+  base::Value font_value(
       FontSettingsUtilities::ResolveFontList(sans_serif_font_.GetValue()));
   base::Value size_value(default_font_size_.GetValue());
   web_ui()->CallJavascriptFunctionUnsafe(
@@ -230,7 +230,7 @@
 }
 
 void FontSettingsHandler::SetUpFixedFontSample() {
-  base::StringValue font_value(
+  base::Value font_value(
       FontSettingsUtilities::ResolveFontList(fixed_font_.GetValue()));
   base::Value size_value(default_fixed_font_size_.GetValue());
   web_ui()->CallJavascriptFunctionUnsafe("FontSettings.setUpFixedFontSample",
diff --git a/chrome/browser/ui/webui/options/language_options_handler_common.cc b/chrome/browser/ui/webui/options/language_options_handler_common.cc
index 4b6b396..c2f6468 100644
--- a/chrome/browser/ui/webui/options/language_options_handler_common.cc
+++ b/chrome/browser/ui/webui/options/language_options_handler_common.cc
@@ -166,21 +166,21 @@
     const std::string& language) {
   web_ui()->CallJavascriptFunctionUnsafe(
       "options.LanguageOptions.onDictionaryDownloadBegin",
-      base::StringValue(language));
+      base::Value(language));
 }
 
 void LanguageOptionsHandlerCommon::OnHunspellDictionaryDownloadSuccess(
     const std::string& language) {
   web_ui()->CallJavascriptFunctionUnsafe(
       "options.LanguageOptions.onDictionaryDownloadSuccess",
-      base::StringValue(language));
+      base::Value(language));
 }
 
 void LanguageOptionsHandlerCommon::OnHunspellDictionaryDownloadFailure(
     const std::string& language) {
   web_ui()->CallJavascriptFunctionUnsafe(
       "options.LanguageOptions.onDictionaryDownloadFailure",
-      base::StringValue(language));
+      base::Value(language));
 }
 
 base::DictionaryValue* LanguageOptionsHandlerCommon::GetUILanguageCodeSet() {
@@ -232,7 +232,7 @@
       "LanguageOptions_UiLanguageChange_%s", language_code.c_str());
   content::RecordComputedAction(action);
   SetApplicationLocale(language_code);
-  base::StringValue language_value(language_code);
+  base::Value language_value(language_code);
   web_ui()->CallJavascriptFunctionUnsafe(
       "options.LanguageOptions.uiLanguageSaved", language_value);
 }
diff --git a/chrome/browser/ui/webui/options/manage_profile_handler.cc b/chrome/browser/ui/webui/options/manage_profile_handler.cc
index 2dbc2697..61f6b8e 100644
--- a/chrome/browser/ui/webui/options/manage_profile_handler.cc
+++ b/chrome/browser/ui/webui/options/manage_profile_handler.cc
@@ -218,13 +218,13 @@
 void ManageProfileHandler::OnProfileNameChanged(
     const base::FilePath& profile_path,
     const base::string16& old_profile_name) {
-  base::StringValue value(kManageProfileIdentifier);
+  base::Value value(kManageProfileIdentifier);
   SendProfileIconsAndNames(value);
 }
 
 void ManageProfileHandler::OnProfileAvatarChanged(
     const base::FilePath& profile_path) {
-  base::StringValue value(kManageProfileIdentifier);
+  base::Value value(kManageProfileIdentifier);
   SendProfileIconsAndNames(value);
 }
 
@@ -273,7 +273,7 @@
   DCHECK(ok);
   DCHECK(mode == kCreateProfileIdentifier || mode == kManageProfileIdentifier);
   if (ok) {
-    base::StringValue value(mode);
+    base::Value value(mode);
     SendProfileIconsAndNames(value);
   }
 }
@@ -293,8 +293,7 @@
       "ManageProfileOverlay.receiveNewProfileDefaults", profile_info);
 }
 
-void ManageProfileHandler::SendProfileIconsAndNames(
-    const base::StringValue& mode) {
+void ManageProfileHandler::SendProfileIconsAndNames(const base::Value& mode) {
   base::ListValue image_url_list;
   base::ListValue default_name_list;
 
@@ -435,8 +434,8 @@
   if (gaia_name.empty())
     return;
 
-  base::StringValue gaia_name_value(gaia_name);
-  base::StringValue mode_value(kManageProfileIdentifier);
+  base::Value gaia_name_value(gaia_name);
+  base::Value mode_value(kManageProfileIdentifier);
   web_ui()->CallJavascriptFunctionUnsafe("ManageProfileOverlay.setProfileName",
                                          gaia_name_value, mode_value);
 }
@@ -488,7 +487,7 @@
                     state == GoogleServiceAuthError::ACCOUNT_DELETED ||
                     state == GoogleServiceAuthError::ACCOUNT_DISABLED);
   web_ui()->CallJavascriptFunctionUnsafe(
-      "CreateProfileOverlay.updateSignedInStatus", base::StringValue(username),
+      "CreateProfileOverlay.updateSignedInStatus", base::Value(username),
       base::Value(has_error));
 
   OnCreateSupervisedUserPrefChange();
diff --git a/chrome/browser/ui/webui/options/manage_profile_handler.h b/chrome/browser/ui/webui/options/manage_profile_handler.h
index f677f015..b0688bf 100644
--- a/chrome/browser/ui/webui/options/manage_profile_handler.h
+++ b/chrome/browser/ui/webui/options/manage_profile_handler.h
@@ -16,7 +16,6 @@
 
 namespace base {
 class Value;
-using StringValue = Value;
 }
 
 namespace options {
@@ -65,7 +64,7 @@
 
   // Send all profile icons and their default names to the overlay.
   // |mode| is the dialog mode, i.e. "create" or "manage".
-  void SendProfileIconsAndNames(const base::StringValue& mode);
+  void SendProfileIconsAndNames(const base::Value& mode);
 
   // Sends an object to WebUI of the form:
   //   profileNames = {
diff --git a/chrome/browser/ui/webui/options/media_devices_selection_handler.cc b/chrome/browser/ui/webui/options/media_devices_selection_handler.cc
index 445562d..df8b459 100644
--- a/chrome/browser/ui/webui/options/media_devices_selection_handler.cc
+++ b/chrome/browser/ui/webui/options/media_devices_selection_handler.cc
@@ -130,8 +130,8 @@
   if (!devices.empty() && default_id.empty())
     default_id = devices[0].id;
 
-  base::StringValue default_value(default_id);
-  base::StringValue type_value(device_type);
+  base::Value default_value(default_id);
+  base::Value type_value(device_type);
   web_ui()->CallJavascriptFunctionUnsafe("ContentSettings.updateDevicesMenu",
                                          type_value, device_list,
                                          default_value);
diff --git a/chrome/browser/ui/webui/options/password_manager_handler.cc b/chrome/browser/ui/webui/options/password_manager_handler.cc
index c3aacdb3..dd80fb4 100644
--- a/chrome/browser/ui/webui/options/password_manager_handler.cc
+++ b/chrome/browser/ui/webui/options/password_manager_handler.cc
@@ -247,7 +247,7 @@
   // Call back the front end to reveal the password.
   web_ui()->CallJavascriptFunctionUnsafe("PasswordManager.showPassword",
                                          base::Value(static_cast<int>(index)),
-                                         base::StringValue(password_value));
+                                         base::Value(password_value));
 }
 
 void PasswordManagerHandler::HandleUpdatePasswordLists(
diff --git a/chrome/browser/ui/webui/options/preferences_browsertest.cc b/chrome/browser/ui/webui/options/preferences_browsertest.cc
index 49f0867..545e559 100644
--- a/chrome/browser/ui/webui/options/preferences_browsertest.cc
+++ b/chrome/browser/ui/webui/options/preferences_browsertest.cc
@@ -260,7 +260,7 @@
   ASSERT_TRUE(pref->GetAsDictionary(&dict));
   VerifyKeyValue(*dict, "value", *value);
   if (!controlledBy.empty())
-    VerifyKeyValue(*dict, "controlledBy", base::StringValue(controlledBy));
+    VerifyKeyValue(*dict, "controlledBy", base::Value(controlledBy));
   else
     EXPECT_FALSE(dict->HasKey("controlledBy"));
 
@@ -689,7 +689,7 @@
 
   // String pref.
   pref_names_.push_back(chromeos::kReleaseChannel);
-  default_values_.push_back(base::MakeUnique<base::StringValue>(""));
+  default_values_.push_back(base::MakeUnique<base::Value>(""));
 
   // List pref.
   pref_names_.push_back(chromeos::kAccountsPrefUsers);
@@ -712,9 +712,9 @@
   // Non-privileged string pref.
   pref_names_.push_back(chromeos::kSystemTimezone);
   default_values_.push_back(
-      base::MakeUnique<base::StringValue>("America/Los_Angeles"));
+      base::MakeUnique<base::Value>("America/Los_Angeles"));
   non_default_values_.push_back(
-      base::MakeUnique<base::StringValue>("America/New_York"));
+      base::MakeUnique<base::Value>("America/New_York"));
   decorated_non_default_values.push_back(
       non_default_values_.back()->CreateDeepCopy());
 
@@ -764,7 +764,7 @@
   // String pref.
   pref_names_.push_back(chromeos::kReleaseChannel);
   non_default_values_.push_back(
-      base::MakeUnique<base::StringValue>("stable-channel"));
+      base::MakeUnique<base::Value>("stable-channel"));
   decorated_non_default_values.push_back(
       non_default_values_.back()->CreateDeepCopy());
 
@@ -811,7 +811,7 @@
   // Non-privileged string pref.
   pref_names_.push_back(chromeos::kSystemTimezone);
   non_default_values_.push_back(
-      base::MakeUnique<base::StringValue>("America/New_York"));
+      base::MakeUnique<base::Value>("America/New_York"));
   decorated_non_default_values.push_back(
       non_default_values_.back()->CreateDeepCopy());
 
@@ -872,9 +872,8 @@
                              shill::kTypeEthernet,
                              shill::kStateOnline,
                              true /* add_to_visible */ );
-    service_test->SetServiceProperty("stub_ethernet",
-                                     shill::kProfileProperty,
-                                     base::StringValue(kUserProfilePath));
+    service_test->SetServiceProperty("stub_ethernet", shill::kProfileProperty,
+                                     base::Value(kUserProfilePath));
     profile_test->AddService(kUserProfilePath, "stub_wifi2");
   }
 
@@ -897,7 +896,7 @@
     policy::PolicyMap map;
     map.Set(policy_name, policy::POLICY_LEVEL_MANDATORY, scope,
             policy::POLICY_SOURCE_CLOUD,
-            base::MakeUnique<base::StringValue>(onc_policy), nullptr);
+            base::MakeUnique<base::Value>(onc_policy), nullptr);
     policy_provider_.UpdateChromePolicy(map);
 
     content::RunAllPendingInMessageLoop();
@@ -960,8 +959,7 @@
 
   // String pref.
   pref_names_.push_back(chromeos::proxy_cros_settings_parser::kProxySingleHttp);
-  non_default_values_.push_back(
-      base::MakeUnique<base::StringValue>("127.0.0.1"));
+  non_default_values_.push_back(base::MakeUnique<base::Value>("127.0.0.1"));
 
   // List pref.
   pref_names_.push_back(chromeos::proxy_cros_settings_parser::kProxyIgnoreList);
@@ -1036,8 +1034,8 @@
 
 IN_PROC_BROWSER_TEST_F(ProxyPreferencesBrowserTest, UserProxyPolicy) {
   policy_names_.push_back(policy::key::kProxyMode);
-  default_values_.push_back(base::MakeUnique<base::StringValue>(
-      ProxyPrefs::kAutoDetectProxyModeName));
+  default_values_.push_back(
+      base::MakeUnique<base::Value>(ProxyPrefs::kAutoDetectProxyModeName));
   SetUserPolicies(policy_names_, default_values_,
                   policy::POLICY_LEVEL_MANDATORY);
   content::RunAllPendingInMessageLoop();
@@ -1065,7 +1063,7 @@
   SetProxyPref(chromeos::proxy_cros_settings_parser::kProxySingleHttpPort,
                base::Value(123));
   SetProxyPref(chromeos::proxy_cros_settings_parser::kProxySingleHttp,
-               base::StringValue("www.adomain.xy"));
+               base::Value("www.adomain.xy"));
 
   VerifyCurrentProxyServer("www.adomain.xy:123",
                            onc::ONC_SOURCE_NONE);
@@ -1082,13 +1080,13 @@
 
   // Set hosts but no ports.
   SetProxyPref(chromeos::proxy_cros_settings_parser::kProxyHttpUrl,
-               base::StringValue("a.com"));
+               base::Value("a.com"));
   SetProxyPref(chromeos::proxy_cros_settings_parser::kProxyHttpsUrl,
-               base::StringValue("4.3.2.1"));
+               base::Value("4.3.2.1"));
   SetProxyPref(chromeos::proxy_cros_settings_parser::kProxyFtpUrl,
-               base::StringValue("c.com"));
+               base::Value("c.com"));
   SetProxyPref(chromeos::proxy_cros_settings_parser::kProxySocks,
-               base::StringValue("d.com"));
+               base::Value("d.com"));
 
   // Verify default ports.
   VerifyCurrentProxyServer(
diff --git a/chrome/browser/ui/webui/options/search_engine_manager_handler.cc b/chrome/browser/ui/webui/options/search_engine_manager_handler.cc
index 41b1642..9979d8b 100644
--- a/chrome/browser/ui/webui/options/search_engine_manager_handler.cc
+++ b/chrome/browser/ui/webui/options/search_engine_manager_handler.cc
@@ -296,7 +296,7 @@
   validity.SetBoolean("name", edit_controller_->IsTitleValid(name));
   validity.SetBoolean("keyword", edit_controller_->IsKeywordValid(keyword));
   validity.SetBoolean("url", edit_controller_->IsURLValid(url));
-  base::StringValue indexValue(modelIndex);
+  base::Value indexValue(modelIndex);
   web_ui()->CallJavascriptFunctionUnsafe(
       "SearchEngineManager.validityCheckCallback", validity, indexValue);
 }
diff --git a/chrome/browser/ui/webui/options/supervised_user_create_confirm_handler.cc b/chrome/browser/ui/webui/options/supervised_user_create_confirm_handler.cc
index d0f8037..9ff957d 100644
--- a/chrome/browser/ui/webui/options/supervised_user_create_confirm_handler.cc
+++ b/chrome/browser/ui/webui/options/supervised_user_create_confirm_handler.cc
@@ -54,7 +54,7 @@
   // affected profile and update or close as needed.
   void OnProfileWasRemoved(const base::FilePath& profile_path,
                            const base::string16& profile_name) override {
-    std::unique_ptr<base::StringValue> profile_path_value(
+    std::unique_ptr<base::Value> profile_path_value(
         base::CreateFilePathValue(profile_path));
     create_confirm_handler_->web_ui()->CallJavascriptFunctionUnsafe(
         "SupervisedUserCreateConfirmOverlay.onDeletedProfile",
@@ -68,11 +68,11 @@
         GetProfileAttributesWithPath(profile_path, &entry))
       return;
     base::string16 new_profile_name = entry->GetName();
-    std::unique_ptr<base::StringValue> profile_path_value(
+    std::unique_ptr<base::Value> profile_path_value(
         base::CreateFilePathValue(profile_path));
     create_confirm_handler_->web_ui()->CallJavascriptFunctionUnsafe(
         "SupervisedUserCreateConfirmOverlay.onUpdatedProfileName",
-        *profile_path_value, base::StringValue(new_profile_name));
+        *profile_path_value, base::Value(new_profile_name));
   }
 
   // Weak.
diff --git a/chrome/browser/ui/webui/options/sync_setup_handler.cc b/chrome/browser/ui/webui/options/sync_setup_handler.cc
index 4e2457e..6c4e9b6 100644
--- a/chrome/browser/ui/webui/options/sync_setup_handler.cc
+++ b/chrome/browser/ui/webui/options/sync_setup_handler.cc
@@ -285,7 +285,7 @@
 }
 
 void SyncSetupHandler::ConfigureSyncDone() {
-  base::StringValue page("done");
+  base::Value page("done");
   web_ui()->CallJavascriptFunctionUnsafe("SyncSetupOverlay.showSyncSetupPage",
                                          page);
 
@@ -427,7 +427,7 @@
 
 void SyncSetupHandler::DisplaySpinner() {
   configuring_sync_ = true;
-  base::StringValue page("spinner");
+  base::Value page("spinner");
   base::DictionaryValue args;
 
   const int kTimeoutSec = 30;
@@ -450,7 +450,7 @@
   // Do not listen to sync startup events.
   sync_startup_tracker_.reset();
 
-  base::StringValue page("timeout");
+  base::Value page("timeout");
   base::DictionaryValue args;
   web_ui()->CallJavascriptFunctionUnsafe("SyncSetupOverlay.showSyncSetupPage",
                                          page, args);
@@ -797,7 +797,7 @@
 
 void SyncSetupHandler::CloseUI() {
   CloseSyncSetup();
-  base::StringValue page("done");
+  base::Value page("done");
   web_ui()->CallJavascriptFunctionUnsafe("SyncSetupOverlay.showSyncSetupPage",
                                          page);
 }
@@ -942,7 +942,7 @@
         GetStringUTF16(IDS_SYNC_FULL_ENCRYPTION_DATA));
   }
 
-  base::StringValue page("configure");
+  base::Value page("configure");
   web_ui()->CallJavascriptFunctionUnsafe("SyncSetupOverlay.showSyncSetupPage",
                                          page, args);
 
diff --git a/chrome/browser/ui/webui/password_manager_internals/password_manager_internals_ui.cc b/chrome/browser/ui/webui/password_manager_internals/password_manager_internals_ui.cc
index 4b89d9c6..976f10af 100644
--- a/chrome/browser/ui/webui/password_manager_internals/password_manager_internals_ui.cc
+++ b/chrome/browser/ui/webui/password_manager_internals/password_manager_internals_ui.cc
@@ -99,7 +99,7 @@
     return;
   std::string no_quotes(text);
   std::replace(no_quotes.begin(), no_quotes.end(), '"', ' ');
-  base::StringValue text_string_value(net::EscapeForHTML(no_quotes));
+  base::Value text_string_value(net::EscapeForHTML(no_quotes));
   web_ui()->CallJavascriptFunctionUnsafe("addSavePasswordProgressLog",
                                          text_string_value);
 }
diff --git a/chrome/browser/ui/webui/policy_indicator_localized_strings_provider.cc b/chrome/browser/ui/webui/policy_indicator_localized_strings_provider.cc
index c36cf177..53157556 100644
--- a/chrome/browser/ui/webui/policy_indicator_localized_strings_provider.cc
+++ b/chrome/browser/ui/webui/policy_indicator_localized_strings_provider.cc
@@ -18,6 +18,8 @@
   html_source->AddLocalizedString(
       "controlledSettingRecommendedDiffers",
       IDS_OPTIONS_CONTROLLED_SETTING_HAS_RECOMMENDATION);
+  html_source->AddLocalizedString("controlledSettingExtension",
+                                  IDS_OPTIONS_CONTROLLED_SETTING_EXTENSION);
 #if defined(OS_CHROMEOS)
   html_source->AddLocalizedString("controlledSettingShared",
                                   IDS_OPTIONS_CONTROLLED_SETTING_SHARED);
diff --git a/chrome/browser/ui/webui/policy_ui_browsertest.cc b/chrome/browser/ui/webui/policy_ui_browsertest.cc
index 6939af92..c6ed1f25 100644
--- a/chrome/browser/ui/webui/policy_ui_browsertest.cc
+++ b/chrome/browser/ui/webui/policy_ui_browsertest.cc
@@ -224,7 +224,7 @@
   expected_values[policy::key::kRestoreOnStartupURLs] = "aaa,bbb,ccc";
   values.Set(policy::key::kHomepageLocation, policy::POLICY_LEVEL_MANDATORY,
              policy::POLICY_SCOPE_MACHINE, policy::POLICY_SOURCE_CLOUD,
-             base::MakeUnique<base::StringValue>("http://google.com"), nullptr);
+             base::MakeUnique<base::Value>("http://google.com"), nullptr);
   expected_values[policy::key::kHomepageLocation] = "http://google.com";
   values.Set(policy::key::kRestoreOnStartup, policy::POLICY_LEVEL_RECOMMENDED,
              policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD,
diff --git a/chrome/browser/ui/webui/policy_ui_handler.cc b/chrome/browser/ui/webui/policy_ui_handler.cc
index a18f2e59..9d8f9444 100644
--- a/chrome/browser/ui/webui/policy_ui_handler.cc
+++ b/chrome/browser/ui/webui/policy_ui_handler.cc
@@ -173,13 +173,13 @@
 }
 
 // Utility function that returns a JSON serialization of the given |dict|.
-std::unique_ptr<base::StringValue> DictionaryToJSONString(
+std::unique_ptr<base::Value> DictionaryToJSONString(
     const base::DictionaryValue& dict) {
   std::string json_string;
   base::JSONWriter::WriteWithOptions(dict,
                                      base::JSONWriter::OPTIONS_PRETTY_PRINT,
                                      &json_string);
-  return base::MakeUnique<base::StringValue>(json_string);
+  return base::MakeUnique<base::Value>(json_string);
 }
 
 // Returns a copy of |value| with some values converted to a representation that
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_handler.cc b/chrome/browser/ui/webui/print_preview/print_preview_handler.cc
index 8c783b5e..862ade1055 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_handler.cc
+++ b/chrome/browser/ui/webui/print_preview/print_preview_handler.cc
@@ -1095,8 +1095,8 @@
   std::string printer_name;
   if (!args->GetString(0, &callback_id) || !args->GetString(1, &printer_name) ||
       callback_id.empty() || printer_name.empty()) {
-    RejectJavascriptCallback(base::StringValue(callback_id),
-                             base::StringValue(printer_name));
+    RejectJavascriptCallback(base::Value(callback_id),
+                             base::Value(printer_name));
     return;
   }
 
@@ -1287,9 +1287,8 @@
 void PrintPreviewHandler::SendAccessToken(const std::string& type,
                                           const std::string& access_token) {
   VLOG(1) << "Get getAccessToken finished";
-  web_ui()->CallJavascriptFunctionUnsafe("onDidGetAccessToken",
-                                         base::StringValue(type),
-                                         base::StringValue(access_token));
+  web_ui()->CallJavascriptFunctionUnsafe(
+      "onDidGetAccessToken", base::Value(type), base::Value(access_token));
 }
 
 void PrintPreviewHandler::SendPrinterCapabilities(
@@ -1298,7 +1297,7 @@
   if (!settings_info) {
     VLOG(1) << "Get printer capabilities failed";
     web_ui()->CallJavascriptFunctionUnsafe("failedToGetPrinterCapabilities",
-                                           base::StringValue(printer_name));
+                                           base::Value(printer_name));
     return;
   }
   VLOG(1) << "Get printer capabilities finished";
@@ -1327,7 +1326,7 @@
   response->SetBoolean("success", success);
   response->Set("capabilities", std::move(caps));
 
-  ResolveJavascriptCallback(base::StringValue(callback_id), *response);
+  ResolveJavascriptCallback(base::Value(callback_id), *response);
 }
 
 void PrintPreviewHandler::SetupPrinterList(
@@ -1365,7 +1364,7 @@
                                    data->size());
   std::string base64_data;
   base::Base64Encode(raw_data, &base64_data);
-  base::StringValue data_value(base64_data);
+  base::Value data_value(base64_data);
 
   web_ui()->CallJavascriptFunctionUnsafe("printToCloud", data_value);
 }
@@ -1658,7 +1657,7 @@
 
 void PrintPreviewHandler::SendPrivetCapabilitiesError(
     const std::string& device_name) {
-  base::StringValue name_value(device_name);
+  base::Value name_value(device_name);
   web_ui()->CallJavascriptFunctionUnsafe("failedToGetPrivetPrinterCapabilities",
                                          name_value);
 }
@@ -1748,13 +1747,12 @@
     const base::DictionaryValue& printer_info) {
   if (printer_info.empty()) {
     web_ui()->CallJavascriptFunctionUnsafe("failedToResolveProvisionalPrinter",
-                                           base::StringValue(printer_id));
+                                           base::Value(printer_id));
     return;
   }
 
   web_ui()->CallJavascriptFunctionUnsafe("onProvisionalPrinterResolved",
-                                         base::StringValue(printer_id),
-                                         printer_info);
+                                         base::Value(printer_id), printer_info);
 }
 
 void PrintPreviewHandler::OnGotExtensionPrinterCapabilities(
@@ -1762,14 +1760,12 @@
     const base::DictionaryValue& capabilities) {
   if (capabilities.empty()) {
     web_ui()->CallJavascriptFunctionUnsafe(
-        "failedToGetExtensionPrinterCapabilities",
-        base::StringValue(printer_id));
+        "failedToGetExtensionPrinterCapabilities", base::Value(printer_id));
     return;
   }
 
   web_ui()->CallJavascriptFunctionUnsafe("onExtensionCapabilitiesSet",
-                                         base::StringValue(printer_id),
-                                         capabilities);
+                                         base::Value(printer_id), capabilities);
 }
 
 void PrintPreviewHandler::OnExtensionPrintResult(bool success,
@@ -1782,7 +1778,7 @@
   // TODO(tbarzic): This function works for extension printers case too, but it
   // should be renamed to something more generic.
   web_ui()->CallJavascriptFunctionUnsafe("onPrivetPrintFailed",
-                                         base::StringValue(status));
+                                         base::Value(status));
 }
 
 void PrintPreviewHandler::RegisterForGaiaCookieChanges() {
diff --git a/chrome/browser/ui/webui/quota_internals/quota_internals_handler.cc b/chrome/browser/ui/webui/quota_internals/quota_internals_handler.cc
index 0d5749bc..1c632127 100644
--- a/chrome/browser/ui/webui/quota_internals/quota_internals_handler.cc
+++ b/chrome/browser/ui/webui/quota_internals/quota_internals_handler.cc
@@ -77,7 +77,7 @@
 void QuotaInternalsHandler::SendMessage(const std::string& message,
                                         const base::Value& value) {
   web_ui()->CallJavascriptFunctionUnsafe("cr.quota.messageHandler",
-                                         base::StringValue(message), value);
+                                         base::Value(message), value);
 }
 
 void QuotaInternalsHandler::OnRequestInfo(const base::ListValue*) {
diff --git a/chrome/browser/ui/webui/settings/about_handler.cc b/chrome/browser/ui/webui/settings/about_handler.cc
index e2fe6c5f..dd1d219 100644
--- a/chrome/browser/ui/webui/settings/about_handler.cc
+++ b/chrome/browser/ui/webui/settings/about_handler.cc
@@ -496,7 +496,7 @@
 void AboutHandler::OnGetVersionInfoReady(
     std::string callback_id,
     std::unique_ptr<base::DictionaryValue> version_info) {
-  ResolveJavascriptCallback(base::StringValue(callback_id), *version_info);
+  ResolveJavascriptCallback(base::Value(callback_id), *version_info);
 }
 
 void AboutHandler::HandleGetRegulatoryInfo(const base::ListValue* args) {
@@ -540,7 +540,7 @@
   channel_info->SetBoolean("canChangeChannel",
                            CanChangeChannel(Profile::FromWebUI(web_ui())));
 
-  ResolveJavascriptCallback(base::StringValue(callback_id), *channel_info);
+  ResolveJavascriptCallback(base::Value(callback_id), *channel_info);
 }
 
 void AboutHandler::HandleRequestUpdate(const base::ListValue* args) {
@@ -584,7 +584,7 @@
 #endif  // defined(OS_CHROMEOS)
 
   CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::StringValue("update-status-changed"), *event);
+                         base::Value("update-status-changed"), *event);
 }
 
 #if defined(OS_MACOSX)
@@ -612,8 +612,7 @@
     promo_state.SetString("text", text);
 
   CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::StringValue("promotion-state-changed"),
-                         promo_state);
+                         base::Value("promotion-state-changed"), promo_state);
 }
 #endif  // defined(OS_MACOSX)
 
@@ -622,7 +621,7 @@
     std::string callback_id,
     const base::FilePath& label_dir_path) {
   if (label_dir_path.empty()) {
-    ResolveJavascriptCallback(base::StringValue(callback_id),
+    ResolveJavascriptCallback(base::Value(callback_id),
                               *base::Value::CreateNullValue());
     return;
   }
@@ -650,7 +649,7 @@
       std::string("chrome://") + chrome::kChromeOSAssetHost + "/" + image_path;
   regulatory_info->SetString("url", url);
 
-  ResolveJavascriptCallback(base::StringValue(callback_id), *regulatory_info);
+  ResolveJavascriptCallback(base::Value(callback_id), *regulatory_info);
 }
 #endif  // defined(OS_CHROMEOS)
 
diff --git a/chrome/browser/ui/webui/settings/certificates_handler.cc b/chrome/browser/ui/webui/settings/certificates_handler.cc
index 37922e3..3c9af03 100644
--- a/chrome/browser/ui/webui/settings/certificates_handler.cc
+++ b/chrome/browser/ui/webui/settings/certificates_handler.cc
@@ -906,7 +906,7 @@
 
   // TODO(mattm): check here if root_cert is not a CA cert and show error.
 
-  base::StringValue cert_name(root_cert->subject().GetDisplayName());
+  base::Value cert_name(root_cert->subject().GetDisplayName());
   ResolveCallback(cert_name);
 }
 
@@ -989,7 +989,7 @@
   base::Value tpm_available_value(
       certificate_manager_model_->is_tpm_available());
   CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::StringValue("certificates-model-ready"),
+                         base::Value("certificates-model-ready"),
                          user_db_available_value, tpm_available_value);
   certificate_manager_model_->Refresh();
 }
@@ -1083,20 +1083,20 @@
     std::sort(nodes->begin(), nodes->end(), comparator);
 
     CallJavascriptFunction("cr.webUIListenerCallback",
-                           base::StringValue("certificates-changed"),
-                           base::StringValue(tab_name), *nodes);
+                           base::Value("certificates-changed"),
+                           base::Value(tab_name), *nodes);
   }
 }
 
 void CertificatesHandler::ResolveCallback(const base::Value& response) {
   DCHECK(!webui_callback_id_.empty());
-  ResolveJavascriptCallback(base::StringValue(webui_callback_id_), response);
+  ResolveJavascriptCallback(base::Value(webui_callback_id_), response);
   webui_callback_id_.clear();
 }
 
 void CertificatesHandler::RejectCallback(const base::Value& response) {
   DCHECK(!webui_callback_id_.empty());
-  RejectJavascriptCallback(base::StringValue(webui_callback_id_), response);
+  RejectJavascriptCallback(base::Value(webui_callback_id_), response);
   webui_callback_id_.clear();
 }
 
diff --git a/chrome/browser/ui/webui/settings/chromeos/android_apps_handler.cc b/chrome/browser/ui/webui/settings/chromeos/android_apps_handler.cc
index c3bf83d8..099654c 100644
--- a/chrome/browser/ui/webui/settings/chromeos/android_apps_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/android_apps_handler.cc
@@ -82,7 +82,7 @@
   AllowJavascript();
   std::unique_ptr<base::DictionaryValue> info = BuildAndroidAppsInfo();
   CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::StringValue("android-apps-info-update"), *info);
+                         base::Value("android-apps-info-update"), *info);
 }
 
 void AndroidAppsHandler::ShowAndroidAppsSettings(const base::ListValue* args) {
diff --git a/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.cc b/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.cc
index 1f73638..e9b8ae75 100644
--- a/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.cc
@@ -144,8 +144,7 @@
     image_urls.Append(std::move(image_data));
   }
   CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::StringValue("default-images-changed"),
-                         image_urls);
+                         base::Value("default-images-changed"), image_urls);
 }
 
 void ChangePictureHandler::HandleChooseFile(const base::ListValue* args) {
@@ -230,10 +229,10 @@
       if (previous_image_index_ >=
           default_user_image::kFirstDefaultImageIndex) {
         // User has image from the current set of default images.
-        base::StringValue image_url(
+        base::Value image_url(
             default_user_image::GetDefaultImageUrl(previous_image_index_));
         CallJavascriptFunction("cr.webUIListenerCallback",
-                               base::StringValue("selected-image-changed"),
+                               base::Value("selected-image-changed"),
                                image_url);
       } else {
         // User has an old default image, so present it in the same manner as a
@@ -247,10 +246,10 @@
 
 void ChangePictureHandler::SendProfileImage(const gfx::ImageSkia& image,
                                             bool should_select) {
-  base::StringValue data_url(webui::GetBitmapDataUrl(*image.bitmap()));
+  base::Value data_url(webui::GetBitmapDataUrl(*image.bitmap()));
   base::Value select(should_select);
   CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::StringValue("profile-image-changed"), data_url,
+                         base::Value("profile-image-changed"), data_url,
                          select);
 }
 
@@ -268,9 +267,9 @@
 
 void ChangePictureHandler::SendOldImage(const std::string& image_url) {
   previous_image_url_ = image_url;
-  base::StringValue url(image_url);
+  base::Value url(image_url);
   CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::StringValue("old-image-changed"), url);
+                         base::Value("old-image-changed"), url);
 }
 
 void ChangePictureHandler::HandleSelectImage(const base::ListValue* args) {
@@ -368,7 +367,7 @@
 
 void ChangePictureHandler::SetCameraPresent(bool present) {
   CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::StringValue("camera-presence-changed"),
+                         base::Value("camera-presence-changed"),
                          base::Value(present));
 }
 
diff --git a/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc b/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc
index b4ab7c9..371bea8 100644
--- a/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc
@@ -148,7 +148,7 @@
   std::unique_ptr<base::DictionaryValue> response =
       base::MakeUnique<base::DictionaryValue>();
   response->Set("printerList", printers_list);
-  ResolveJavascriptCallback(base::StringValue(callback_id), *response);
+  ResolveJavascriptCallback(base::Value(callback_id), *response);
 }
 
 void CupsPrintersHandler::HandleUpdateCupsPrinter(const base::ListValue* args) {
@@ -251,14 +251,14 @@
         std::move(printer));
   }
   CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::StringValue("on-add-cups-printer"),
-                         base::Value(success), base::StringValue(printer_name));
+                         base::Value("on-add-cups-printer"),
+                         base::Value(success), base::Value(printer_name));
 }
 
 void CupsPrintersHandler::OnAddPrinterError() {
   CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::StringValue("on-add-cups-printer"),
-                         base::Value(false), base::StringValue(""));
+                         base::Value("on-add-cups-printer"), base::Value(false),
+                         base::Value(""));
 }
 
 void CupsPrintersHandler::HandleGetCupsPrinterManufacturers(
@@ -287,7 +287,7 @@
     base::DictionaryValue response;
     response.SetBoolean("success", true);
     response.Set("models", base::MakeUnique<base::ListValue>());
-    ResolveJavascriptCallback(base::StringValue(js_callback), response);
+    ResolveJavascriptCallback(base::Value(js_callback), response);
     return;
   }
 
@@ -328,7 +328,7 @@
   response.SetBoolean("success",
                       result_code == chromeos::printing::PpdProvider::SUCCESS);
   response.Set("manufacturers", std::move(manufacturers_value));
-  ResolveJavascriptCallback(base::StringValue(js_callback), response);
+  ResolveJavascriptCallback(base::Value(js_callback), response);
 }
 
 void CupsPrintersHandler::ResolvePrintersDone(
@@ -343,15 +343,15 @@
   response.SetBoolean("success",
                       result_code == chromeos::printing::PpdProvider::SUCCESS);
   response.Set("models", std::move(printers_value));
-  ResolveJavascriptCallback(base::StringValue(js_callback), response);
+  ResolveJavascriptCallback(base::Value(js_callback), response);
 }
 
 void CupsPrintersHandler::FileSelected(const base::FilePath& path,
                                        int index,
                                        void* params) {
   DCHECK(!webui_callback_id_.empty());
-  ResolveJavascriptCallback(base::StringValue(webui_callback_id_),
-                            base::StringValue(path.value()));
+  ResolveJavascriptCallback(base::Value(webui_callback_id_),
+                            base::Value(path.value()));
   webui_callback_id_.clear();
 }
 
@@ -362,7 +362,7 @@
   printer_discoverer_->AddObserver(this);
   if (!printer_discoverer_->StartDiscovery()) {
     CallJavascriptFunction("cr.webUIListenerCallback",
-                           base::StringValue("on-printer-discovery-failed"));
+                           base::Value("on-printer-discovery-failed"));
     printer_discoverer_->RemoveObserver(this);
   }
 }
@@ -386,13 +386,12 @@
   }
 
   CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::StringValue("on-printer-discovered"),
-                         *printers_list);
+                         base::Value("on-printer-discovered"), *printers_list);
 }
 
 void CupsPrintersHandler::OnDiscoveryDone() {
   CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::StringValue("on-printer-discovery-done"));
+                         base::Value("on-printer-discovery-done"));
 }
 
 }  // namespace settings
diff --git a/chrome/browser/ui/webui/settings/chromeos/date_time_handler.cc b/chrome/browser/ui/webui/settings/chromeos/date_time_handler.cc
index 605e28d..e21f0106 100644
--- a/chrome/browser/ui/webui/settings/chromeos/date_time_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/date_time_handler.cc
@@ -171,13 +171,13 @@
                            ->ShouldApplyResolvedTimezone();
 
   CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::StringValue("time-zone-auto-detect-policy"),
+                         base::Value("time-zone-auto-detect-policy"),
                          base::Value(managed), base::Value(force_enabled));
 }
 
 void DateTimeHandler::SystemClockCanSetTimeChanged(bool can_set_time) {
   CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::StringValue("can-set-date-time-changed"),
+                         base::Value("can-set-date-time-changed"),
                          base::Value(can_set_time));
 }
 
diff --git a/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.cc b/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.cc
index 72c7134..9ab0aa83 100644
--- a/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.cc
@@ -76,7 +76,7 @@
       base::CommandLine::ForCurrentProcess()->HasSwitch(
           chromeos::switches::kHasChromeOSDiamondKey));
   CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::StringValue("show-keys-changed"), has_caps_lock,
+                         base::Value("show-keys-changed"), has_caps_lock,
                          has_diamond_key);
 }
 
diff --git a/chrome/browser/ui/webui/settings/chromeos/device_pointer_handler.cc b/chrome/browser/ui/webui/settings/chromeos/device_pointer_handler.cc
index a82f579..7b36f47 100644
--- a/chrome/browser/ui/webui/settings/chromeos/device_pointer_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/device_pointer_handler.cc
@@ -37,14 +37,13 @@
 
 void PointerHandler::TouchpadExists(bool exists) {
   CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::StringValue("has-touchpad-changed"),
+                         base::Value("has-touchpad-changed"),
                          base::Value(exists));
 }
 
 void PointerHandler::MouseExists(bool exists) {
   CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::StringValue("has-mouse-changed"),
-                         base::Value(exists));
+                         base::Value("has-mouse-changed"), base::Value(exists));
 }
 
 void PointerHandler::HandleInitialize(const base::ListValue* args) {
diff --git a/chrome/browser/ui/webui/settings/chromeos/device_power_handler.cc b/chrome/browser/ui/webui/settings/chromeos/device_power_handler.cc
index 383b155..8e4cc5f 100644
--- a/chrome/browser/ui/webui/settings/chromeos/device_power_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/device_power_handler.cc
@@ -116,8 +116,7 @@
   battery_dict.SetString("statusText", status_text);
 
   CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::StringValue("battery-status-changed"),
-                         battery_dict);
+                         base::Value("battery-status-changed"), battery_dict);
 }
 
 void PowerHandler::SendPowerSources() {
@@ -131,10 +130,10 @@
     sources_list.Append(std::move(dict));
   }
 
-  CallJavascriptFunction(
-      "cr.webUIListenerCallback", base::StringValue("power-sources-changed"),
-      sources_list, base::StringValue(power_status_->GetCurrentPowerSourceID()),
-      base::Value(power_status_->IsUsbChargerConnected()));
+  CallJavascriptFunction("cr.webUIListenerCallback",
+                         base::Value("power-sources-changed"), sources_list,
+                         base::Value(power_status_->GetCurrentPowerSourceID()),
+                         base::Value(power_status_->IsUsbChargerConnected()));
 }
 
 }  // namespace settings
diff --git a/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.cc b/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.cc
index e33ec523..a5bc189 100644
--- a/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.cc
@@ -167,8 +167,7 @@
   size_stat.SetInteger("spaceState", storage_space_state);
 
   CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::StringValue("storage-size-stat-changed"),
-                         size_stat);
+                         base::Value("storage-size-stat-changed"), size_stat);
 }
 
 void StorageHandler::UpdateDownloadsSize() {
@@ -190,8 +189,8 @@
 void StorageHandler::OnGetDownloadsSize(int64_t size) {
   updating_downloads_size_ = false;
   CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::StringValue("storage-downloads-size-changed"),
-                         base::StringValue(ui::FormatBytes(size)));
+                         base::Value("storage-downloads-size-changed"),
+                         base::Value(ui::FormatBytes(size)));
 }
 
 void StorageHandler::UpdateDriveCacheSize() {
@@ -205,7 +204,7 @@
 
   // Shows the item "Offline cache" and start calculating size.
   CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::StringValue("storage-drive-enabled-changed"),
+                         base::Value("storage-drive-enabled-changed"),
                          base::Value(true));
   updating_drive_cache_size_ = true;
   file_system->CalculateCacheSize(
@@ -215,8 +214,8 @@
 void StorageHandler::OnGetDriveCacheSize(int64_t size) {
   updating_drive_cache_size_ = false;
   CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::StringValue("storage-drive-cache-size-changed"),
-                         base::StringValue(ui::FormatBytes(size)),
+                         base::Value("storage-drive-cache-size-changed"),
+                         base::Value(ui::FormatBytes(size)),
                          base::Value(size > 0));
 }
 
@@ -285,10 +284,9 @@
           IDS_OPTIONS_SETTINGS_STORAGE_SIZE_UNKNOWN);
     }
     updating_browsing_data_size_ = false;
-    CallJavascriptFunction(
-        "cr.webUIListenerCallback",
-        base::StringValue("storage-browsing-data-size-changed"),
-        base::StringValue(size_string));
+    CallJavascriptFunction("cr.webUIListenerCallback",
+                           base::Value("storage-browsing-data-size-changed"),
+                           base::Value(size_string));
   }
 }
 
@@ -313,10 +311,9 @@
   // We should show "0 B" if there is no other user.
   if (other_users_.empty()) {
     updating_other_users_size_ = false;
-    CallJavascriptFunction(
-        "cr.webUIListenerCallback",
-        base::StringValue("storage-other-users-size-changed"),
-        base::StringValue(ui::FormatBytes(0)));
+    CallJavascriptFunction("cr.webUIListenerCallback",
+                           base::Value("storage-other-users-size-changed"),
+                           base::Value(ui::FormatBytes(0)));
   }
 }
 
@@ -333,10 +330,9 @@
           IDS_OPTIONS_SETTINGS_STORAGE_SIZE_UNKNOWN);
     }
     updating_other_users_size_ = false;
-    CallJavascriptFunction(
-        "cr.webUIListenerCallback",
-        base::StringValue("storage-other-users-size-changed"),
-        base::StringValue(size_string));
+    CallJavascriptFunction("cr.webUIListenerCallback",
+                           base::Value("storage-other-users-size-changed"),
+                           base::Value(size_string));
   }
 }
 
@@ -353,7 +349,7 @@
 
   // Shows the item "Android apps and cache" and start calculating size.
   CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::StringValue("storage-android-enabled-changed"),
+                         base::Value("storage-android-enabled-changed"),
                          base::Value(true));
   bool success = arc::ArcStorageManager::Get()->GetApplicationsSize(
       base::Bind(&StorageHandler::OnGetAndroidSize,
@@ -376,8 +372,8 @@
   }
   updating_android_size_ = false;
   CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::StringValue("storage-android-size-changed"),
-                         base::StringValue(size_string));
+                         base::Value("storage-android-size-changed"),
+                         base::Value(size_string));
 }
 
 void StorageHandler::OnClearDriveCacheDone(bool success) {
diff --git a/chrome/browser/ui/webui/settings/chromeos/device_stylus_handler.cc b/chrome/browser/ui/webui/settings/chromeos/device_stylus_handler.cc
index 1f752da..34546b27 100644
--- a/chrome/browser/ui/webui/settings/chromeos/device_stylus_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/device_stylus_handler.cc
@@ -85,8 +85,8 @@
 
   AllowJavascript();
   CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::StringValue("onNoteTakingAppsUpdated"),
-                         apps_list, base::Value(waiting_for_android));
+                         base::Value("onNoteTakingAppsUpdated"), apps_list,
+                         base::Value(waiting_for_android));
 }
 
 void StylusHandler::RequestApps(const base::ListValue* unused_args) {
@@ -117,7 +117,7 @@
   DCHECK(ui::InputDeviceManager::GetInstance()->AreDeviceListsComplete());
   AllowJavascript();
   CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::StringValue("has-stylus-changed"),
+                         base::Value("has-stylus-changed"),
                          base::Value(ash::palette_utils::HasStylusInput()));
 }
 
diff --git a/chrome/browser/ui/webui/settings/chromeos/easy_unlock_settings_handler.cc b/chrome/browser/ui/webui/settings/chromeos/easy_unlock_settings_handler.cc
index b1f0002..c16ef08 100644
--- a/chrome/browser/ui/webui/settings/chromeos/easy_unlock_settings_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/easy_unlock_settings_handler.cc
@@ -87,14 +87,13 @@
 
 void EasyUnlockSettingsHandler::OnTurnOffOperationStatusChanged() {
   CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::StringValue("easy-unlock-turn-off-flow-status"),
-                         base::StringValue(GetTurnOffFlowStatus()));
+                         base::Value("easy-unlock-turn-off-flow-status"),
+                         base::Value(GetTurnOffFlowStatus()));
 }
 
 void EasyUnlockSettingsHandler::SendEnabledStatus() {
   CallJavascriptFunction(
-      "cr.webUIListenerCallback",
-      base::StringValue("easy-unlock-enabled-status"),
+      "cr.webUIListenerCallback", base::Value("easy-unlock-enabled-status"),
       base::Value(EasyUnlockService::Get(profile_)->IsEnabled()));
 }
 
@@ -145,8 +144,7 @@
   CHECK_EQ(1U, args->GetSize());
   const base::Value* callback_id;
   CHECK(args->Get(0, &callback_id));
-  ResolveJavascriptCallback(*callback_id,
-                            base::StringValue(GetTurnOffFlowStatus()));
+  ResolveJavascriptCallback(*callback_id, base::Value(GetTurnOffFlowStatus()));
 }
 
 void EasyUnlockSettingsHandler::HandleStartTurnOffFlow(
diff --git a/chrome/browser/ui/webui/settings/chromeos/fingerprint_handler.cc b/chrome/browser/ui/webui/settings/chromeos/fingerprint_handler.cc
index 542a575e..634da77 100644
--- a/chrome/browser/ui/webui/settings/chromeos/fingerprint_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/fingerprint_handler.cc
@@ -28,8 +28,8 @@
 
   DCHECK(int{fingerprints_list.size()} <= kMaxAllowedFingerprints);
   for (auto& fingerprint_name: fingerprints_list) {
-    std::unique_ptr<base::StringValue> str =
-        base::MakeUnique<base::StringValue>(fingerprint_name);
+    std::unique_ptr<base::Value> str =
+        base::MakeUnique<base::Value>(fingerprint_name);
     fingerprints->Append(std::move(str));
   }
 
@@ -102,7 +102,7 @@
 
   std::unique_ptr<base::DictionaryValue> fingerprint_info =
       GetFingerprintsInfo(fingerprints_list_);
-  ResolveJavascriptCallback(base::StringValue(callback_id), *fingerprint_info);
+  ResolveJavascriptCallback(base::Value(callback_id), *fingerprint_info);
 }
 
 void FingerprintHandler::HandleGetNumFingerprints(const base::ListValue* args) {
@@ -112,7 +112,7 @@
   std::string callback_id;
   CHECK(args->GetString(0, &callback_id));
 
-  ResolveJavascriptCallback(base::StringValue(callback_id),
+  ResolveJavascriptCallback(base::Value(callback_id),
                             base::Value(int{fingerprints_list_.size()}));
 }
 
@@ -133,8 +133,8 @@
   CHECK(args->GetInteger(1, &index));
 
   DCHECK(index < int{fingerprints_list_.size()});
-  ResolveJavascriptCallback(base::StringValue(callback_id),
-                            base::StringValue(fingerprints_list_[index]));
+  ResolveJavascriptCallback(base::Value(callback_id),
+                            base::Value(fingerprints_list_[index]));
 }
 
 void FingerprintHandler::HandleRemoveEnrollment(const base::ListValue* args) {
@@ -149,7 +149,7 @@
   DCHECK(index < int{fingerprints_list_.size()});
   bool deleteSucessful = true;
   fingerprints_list_.erase(fingerprints_list_.begin() + index);
-  ResolveJavascriptCallback(base::StringValue(callback_id),
+  ResolveJavascriptCallback(base::Value(callback_id),
                             base::Value(deleteSucessful));
 }
 
diff --git a/chrome/browser/ui/webui/settings/downloads_handler.cc b/chrome/browser/ui/webui/settings/downloads_handler.cc
index 4cbb9ac..7eacb649 100644
--- a/chrome/browser/ui/webui/settings/downloads_handler.cc
+++ b/chrome/browser/ui/webui/settings/downloads_handler.cc
@@ -68,7 +68,7 @@
   bool auto_open_downloads =
       manager && DownloadPrefs::FromDownloadManager(manager)->IsAutoOpenUsed();
   CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::StringValue("auto-open-downloads-changed"),
+                         base::Value("auto-open-downloads-changed"),
                          base::Value(auto_open_downloads));
 }
 
diff --git a/chrome/browser/ui/webui/settings/font_handler.cc b/chrome/browser/ui/webui/settings/font_handler.cc
index 7eb28f0..4d7c4c3 100644
--- a/chrome/browser/ui/webui/settings/font_handler.cc
+++ b/chrome/browser/ui/webui/settings/font_handler.cc
@@ -104,7 +104,7 @@
 void FontHandler::NotifyAdvancedFontSettingsAvailability() {
   CallJavascriptFunction(
       "cr.webUIListenerCallback",
-      base::StringValue("advanced-font-settings-installed"),
+      base::Value("advanced-font-settings-installed"),
       base::Value(GetAdvancedFontSettingsExtension() != nullptr));
 }
 
@@ -144,7 +144,7 @@
       "extensionUrl",
       extension_url.Resolve(kAdvancedFontSettingsExtensionId).spec());
 
-  ResolveJavascriptCallback(base::StringValue(callback_id), response);
+  ResolveJavascriptCallback(base::Value(callback_id), response);
 }
 
 }  // namespace settings
diff --git a/chrome/browser/ui/webui/settings/languages_handler.cc b/chrome/browser/ui/webui/settings/languages_handler.cc
index 52ea1a1b..d3b4595c 100644
--- a/chrome/browser/ui/webui/settings/languages_handler.cc
+++ b/chrome/browser/ui/webui/settings/languages_handler.cc
@@ -61,7 +61,7 @@
         g_browser_process->local_state()->GetString(prefs::kApplicationLocale);
   }
 
-  ResolveJavascriptCallback(*callback_id, base::StringValue(locale));
+  ResolveJavascriptCallback(*callback_id, base::Value(locale));
 #else
   NOTREACHED() << "Attempting to get locale on unsupported platform";
 #endif  // defined(OS_WIN) || defined(OS_CHROMEOS)
diff --git a/chrome/browser/ui/webui/settings/metrics_reporting_handler.cc b/chrome/browser/ui/webui/settings/metrics_reporting_handler.cc
index 05ec166..06feda9 100644
--- a/chrome/browser/ui/webui/settings/metrics_reporting_handler.cc
+++ b/chrome/browser/ui/webui/settings/metrics_reporting_handler.cc
@@ -96,10 +96,9 @@
 }
 
 void MetricsReportingHandler::SendMetricsReportingChange() {
-  CallJavascriptFunction(
-      "cr.webUIListenerCallback",
-      base::StringValue("metrics-reporting-change"),
-      *CreateMetricsReportingDict());
+  CallJavascriptFunction("cr.webUIListenerCallback",
+                         base::Value("metrics-reporting-change"),
+                         *CreateMetricsReportingDict());
 }
 
 }  // namespace settings
diff --git a/chrome/browser/ui/webui/settings/people_handler.cc b/chrome/browser/ui/webui/settings/people_handler.cc
index fd07196c..0ff3858 100644
--- a/chrome/browser/ui/webui/settings/people_handler.cc
+++ b/chrome/browser/ui/webui/settings/people_handler.cc
@@ -324,8 +324,8 @@
                              &PeopleHandler::DisplayTimeout);
 
   CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::StringValue("page-status-changed"),
-                         base::StringValue(kSpinnerPageStatus));
+                         base::Value("page-status-changed"),
+                         base::Value(kSpinnerPageStatus));
 }
 
 void PeopleHandler::DisplayTimeout() {
@@ -336,8 +336,8 @@
   sync_startup_tracker_.reset();
 
   CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::StringValue("page-status-changed"),
-                         base::StringValue(kTimeoutPageStatus));
+                         base::Value("page-status-changed"),
+                         base::Value(kTimeoutPageStatus));
 }
 
 void PeopleHandler::OnDidClosePage(const base::ListValue* args) {
@@ -391,7 +391,7 @@
   // dialog.
   if (!service || !service->IsEngineInitialized()) {
     CloseSyncSetup();
-    ResolveJavascriptCallback(*callback_id, base::StringValue(kDonePageStatus));
+    ResolveJavascriptCallback(*callback_id, base::Value(kDonePageStatus));
     return;
   }
 
@@ -399,8 +399,7 @@
                                 configuration.data_types);
 
   // Choosing data types to sync never fails.
-  ResolveJavascriptCallback(*callback_id,
-                            base::StringValue(kConfigurePageStatus));
+  ResolveJavascriptCallback(*callback_id, base::Value(kConfigurePageStatus));
 
   ProfileMetrics::LogProfileSyncInfo(ProfileMetrics::SYNC_CUSTOMIZE);
   if (!configuration.sync_everything)
@@ -422,7 +421,7 @@
   // dialog.
   if (!service || !service->IsEngineInitialized()) {
     CloseSyncSetup();
-    ResolveJavascriptCallback(*callback_id, base::StringValue(kDonePageStatus));
+    ResolveJavascriptCallback(*callback_id, base::Value(kDonePageStatus));
     return;
   }
 
@@ -473,10 +472,9 @@
     // TODO(tommycli): Switch this to RejectJavascriptCallback once the
     // Sync page JavaScript has been further refactored.
     ResolveJavascriptCallback(*callback_id,
-                              base::StringValue(kPassphraseFailedPageStatus));
+                              base::Value(kPassphraseFailedPageStatus));
   } else {
-    ResolveJavascriptCallback(*callback_id,
-                              base::StringValue(kConfigurePageStatus));
+    ResolveJavascriptCallback(*callback_id, base::Value(kConfigurePageStatus));
   }
 
   if (configuration.encrypt_all)
@@ -698,8 +696,8 @@
 void PeopleHandler::CloseUI() {
   CloseSyncSetup();
   CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::StringValue("page-status-changed"),
-                         base::StringValue(kDonePageStatus));
+                         base::Value("page-status-changed"),
+                         base::Value(kDonePageStatus));
 }
 
 void PeopleHandler::GoogleSigninSucceeded(const std::string& /* account_id */,
@@ -888,7 +886,7 @@
   }
 
   CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::StringValue("sync-prefs-changed"), args);
+                         base::Value("sync-prefs-changed"), args);
 }
 
 LoginUIService* PeopleHandler::GetLoginUIService() const {
@@ -897,7 +895,7 @@
 
 void PeopleHandler::UpdateSyncStatus() {
   CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::StringValue("sync-status-changed"),
+                         base::Value("sync-status-changed"),
                          *GetSyncStatusDictionary());
 }
 
diff --git a/chrome/browser/ui/webui/settings/profile_info_handler.cc b/chrome/browser/ui/webui/settings/profile_info_handler.cc
index 175dac3..d6510f5 100644
--- a/chrome/browser/ui/webui/settings/profile_info_handler.cc
+++ b/chrome/browser/ui/webui/settings/profile_info_handler.cc
@@ -152,7 +152,7 @@
   // available. Therefore, webUIListenerCallback mechanism is used instead of
   // the Promise callback approach.
   CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::StringValue(kProfileStatsCountReadyEventName),
+                         base::Value(kProfileStatsCountReadyEventName),
                          base::Value(count));
 }
 #endif
@@ -171,14 +171,14 @@
 
 void ProfileInfoHandler::PushProfileInfo() {
   CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::StringValue(kProfileInfoChangedEventName),
+                         base::Value(kProfileInfoChangedEventName),
                          *GetAccountNameAndIcon());
 }
 
 void ProfileInfoHandler::PushProfileManagesSupervisedUsersStatus() {
   CallJavascriptFunction(
       "cr.webUIListenerCallback",
-      base::StringValue(kProfileManagesSupervisedUsersChangedEventName),
+      base::Value(kProfileManagesSupervisedUsersChangedEventName),
       base::Value(IsProfileManagingSupervisedUsers()));
 }
 
diff --git a/chrome/browser/ui/webui/settings/protocol_handlers_handler.cc b/chrome/browser/ui/webui/settings/protocol_handlers_handler.cc
index 42610c6..70d02e81 100644
--- a/chrome/browser/ui/webui/settings/protocol_handlers_handler.cc
+++ b/chrome/browser/ui/webui/settings/protocol_handlers_handler.cc
@@ -128,10 +128,9 @@
   std::unique_ptr<base::ListValue> ignored_handlers(new base::ListValue());
   GetIgnoredHandlers(ignored_handlers.get());
   CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::StringValue("setProtocolHandlers"),
-                         handlers);
+                         base::Value("setProtocolHandlers"), handlers);
   CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::StringValue("setIgnoredProtocolHandlers"),
+                         base::Value("setIgnoredProtocolHandlers"),
                          *ignored_handlers);
 }
 
@@ -150,7 +149,7 @@
 
 void ProtocolHandlersHandler::SendHandlersEnabledValue() {
   CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::StringValue("setHandlersEnabled"),
+                         base::Value("setHandlersEnabled"),
                          base::Value(GetProtocolHandlerRegistry()->enabled()));
 }
 
diff --git a/chrome/browser/ui/webui/settings/reset_settings_handler.cc b/chrome/browser/ui/webui/settings/reset_settings_handler.cc
index 372af03..ca62979 100644
--- a/chrome/browser/ui/webui/settings/reset_settings_handler.cc
+++ b/chrome/browser/ui/webui/settings/reset_settings_handler.cc
@@ -157,8 +157,8 @@
     std::string callback_id,
     bool send_feedback,
     reset_report::ChromeResetReport::ResetRequestOrigin request_origin) {
-  ResolveJavascriptCallback(
-      base::StringValue(callback_id), *base::Value::CreateNullValue());
+  ResolveJavascriptCallback(base::Value(callback_id),
+                            *base::Value::CreateNullValue());
   if (send_feedback && setting_snapshot_) {
     ResettableSettingsSnapshot current_snapshot(profile_);
     int difference = setting_snapshot_->FindDifferentFields(current_snapshot);
@@ -192,7 +192,7 @@
 void ResetSettingsHandler::OnGetReportedSettingsDone(std::string callback_id) {
   std::unique_ptr<base::ListValue> list =
       GetReadableFeedbackForSnapshot(profile_, *setting_snapshot_);
-  ResolveJavascriptCallback(base::StringValue(callback_id), *list);
+  ResolveJavascriptCallback(base::Value(callback_id), *list);
 }
 
 void ResetSettingsHandler::OnShowResetProfileDialog(
@@ -294,7 +294,7 @@
         IDS_TRIGGERED_RESET_PROFILE_SETTINGS_DEFAULT_TOOL_NAME);
   }
 
-  base::StringValue string_value(reset_tool_name);
+  base::Value string_value(reset_tool_name);
   ResolveJavascriptCallback(*callback_id, string_value);
 }
 
diff --git a/chrome/browser/ui/webui/settings/safe_browsing_handler.cc b/chrome/browser/ui/webui/settings/safe_browsing_handler.cc
index 918dcf9..1490781 100644
--- a/chrome/browser/ui/webui/settings/safe_browsing_handler.cc
+++ b/chrome/browser/ui/webui/settings/safe_browsing_handler.cc
@@ -64,9 +64,9 @@
          pref_name == prefs::kSafeBrowsingScoutReportingEnabled);
 
   base::Value is_enabled(safe_browsing::IsExtendedReportingEnabled(*prefs_));
-  CallJavascriptFunction(
-      "cr.webUIListenerCallback",
-      base::StringValue("safe-browsing-extended-reporting-change"), is_enabled);
+  CallJavascriptFunction("cr.webUIListenerCallback",
+                         base::Value("safe-browsing-extended-reporting-change"),
+                         is_enabled);
 }
 
 }  // namespace settings
diff --git a/chrome/browser/ui/webui/settings/search_engines_handler.cc b/chrome/browser/ui/webui/settings/search_engines_handler.cc
index 53534e3..d5f70c77 100644
--- a/chrome/browser/ui/webui/settings/search_engines_handler.cc
+++ b/chrome/browser/ui/webui/settings/search_engines_handler.cc
@@ -195,11 +195,11 @@
 void SearchEnginesHandler::OnModelChanged() {
   AllowJavascript();
   CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::StringValue("search-engines-changed"),
+                         base::Value("search-engines-changed"),
                          *GetSearchEnginesList());
   // Google Now availability may have changed.
   CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::StringValue("google-now-availability-changed"),
+                         base::Value("google-now-availability-changed"),
                          base::Value(IsGoogleNowAvailable(profile_)));
 }
 
@@ -518,7 +518,7 @@
     ResolveJavascriptCallback(*callback_id, status);
   } else {
     CallJavascriptFunction("cr.webUIListenerCallback",
-                           base::StringValue("hotword-info-update"), status);
+                           base::Value("hotword-info-update"), status);
   }
 }
 
diff --git a/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.cc b/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.cc
index dd8d078d..30f8aa2e 100644
--- a/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.cc
+++ b/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.cc
@@ -241,7 +241,7 @@
   UMA_HISTOGRAM_BOOLEAN(
       "History.ClearBrowsingData.ShownHistoryNoticeAfterClearing", show_notice);
 
-  ResolveJavascriptCallback(base::StringValue(webui_callback_id),
+  ResolveJavascriptCallback(base::Value(webui_callback_id),
                             base::Value(show_notice));
   task_observer_.reset();
 }
@@ -272,7 +272,7 @@
 
 void ClearBrowsingDataHandler::UpdateSyncState() {
   CallJavascriptFunction(
-      "cr.webUIListenerCallback", base::StringValue("update-footer"),
+      "cr.webUIListenerCallback", base::Value("update-footer"),
       base::Value(sync_service_ && sync_service_->IsSyncActive()),
       base::Value(show_history_footer_));
 }
@@ -326,9 +326,9 @@
 void ClearBrowsingDataHandler::UpdateCounterText(
     std::unique_ptr<browsing_data::BrowsingDataCounter::Result> result) {
   CallJavascriptFunction(
-      "cr.webUIListenerCallback", base::StringValue("update-counter-text"),
-      base::StringValue(result->source()->GetPrefName()),
-      base::StringValue(GetChromeCounterTextFromResult(result.get())));
+      "cr.webUIListenerCallback", base::Value("update-counter-text"),
+      base::Value(result->source()->GetPrefName()),
+      base::Value(GetChromeCounterTextFromResult(result.get())));
 }
 
 }  // namespace settings
diff --git a/chrome/browser/ui/webui/settings/settings_cookies_view_handler.cc b/chrome/browser/ui/webui/settings/settings_cookies_view_handler.cc
index d2d0b0e..fef6e14c 100644
--- a/chrome/browser/ui/webui/settings/settings_cookies_view_handler.cc
+++ b/chrome/browser/ui/webui/settings/settings_cookies_view_handler.cc
@@ -108,8 +108,7 @@
   args.SetInteger(kStart, start);
   args.Set(kChildren, std::move(children));
   CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::StringValue("onTreeItemAdded"),
-                         args);
+                         base::Value("onTreeItemAdded"), args);
 }
 
 void CookiesViewHandler::TreeNodesRemoved(ui::TreeModel* model,
@@ -130,8 +129,7 @@
   args.SetInteger(kStart, start);
   args.SetInteger(kCount, count);
   CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::StringValue("onTreeItemRemoved"),
-                         args);
+                         base::Value("onTreeItemRemoved"), args);
 }
 
 void CookiesViewHandler::TreeModelBeginBatch(CookiesTreeModel* model) {
@@ -199,7 +197,7 @@
       cookies_tree_model_->GetRoot(), base::UTF8ToUTF16(site));
 
   if (!node) {
-    RejectJavascriptCallback(base::StringValue(callback_id_),
+    RejectJavascriptCallback(base::Value(callback_id_),
                              *base::Value::CreateNullValue());
     callback_id_.clear();
     return;
@@ -262,7 +260,7 @@
     args.SetString(kId, model_util_->GetTreeNodeId(parent));
   args.Set(kChildren, std::move(children));
 
-  ResolveJavascriptCallback(base::StringValue(callback_id_), args);
+  ResolveJavascriptCallback(base::Value(callback_id_), args);
   callback_id_.clear();
 }
 
@@ -282,7 +280,7 @@
     args.SetString(kId, model_util_->GetTreeNodeId(parent));
   args.Set(kChildren, std::move(children));
 
-  ResolveJavascriptCallback(base::StringValue(callback_id_), args);
+  ResolveJavascriptCallback(base::Value(callback_id_), args);
   callback_id_.clear();
 }
 
diff --git a/chrome/browser/ui/webui/settings/settings_default_browser_handler.cc b/chrome/browser/ui/webui/settings/settings_default_browser_handler.cc
index 867ac73d..f8cb64a 100644
--- a/chrome/browser/ui/webui/settings/settings_default_browser_handler.cc
+++ b/chrome/browser/ui/webui/settings/settings_default_browser_handler.cc
@@ -97,7 +97,8 @@
   dict.SetBoolean("isDisabledByPolicy", DefaultBrowserIsDisabledByPolicy());
 
   CallJavascriptFunction("cr.webUIListenerCallback",
-      base::StringValue("settings.updateDefaultBrowserState"), dict);
+                         base::Value("settings.updateDefaultBrowserState"),
+                         dict);
 }
 
 }  // namespace settings
diff --git a/chrome/browser/ui/webui/settings/settings_import_data_handler.cc b/chrome/browser/ui/webui/settings/settings_import_data_handler.cc
index ced4cd23..2b7a370 100644
--- a/chrome/browser/ui/webui/settings/settings_import_data_handler.cc
+++ b/chrome/browser/ui/webui/settings/settings_import_data_handler.cc
@@ -94,8 +94,8 @@
     importer_host_->set_observer(NULL);
 
   CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::StringValue("import-data-status-changed"),
-                         base::StringValue(kImportStatusInProgress));
+                         base::Value("import-data-status-changed"),
+                         base::Value(kImportStatusInProgress));
   import_did_succeed_ = false;
 
   importer_host_ = new ExternalProcessImporterHost();
@@ -185,7 +185,7 @@
     browser_profiles.Append(std::move(browser_profile));
   }
 
-  ResolveJavascriptCallback(base::StringValue(callback_id), browser_profiles);
+  ResolveJavascriptCallback(base::Value(callback_id), browser_profiles);
 }
 
 void ImportDataHandler::ImportStarted() {
@@ -212,10 +212,9 @@
   importer_host_ = NULL;
 
   CallJavascriptFunction(
-      "cr.webUIListenerCallback",
-      base::StringValue("import-data-status-changed"),
-      base::StringValue(import_did_succeed_ ? kImportStatusSucceeded
-                                            : kImportStatusFailed));
+      "cr.webUIListenerCallback", base::Value("import-data-status-changed"),
+      base::Value(import_did_succeed_ ? kImportStatusSucceeded
+                                      : kImportStatusFailed));
 }
 
 void ImportDataHandler::FileSelected(const base::FilePath& path,
diff --git a/chrome/browser/ui/webui/settings/settings_manage_profile_handler.cc b/chrome/browser/ui/webui/settings/settings_manage_profile_handler.cc
index 6a00c7c..999d4f8e 100644
--- a/chrome/browser/ui/webui/settings/settings_manage_profile_handler.cc
+++ b/chrome/browser/ui/webui/settings/settings_manage_profile_handler.cc
@@ -92,7 +92,7 @@
     const base::FilePath& profile_path) {
   // This is necessary to send the potentially updated GAIA photo.
   CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::StringValue("available-icons-changed"),
+                         base::Value("available-icons-changed"),
                          *GetAvailableIcons());
 }
 
@@ -194,8 +194,8 @@
   ProfileAttributesStorage& storage =
       g_browser_process->profile_manager()->GetProfileAttributesStorage();
   if (storage.GetNumberOfProfiles() <= 1u) {
-    ResolveJavascriptCallback(base::StringValue(callback_id),
-                              base::StringValue(kProfileShortcutSettingHidden));
+    ResolveJavascriptCallback(base::Value(callback_id),
+                              base::Value(kProfileShortcutSettingHidden));
     return;
   }
 
@@ -212,9 +212,9 @@
     const std::string& callback_id, bool has_shortcuts) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   ResolveJavascriptCallback(
-      base::StringValue(callback_id),
-      base::StringValue(has_shortcuts ? kProfileShortcutFound
-                                      : kProfileShortcutNotFound));
+      base::Value(callback_id),
+      base::Value(has_shortcuts ? kProfileShortcutFound
+                                : kProfileShortcutNotFound));
 }
 
 void ManageProfileHandler::HandleAddProfileShortcut(
diff --git a/chrome/browser/ui/webui/settings/settings_media_devices_selection_handler.cc b/chrome/browser/ui/webui/settings/settings_media_devices_selection_handler.cc
index 8070f704..56093d1f 100644
--- a/chrome/browser/ui/webui/settings/settings_media_devices_selection_handler.cc
+++ b/chrome/browser/ui/webui/settings/settings_media_devices_selection_handler.cc
@@ -137,13 +137,11 @@
   if (!devices.empty() && default_id.empty())
     default_id = devices[0].id;
 
-  base::StringValue default_value(default_id);
-  base::StringValue type_value(device_type);
+  base::Value default_value(default_id);
+  base::Value type_value(device_type);
   CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::StringValue("updateDevicesMenu"),
-                         type_value,
-                         device_list,
-                         default_value);
+                         base::Value("updateDevicesMenu"), type_value,
+                         device_list, default_value);
 }
 
 std::string MediaDevicesSelectionHandler::GetDeviceDisplayName(
diff --git a/chrome/browser/ui/webui/settings/settings_startup_pages_handler.cc b/chrome/browser/ui/webui/settings/settings_startup_pages_handler.cc
index 2acbea12..c0b8702 100644
--- a/chrome/browser/ui/webui/settings/settings_startup_pages_handler.cc
+++ b/chrome/browser/ui/webui/settings/settings_startup_pages_handler.cc
@@ -86,8 +86,7 @@
   }
 
   CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::StringValue("update-startup-pages"),
-                         startup_pages);
+                         base::Value("update-startup-pages"), startup_pages);
 }
 
 void StartupPagesHandler::OnItemsChanged(int start, int length) {
diff --git a/chrome/browser/ui/webui/settings/site_settings_handler.cc b/chrome/browser/ui/webui/settings/site_settings_handler.cc
index 08b1e24e..824daae 100644
--- a/chrome/browser/ui/webui/settings/site_settings_handler.cc
+++ b/chrome/browser/ui/webui/settings/site_settings_handler.cc
@@ -206,8 +206,8 @@
     if (entry.usage <= 0) continue;
     if (entry.host == usage_host_) {
       CallJavascriptFunction("settings.WebsiteUsagePrivateApi.returnUsageTotal",
-                             base::StringValue(entry.host),
-                             base::StringValue(ui::FormatBytes(entry.usage)),
+                             base::Value(entry.host),
+                             base::Value(ui::FormatBytes(entry.usage)),
                              base::Value(entry.type));
       return;
     }
@@ -217,7 +217,7 @@
 void SiteSettingsHandler::OnUsageInfoCleared(storage::QuotaStatusCode code) {
   if (code == storage::kQuotaStatusOk) {
     CallJavascriptFunction("settings.WebsiteUsagePrivateApi.onUsageCleared",
-                           base::StringValue(clearing_origin_));
+                           base::Value(clearing_origin_));
   }
 }
 
@@ -232,19 +232,19 @@
   if (primary_pattern.ToString().empty()) {
     CallJavascriptFunction(
         "cr.webUIListenerCallback",
-        base::StringValue("contentSettingCategoryChanged"),
-        base::StringValue(site_settings::ContentSettingsTypeToGroupName(
-            content_type)));
+        base::Value("contentSettingCategoryChanged"),
+        base::Value(
+            site_settings::ContentSettingsTypeToGroupName(content_type)));
   } else {
     CallJavascriptFunction(
         "cr.webUIListenerCallback",
-        base::StringValue("contentSettingSitePermissionChanged"),
-        base::StringValue(site_settings::ContentSettingsTypeToGroupName(
-            content_type)),
-        base::StringValue(primary_pattern.ToString()),
-        base::StringValue(
-            secondary_pattern == ContentSettingsPattern::Wildcard() ?
-            "" : secondary_pattern.ToString()));
+        base::Value("contentSettingSitePermissionChanged"),
+        base::Value(
+            site_settings::ContentSettingsTypeToGroupName(content_type)),
+        base::Value(primary_pattern.ToString()),
+        base::Value(secondary_pattern == ContentSettingsPattern::Wildcard()
+                        ? ""
+                        : secondary_pattern.ToString()));
   }
 }
 
@@ -617,7 +617,7 @@
       !(was_destroyed && profile == profile_->GetOffTheRecordProfile());
 
   CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::StringValue("onIncognitoStatusChanged"),
+                         base::Value("onIncognitoStatusChanged"),
                          base::Value(incognito_enabled));
 }
 
@@ -703,7 +703,7 @@
   }
 
   CallJavascriptFunction("cr.webUIListenerCallback",
-                         base::StringValue("onZoomLevelsChanged"),
+                         base::Value("onZoomLevelsChanged"),
                          zoom_levels_exceptions);
 }
 
diff --git a/chrome/browser/ui/webui/signin/inline_login_ui_browsertest.cc b/chrome/browser/ui/webui/signin/inline_login_ui_browsertest.cc
index 57bd3f0f..34527db3a 100644
--- a/chrome/browser/ui/webui/signin/inline_login_ui_browsertest.cc
+++ b/chrome/browser/ui/webui/signin/inline_login_ui_browsertest.cc
@@ -292,7 +292,7 @@
   PrefService* pref_service = browser()->profile()->GetPrefs();
   ListPrefUpdate updater(pref_service,
                          prefs::kReverseAutologinRejectedEmailList);
-  updater->AppendIfNotPresent(base::MakeUnique<base::StringValue>(email));
+  updater->AppendIfNotPresent(base::MakeUnique<base::Value>(email));
 }
 
 void InlineLoginUIBrowserTest::AllowSigninCookies(bool enable) {
diff --git a/chrome/browser/ui/webui/signin/signin_create_profile_handler.cc b/chrome/browser/ui/webui/signin/signin_create_profile_handler.cc
index 299151962..c6f3282 100644
--- a/chrome/browser/ui/webui/signin/signin_create_profile_handler.cc
+++ b/chrome/browser/ui/webui/signin/signin_create_profile_handler.cc
@@ -184,7 +184,7 @@
 void SigninCreateProfileHandler::RequestDefaultProfileIcons(
     const base::ListValue* args) {
   web_ui()->CallJavascriptFunctionUnsafe(
-      "cr.webUIListenerCallback", base::StringValue("profile-icons-received"),
+      "cr.webUIListenerCallback", base::Value("profile-icons-received"),
       *profiles::GetDefaultProfileAvatarIconsAndLabels());
 
   SendNewProfileDefaults();
@@ -197,8 +197,8 @@
   profile_info.SetString("name", storage.ChooseNameForNewProfile(0));
 
   web_ui()->CallJavascriptFunctionUnsafe(
-      "cr.webUIListenerCallback",
-      base::StringValue("profile-defaults-received"), profile_info);
+      "cr.webUIListenerCallback", base::Value("profile-defaults-received"),
+      profile_info);
 }
 
 void SigninCreateProfileHandler::RequestSignedInProfiles(
@@ -219,9 +219,9 @@
 
     user_info_list.Append(std::move(user_info));
   }
-  web_ui()->CallJavascriptFunctionUnsafe(
-      "cr.webUIListenerCallback", base::StringValue("signedin-users-received"),
-      user_info_list);
+  web_ui()->CallJavascriptFunctionUnsafe("cr.webUIListenerCallback",
+                                         base::Value("signedin-users-received"),
+                                         user_info_list);
 }
 
 void SigninCreateProfileHandler::OnProfileAuthInfoChanged(
@@ -439,7 +439,7 @@
   DCHECK_NE(NO_CREATION_IN_PROGRESS, profile_creation_type_);
   web_ui()->CallJavascriptFunctionUnsafe(
       "cr.webUIListenerCallback", GetWebUIListenerName(PROFILE_CREATION_ERROR),
-      base::StringValue(error));
+      base::Value(error));
   // The ProfileManager calls us back with a NULL profile in some cases.
   if (profile) {
     webui::DeleteProfileAtPath(profile->GetPath(),
@@ -497,16 +497,16 @@
   }
 }
 
-base::StringValue SigninCreateProfileHandler::GetWebUIListenerName(
+base::Value SigninCreateProfileHandler::GetWebUIListenerName(
     ProfileCreationStatus status) const {
   switch (status) {
     case PROFILE_CREATION_SUCCESS:
-      return base::StringValue("create-profile-success");
+      return base::Value("create-profile-success");
     case PROFILE_CREATION_ERROR:
-      return base::StringValue("create-profile-error");
+      return base::Value("create-profile-error");
   }
   NOTREACHED();
-  return base::StringValue(std::string());
+  return base::Value(std::string());
 }
 
 #if BUILDFLAG(ENABLE_SUPERVISED_USERS)
@@ -768,9 +768,9 @@
 void SigninCreateProfileHandler::ShowProfileCreationWarning(
     const base::string16& warning) {
   DCHECK_EQ(SUPERVISED_PROFILE_CREATION, profile_creation_type_);
-  web_ui()->CallJavascriptFunctionUnsafe(
-      "cr.webUIListenerCallback", base::StringValue("create-profile-warning"),
-      base::StringValue(warning));
+  web_ui()->CallJavascriptFunctionUnsafe("cr.webUIListenerCallback",
+                                         base::Value("create-profile-warning"),
+                                         base::Value(warning));
 }
 
 void SigninCreateProfileHandler::RecordSupervisedProfileCreationMetrics(
diff --git a/chrome/browser/ui/webui/signin/signin_create_profile_handler.h b/chrome/browser/ui/webui/signin/signin_create_profile_handler.h
index 46c5de5..87bf6e4 100644
--- a/chrome/browser/ui/webui/signin/signin_create_profile_handler.h
+++ b/chrome/browser/ui/webui/signin/signin_create_profile_handler.h
@@ -158,7 +158,7 @@
 
   base::string16 GetProfileCreationErrorMessageLocal() const;
 
-  base::StringValue GetWebUIListenerName(ProfileCreationStatus status) const;
+  base::Value GetWebUIListenerName(ProfileCreationStatus status) const;
 
   // Used to allow canceling a profile creation (particularly a supervised-user
   // registration) in progress. Set when profile creation is begun, and
diff --git a/chrome/browser/ui/webui/signin/signin_supervised_user_import_handler.cc b/chrome/browser/ui/webui/signin/signin_supervised_user_import_handler.cc
index 1a53687..f7e115ff 100644
--- a/chrome/browser/ui/webui/signin/signin_supervised_user_import_handler.cc
+++ b/chrome/browser/ui/webui/signin/signin_supervised_user_import_handler.cc
@@ -218,9 +218,7 @@
 
 void SigninSupervisedUserImportHandler::RejectCallback(
     const base::string16& error) {
-  RejectJavascriptCallback(
-      base::StringValue(webui_callback_id_),
-      base::StringValue(error));
+  RejectJavascriptCallback(base::Value(webui_callback_id_), base::Value(error));
   webui_callback_id_.clear();
 }
 
@@ -297,9 +295,7 @@
   }
 
   // Resolve callback with response.
-  ResolveJavascriptCallback(
-      base::StringValue(webui_callback_id_),
-      supervised_users);
+  ResolveJavascriptCallback(base::Value(webui_callback_id_), supervised_users);
   webui_callback_id_.clear();
 }
 
diff --git a/chrome/browser/ui/webui/signin/sync_confirmation_handler.cc b/chrome/browser/ui/webui/signin/sync_confirmation_handler.cc
index 1bc5644..4cd0b140 100644
--- a/chrome/browser/ui/webui/signin/sync_confirmation_handler.cc
+++ b/chrome/browser/ui/webui/signin/sync_confirmation_handler.cc
@@ -86,7 +86,7 @@
     // Use the placeholder avatar icon until the account picture URL is fetched.
     picture_url_to_load = profiles::GetPlaceholderAvatarIconUrl();
   }
-  base::StringValue picture_url_value(picture_url_to_load);
+  base::Value picture_url_value(picture_url_to_load);
   web_ui()->CallJavascriptFunctionUnsafe("sync.confirmation.setUserImageURL",
                                          picture_url_value);
 }
diff --git a/chrome/browser/ui/webui/signin/user_manager_screen_handler.cc b/chrome/browser/ui/webui/signin/user_manager_screen_handler.cc
index 26c0eee0..142e598 100644
--- a/chrome/browser/ui/webui/signin/user_manager_screen_handler.cc
+++ b/chrome/browser/ui/webui/signin/user_manager_screen_handler.cc
@@ -322,8 +322,7 @@
 void UserManagerScreenHandler::ShowBannerMessage(
     const base::string16& message) {
   web_ui()->CallJavascriptFunctionUnsafe(
-      "login.AccountPickerScreen.showBannerMessage",
-      base::StringValue(message));
+      "login.AccountPickerScreen.showBannerMessage", base::Value(message));
 }
 
 void UserManagerScreenHandler::ShowUserPodCustomIcon(
@@ -336,14 +335,14 @@
     return;
   web_ui()->CallJavascriptFunctionUnsafe(
       "login.AccountPickerScreen.showUserPodCustomIcon",
-      base::StringValue(account_id.GetUserEmail()), *icon);
+      base::Value(account_id.GetUserEmail()), *icon);
 }
 
 void UserManagerScreenHandler::HideUserPodCustomIcon(
     const AccountId& account_id) {
   web_ui()->CallJavascriptFunctionUnsafe(
       "login.AccountPickerScreen.hideUserPodCustomIcon",
-      base::StringValue(account_id.GetUserEmail()));
+      base::Value(account_id.GetUserEmail()));
 }
 
 void UserManagerScreenHandler::EnableInput() {
@@ -361,8 +360,8 @@
   user_auth_type_map_[account_id.GetUserEmail()] = auth_type;
   web_ui()->CallJavascriptFunctionUnsafe(
       "login.AccountPickerScreen.setAuthType",
-      base::StringValue(account_id.GetUserEmail()), base::Value(auth_type),
-      base::StringValue(auth_value));
+      base::Value(account_id.GetUserEmail()), base::Value(auth_type),
+      base::Value(auth_value));
 }
 
 proximity_auth::ScreenlockBridge::LockHandler::AuthType
@@ -500,9 +499,8 @@
 
   if (profiles::AreAllNonChildNonSupervisedProfilesLocked()) {
     web_ui()->CallJavascriptFunctionUnsafe(
-        "cr.webUIListenerCallback",
-        base::StringValue("show-error-dialog"),
-        base::StringValue(l10n_util::GetStringUTF8(
+        "cr.webUIListenerCallback", base::Value("show-error-dialog"),
+        base::Value(l10n_util::GetStringUTF8(
             IDS_USER_MANAGER_REMOVE_PROFILE_PROFILES_LOCKED_ERROR)));
     return;
   }
@@ -535,7 +533,7 @@
 
   AllowJavascript();
   ResolveJavascriptCallback(
-      base::StringValue(webui_callback_id),
+      base::Value(webui_callback_id),
       base::Value(profiles::AreAllNonChildNonSupervisedProfilesLocked()));
 }
 
@@ -603,7 +601,7 @@
   if (!base::GetValueAsFilePath(*profile_path_value, &profile_path))
     return;
 
-  base::StringValue return_profile_path(profile_path.value());
+  base::Value return_profile_path(profile_path.value());
   Profile* profile = g_browser_process->profile_manager()->
       GetProfileByPath(profile_path);
 
@@ -630,9 +628,9 @@
       stats_success &= item.success;
     }
     if (stats_success) {
-      web_ui()->CallJavascriptFunctionUnsafe(
-          "updateRemoveWarningDialog", base::StringValue(profile_path.value()),
-          return_value);
+      web_ui()->CallJavascriptFunctionUnsafe("updateRemoveWarningDialog",
+                                             base::Value(profile_path.value()),
+                                             return_value);
       return;
     }
   }
@@ -654,9 +652,9 @@
     stat->SetBooleanWithoutPathExpansion("success", item.success);
     return_value.SetWithoutPathExpansion(item.category, std::move(stat));
   }
-  web_ui()->CallJavascriptFunctionUnsafe(
-      "updateRemoveWarningDialog", base::StringValue(profile_path.value()),
-      return_value);
+  web_ui()->CallJavascriptFunctionUnsafe("updateRemoveWarningDialog",
+                                         base::Value(profile_path.value()),
+                                         return_value);
 }
 
 void UserManagerScreenHandler::HandleGetRemoveWarningDialogMessage(
@@ -684,12 +682,12 @@
       (has_errors ? IDS_LOGIN_POD_USER_REMOVE_WARNING_NONSYNC_WITH_ERRORS :
                     IDS_LOGIN_POD_USER_REMOVE_WARNING_NONSYNC);
 
-  base::StringValue message = base::StringValue(
-      l10n_util::GetPluralStringFUTF16(message_id, total_count));
+  base::Value message =
+      base::Value(l10n_util::GetPluralStringFUTF16(message_id, total_count));
 
   web_ui()->CallJavascriptFunctionUnsafe("updateRemoveWarningDialogSetMessage",
-                                         base::StringValue(profile_path),
-                                         message, base::Value(total_count));
+                                         base::Value(profile_path), message,
+                                         base::Value(total_count));
 }
 
 void UserManagerScreenHandler::OnGetTokenInfoResponse(
@@ -998,11 +996,11 @@
   } else {
     web_ui()->CallJavascriptFunctionUnsafe(
         "cr.ui.UserManager.showSignInError", base::Value(0),
-        base::StringValue(l10n_util::GetStringUTF8(
+        base::Value(l10n_util::GetStringUTF8(
             auth == ProfileMetrics::AUTH_FAILED_OFFLINE
                 ? IDS_LOGIN_ERROR_AUTHENTICATING_OFFLINE
                 : IDS_LOGIN_ERROR_AUTHENTICATING)),
-        base::StringValue(""), base::Value(0));
+        base::Value(""), base::Value(0));
   }
 }
 
diff --git a/chrome/browser/ui/webui/snippets_internals_message_handler.cc b/chrome/browser/ui/webui/snippets_internals_message_handler.cc
index a186159f..c67289d6 100644
--- a/chrome/browser/ui/webui/snippets_internals_message_handler.cc
+++ b/chrome/browser/ui/webui/snippets_internals_message_handler.cc
@@ -317,7 +317,7 @@
     SendString("switch-fetch-url", fetcher->fetch_url().spec());
     web_ui()->CallJavascriptFunctionUnsafe(
         "chrome.SnippetsInternals.receiveJson",
-        base::StringValue(fetcher->last_json()));
+        base::Value(fetcher->last_json()));
   }
 
   SendContentSuggestions();
@@ -326,8 +326,8 @@
 void SnippetsInternalsMessageHandler::SendClassification() {
   web_ui()->CallJavascriptFunctionUnsafe(
       "chrome.SnippetsInternals.receiveClassification",
-      base::StringValue(content_suggestions_service_->user_classifier()
-                            ->GetUserClassDescriptionForDebugging()),
+      base::Value(content_suggestions_service_->user_classifier()
+                      ->GetUserClassDescriptionForDebugging()),
       base::Value(
           content_suggestions_service_->user_classifier()->GetEstimatedAvgTime(
               UserClassifier::Metric::NTP_OPENED)),
@@ -346,7 +346,7 @@
   web_ui()->CallJavascriptFunctionUnsafe(
       "chrome.SnippetsInternals."
       "receiveLastRemoteSuggestionsBackgroundFetchTime",
-      base::StringValue(base::TimeFormatShortDateAndTime(time)));
+      base::Value(base::TimeFormatShortDateAndTime(time)));
 }
 
 void SnippetsInternalsMessageHandler::SendContentSuggestions() {
@@ -408,8 +408,8 @@
 
 void SnippetsInternalsMessageHandler::SendString(const std::string& name,
                                                  const std::string& value) {
-  base::StringValue string_name(name);
-  base::StringValue string_value(value);
+  base::Value string_name(name);
+  base::Value string_value(value);
 
   web_ui()->CallJavascriptFunctionUnsafe(
       "chrome.SnippetsInternals.receiveProperty", string_name, string_value);
diff --git a/chrome/browser/ui/webui/sync_file_system_internals/sync_file_system_internals_handler.cc b/chrome/browser/ui/webui/sync_file_system_internals/sync_file_system_internals_handler.cc
index 57872aac..2bd6144 100644
--- a/chrome/browser/ui/webui/sync_file_system_internals/sync_file_system_internals_handler.cc
+++ b/chrome/browser/ui/webui/sync_file_system_internals/sync_file_system_internals_handler.cc
@@ -86,7 +86,7 @@
   // TODO(calvinlo): OnSyncStateUpdated should be updated to also provide the
   // notification mechanism (XMPP or Polling).
   web_ui()->CallJavascriptFunctionUnsafe("SyncService.onGetServiceStatus",
-                                         base::StringValue(state_string));
+                                         base::Value(state_string));
 }
 
 void SyncFileSystemInternalsHandler::OnFileSynced(
@@ -121,7 +121,7 @@
   const std::string state_string = extensions::api::sync_file_system::ToString(
       extensions::SyncServiceStateToExtensionEnum(state_enum));
   web_ui()->CallJavascriptFunctionUnsafe("SyncService.onGetServiceStatus",
-                                         base::StringValue(state_string));
+                                         base::Value(state_string));
 }
 
 void SyncFileSystemInternalsHandler::GetNotificationSource(
@@ -132,9 +132,8 @@
     return;
   bool xmpp_enabled = drive_notification_manager->push_notification_enabled();
   std::string notification_source = xmpp_enabled ? "XMPP" : "Polling";
-  web_ui()->CallJavascriptFunctionUnsafe(
-      "SyncService.onGetNotificationSource",
-      base::StringValue(notification_source));
+  web_ui()->CallJavascriptFunctionUnsafe("SyncService.onGetNotificationSource",
+                                         base::Value(notification_source));
 }
 
 void SyncFileSystemInternalsHandler::GetLog(
diff --git a/chrome/browser/ui/webui/sync_internals_message_handler.cc b/chrome/browser/ui/webui/sync_internals_message_handler.cc
index 4a5a532..eab283c 100644
--- a/chrome/browser/ui/webui/sync_internals_message_handler.cc
+++ b/chrome/browser/ui/webui/sync_internals_message_handler.cc
@@ -147,8 +147,7 @@
   event_details.Set(syncer::sync_ui_util::kTypes, type_list.release());
   web_ui()->CallJavascriptFunctionUnsafe(
       syncer::sync_ui_util::kDispatchEvent,
-      base::StringValue(syncer::sync_ui_util::kOnReceivedListOfTypes),
-      event_details);
+      base::Value(syncer::sync_ui_util::kOnReceivedListOfTypes), event_details);
 }
 
 void SyncInternalsMessageHandler::HandleGetAllNodes(
@@ -184,7 +183,7 @@
       syncer::ProtocolEvent::ToValue(event));
   web_ui()->CallJavascriptFunctionUnsafe(
       syncer::sync_ui_util::kDispatchEvent,
-      base::StringValue(syncer::sync_ui_util::kOnProtocolEvent), *value);
+      base::Value(syncer::sync_ui_util::kOnProtocolEvent), *value);
 }
 
 void SyncInternalsMessageHandler::OnCommitCountersUpdated(
@@ -215,7 +214,7 @@
   details->Set(syncer::sync_ui_util::kCounters, value.release());
   web_ui()->CallJavascriptFunctionUnsafe(
       syncer::sync_ui_util::kDispatchEvent,
-      base::StringValue(syncer::sync_ui_util::kOnCountersUpdated), *details);
+      base::Value(syncer::sync_ui_util::kOnCountersUpdated), *details);
 }
 
 void SyncInternalsMessageHandler::HandleJsEvent(
@@ -224,8 +223,7 @@
   DVLOG(1) << "Handling event: " << name
            << " with details " << details.ToString();
   web_ui()->CallJavascriptFunctionUnsafe(syncer::sync_ui_util::kDispatchEvent,
-                                         base::StringValue(name),
-                                         details.Get());
+                                         base::Value(name), details.Get());
 }
 
 void SyncInternalsMessageHandler::SendAboutInfo() {
@@ -236,7 +234,7 @@
                                                             signin);
   web_ui()->CallJavascriptFunctionUnsafe(
       syncer::sync_ui_util::kDispatchEvent,
-      base::StringValue(syncer::sync_ui_util::kOnAboutInfoUpdated), *value);
+      base::Value(syncer::sync_ui_util::kOnAboutInfoUpdated), *value);
 }
 
 // Gets the ProfileSyncService of the underlying original profile.
diff --git a/chrome/browser/ui/webui/translate_internals/translate_internals_handler.cc b/chrome/browser/ui/webui/translate_internals/translate_internals_handler.cc
index 43bb3f9..8827d4e8 100644
--- a/chrome/browser/ui/webui/translate_internals/translate_internals_handler.cc
+++ b/chrome/browser/ui/webui/translate_internals/translate_internals_handler.cc
@@ -89,23 +89,20 @@
   base::DictionaryValue dict;
   dict.Set("time",
            new base::Value(language_detection_details->time.ToJsTime()));
-  dict.Set("url",
-           new base::StringValue(language_detection_details->url.spec()));
+  dict.Set("url", new base::Value(language_detection_details->url.spec()));
   dict.Set("content_language",
-           new base::StringValue(language_detection_details->content_language));
+           new base::Value(language_detection_details->content_language));
   dict.Set("cld_language",
-           new base::StringValue(language_detection_details->cld_language));
+           new base::Value(language_detection_details->cld_language));
   dict.Set("is_cld_reliable",
            new base::Value(language_detection_details->is_cld_reliable));
   dict.Set("has_notranslate",
            new base::Value(language_detection_details->has_notranslate));
-  dict.Set(
-      "html_root_language",
-      new base::StringValue(language_detection_details->html_root_language));
+  dict.Set("html_root_language",
+           new base::Value(language_detection_details->html_root_language));
   dict.Set("adopted_language",
-           new base::StringValue(language_detection_details->adopted_language));
-  dict.Set("content",
-           new base::StringValue(language_detection_details->contents));
+           new base::Value(language_detection_details->adopted_language));
+  dict.Set("content", new base::Value(language_detection_details->contents));
   SendMessageToJs("languageDetectionInfoAdded", dict);
 }
 
@@ -113,7 +110,7 @@
     const translate::TranslateErrorDetails& details) {
   base::DictionaryValue dict;
   dict.Set("time", new base::Value(details.time.ToJsTime()));
-  dict.Set("url", new base::StringValue(details.url.spec()));
+  dict.Set("url", new base::Value(details.url.spec()));
   dict.Set("error", new base::Value(details.error));
   SendMessageToJs("translateErrorDetailsAdded", dict);
 }
@@ -122,9 +119,9 @@
     const translate::TranslateEventDetails& details) {
   base::DictionaryValue dict;
   dict.Set("time", new base::Value(details.time.ToJsTime()));
-  dict.Set("filename", new base::StringValue(details.filename));
+  dict.Set("filename", new base::Value(details.filename));
   dict.Set("line", new base::Value(details.line));
-  dict.Set("message", new base::StringValue(details.message));
+  dict.Set("message", new base::Value(details.message));
   SendMessageToJs("translateEventDetailsAdded", dict);
 }
 
@@ -187,7 +184,7 @@
 void TranslateInternalsHandler::SendMessageToJs(const std::string& message,
                                                 const base::Value& value) {
   const char func[] = "cr.translateInternals.messageHandler";
-  base::StringValue message_data(message);
+  base::Value message_data(message);
   web_ui()->CallJavascriptFunctionUnsafe(func, message_data, value);
 }
 
@@ -252,7 +249,7 @@
 
   base::DictionaryValue dict;
   if (!country.empty()) {
-    dict.Set("country", new base::StringValue(country));
+    dict.Set("country", new base::Value(country));
     dict.Set("update", new base::Value(was_updated));
   }
   SendMessageToJs("countryUpdated", dict);
diff --git a/chrome/browser/ui/webui/uber/uber_ui.cc b/chrome/browser/ui/webui/uber/uber_ui.cc
index e3f14a2..5cc1e167 100644
--- a/chrome/browser/ui/webui/uber/uber_ui.cc
+++ b/chrome/browser/ui/webui/uber/uber_ui.cc
@@ -133,8 +133,8 @@
                        chrome::kChromeUIHistoryHost);
   web_ui->CallJavascriptFunctionUnsafe(
       "uber_frame.setNavigationOverride",
-      base::StringValue(chrome::kChromeUIHistoryHost),
-      base::StringValue(overrides_history ? "yes" : "no"));
+      base::Value(chrome::kChromeUIHistoryHost),
+      base::Value(overrides_history ? "yes" : "no"));
 }
 
 }  // namespace
diff --git a/chrome/browser/ui/webui/user_actions/user_actions_ui_handler.cc b/chrome/browser/ui/webui/user_actions/user_actions_ui_handler.cc
index f3b9676..ef6ea8f 100644
--- a/chrome/browser/ui/webui/user_actions/user_actions_ui_handler.cc
+++ b/chrome/browser/ui/webui/user_actions/user_actions_ui_handler.cc
@@ -22,7 +22,7 @@
 void UserActionsUIHandler::RegisterMessages() {}
 
 void UserActionsUIHandler::OnUserAction(const std::string& action) {
-  base::StringValue user_action_name(action);
+  base::Value user_action_name(action);
   web_ui()->CallJavascriptFunctionUnsafe("userActions.observeUserAction",
                                          user_action_name);
 }
diff --git a/chrome/browser/ui/webui/version_handler.cc b/chrome/browser/ui/webui/version_handler.cc
index b044d55..3d7f7ba7 100644
--- a/chrome/browser/ui/webui/version_handler.cc
+++ b/chrome/browser/ui/webui/version_handler.cc
@@ -97,8 +97,8 @@
                                     base::string16* profile_path_data) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
-  base::StringValue exec_path(*executable_path_data);
-  base::StringValue profile_path(*profile_path_data);
+  base::Value exec_path(*executable_path_data);
+  base::Value profile_path(*profile_path_data);
   web_ui()->CallJavascriptFunctionUnsafe(version_ui::kReturnFilePaths,
                                          exec_path, profile_path);
 }
@@ -125,7 +125,7 @@
     }
   }
 
-  base::StringValue arg(flash_version_and_path);
+  base::Value arg(flash_version_and_path);
 
   web_ui()->CallJavascriptFunctionUnsafe(version_ui::kReturnFlashVersion, arg);
 }
diff --git a/chrome/browser/ui/webui/version_handler_chromeos.cc b/chrome/browser/ui/webui/version_handler_chromeos.cc
index f61d780d..676496b 100644
--- a/chrome/browser/ui/webui/version_handler_chromeos.cc
+++ b/chrome/browser/ui/webui/version_handler_chromeos.cc
@@ -40,16 +40,16 @@
 }
 
 void VersionHandlerChromeOS::OnVersion(const std::string& version) {
-  base::StringValue arg(version);
+  base::Value arg(version);
   web_ui()->CallJavascriptFunctionUnsafe("returnOsVersion", arg);
 }
 
 void VersionHandlerChromeOS::OnOSFirmware(const std::string& version) {
-  base::StringValue arg(version);
+  base::Value arg(version);
   web_ui()->CallJavascriptFunctionUnsafe("returnOsFirmwareVersion", arg);
 }
 
 void VersionHandlerChromeOS::OnARCVersion(const std::string& version) {
-  base::StringValue arg(version);
+  base::Value arg(version);
   web_ui()->CallJavascriptFunctionUnsafe("returnARCVersion", arg);
 }
diff --git a/chrome/browser/ui/webui/webapks_handler.cc b/chrome/browser/ui/webui/webapks_handler.cc
index 69d98c8..264fe0e4 100644
--- a/chrome/browser/ui/webui/webapks_handler.cc
+++ b/chrome/browser/ui/webui/webapks_handler.cc
@@ -4,10 +4,25 @@
 
 #include "chrome/browser/ui/webui/webapks_handler.h"
 
+#include <string>
+
 #include "base/callback_forward.h"
+#include "base/strings/stringprintf.h"
 #include "base/values.h"
 #include "chrome/browser/android/shortcut_helper.h"
 #include "content/public/browser/web_ui.h"
+#include "content/public/common/manifest_util.h"
+#include "ui/gfx/color_utils.h"
+
+namespace {
+// Converts a color from the format documented in content::Manifest to a
+// rgba() CSS string.
+std::string ColorToString(int64_t color) {
+  if (color == content::Manifest::kInvalidOrMissingColor)
+    return std::string();
+  return color_utils::SkColorToRgbaString(reinterpret_cast<uint32_t&>(color));
+}
+}  // namespace
 
 WebApksHandler::WebApksHandler() : weak_ptr_factory_(this) {}
 
@@ -33,10 +48,23 @@
   base::ListValue list;
   for (const auto& webapk_info : webapks_list) {
     std::unique_ptr<base::DictionaryValue> result(new base::DictionaryValue());
+    result->SetString("name", webapk_info.name);
     result->SetString("shortName", webapk_info.short_name);
     result->SetString("packageName", webapk_info.package_name);
     result->SetInteger("shellApkVersion", webapk_info.shell_apk_version);
     result->SetInteger("versionCode", webapk_info.version_code);
+    result->SetString("uri", webapk_info.uri);
+    result->SetString("scope", webapk_info.scope);
+    result->SetString("manifestUrl", webapk_info.manifest_url);
+    result->SetString("manifestStartUrl", webapk_info.manifest_start_url);
+    result->SetString("displayMode",
+                      content::WebDisplayModeToString(webapk_info.display));
+    result->SetString(
+        "orientation",
+        content::WebScreenOrientationLockTypeToString(webapk_info.orientation));
+    result->SetString("themeColor", ColorToString(webapk_info.theme_color));
+    result->SetString("backgroundColor",
+                      ColorToString(webapk_info.background_color));
     list.Append(std::move(result));
   }
 
diff --git a/chrome/browser/ui/webui/webui_webview_browsertest.cc b/chrome/browser/ui/webui/webui_webview_browsertest.cc
index 5c529012..250d314 100644
--- a/chrome/browser/ui/webui/webui_webview_browsertest.cc
+++ b/chrome/browser/ui/webui/webui_webview_browsertest.cc
@@ -140,8 +140,7 @@
   ui_test_utils::NavigateToURL(browser(), GetWebViewEnabledWebUIURL());
 
   ASSERT_TRUE(WebUIBrowserTest::RunJavascriptAsyncTest(
-      "testDisplayNone",
-      new base::StringValue(GetTestUrl("empty.html").spec())));
+      "testDisplayNone", new base::Value(GetTestUrl("empty.html").spec())));
 }
 
 IN_PROC_BROWSER_TEST_F(WebUIWebViewBrowserTest, ExecuteScriptCode) {
@@ -149,7 +148,7 @@
 
   ASSERT_TRUE(WebUIBrowserTest::RunJavascriptAsyncTest(
       "testExecuteScriptCode",
-      new base::StringValue(GetTestUrl("empty.html").spec())));
+      new base::Value(GetTestUrl("empty.html").spec())));
 }
 
 IN_PROC_BROWSER_TEST_F(WebUIWebViewBrowserTest, ExecuteScriptCodeFromFile) {
@@ -157,7 +156,7 @@
 
   ASSERT_TRUE(WebUIBrowserTest::RunJavascriptAsyncTest(
       "testExecuteScriptCodeFromFile",
-      new base::StringValue(GetTestUrl("empty.html").spec())));
+      new base::Value(GetTestUrl("empty.html").spec())));
 }
 
 IN_PROC_BROWSER_TEST_F(WebUIWebViewBrowserTest, AddContentScript) {
@@ -165,7 +164,7 @@
 
   ASSERT_TRUE(WebUIBrowserTest::RunJavascriptAsyncTest(
       "testAddContentScript",
-      new base::StringValue(GetTestUrl("empty.html").spec())));
+      new base::Value(GetTestUrl("empty.html").spec())));
 }
 
 IN_PROC_BROWSER_TEST_F(WebUIWebViewBrowserTest, AddMultiContentScripts) {
@@ -173,7 +172,7 @@
 
   ASSERT_TRUE(WebUIBrowserTest::RunJavascriptAsyncTest(
       "testAddMultiContentScripts",
-      new base::StringValue(GetTestUrl("empty.html").spec())));
+      new base::Value(GetTestUrl("empty.html").spec())));
 }
 
 IN_PROC_BROWSER_TEST_F(
@@ -183,7 +182,7 @@
 
   ASSERT_TRUE(WebUIBrowserTest::RunJavascriptAsyncTest(
       "testAddContentScriptWithSameNameShouldOverwriteTheExistingOne",
-      new base::StringValue(GetTestUrl("empty.html").spec())));
+      new base::Value(GetTestUrl("empty.html").spec())));
 }
 
 IN_PROC_BROWSER_TEST_F(
@@ -193,7 +192,7 @@
 
   ASSERT_TRUE(WebUIBrowserTest::RunJavascriptAsyncTest(
       "testAddContentScriptToOneWebViewShouldNotInjectToTheOtherWebView",
-      new base::StringValue(GetTestUrl("empty.html").spec())));
+      new base::Value(GetTestUrl("empty.html").spec())));
 }
 
 IN_PROC_BROWSER_TEST_F(WebUIWebViewBrowserTest, AddAndRemoveContentScripts) {
@@ -201,7 +200,7 @@
 
   ASSERT_TRUE(WebUIBrowserTest::RunJavascriptAsyncTest(
       "testAddAndRemoveContentScripts",
-      new base::StringValue(GetTestUrl("empty.html").spec())));
+      new base::Value(GetTestUrl("empty.html").spec())));
 }
 
 IN_PROC_BROWSER_TEST_F(WebUIWebViewBrowserTest,
@@ -210,7 +209,7 @@
 
   ASSERT_TRUE(WebUIBrowserTest::RunJavascriptAsyncTest(
       "testAddContentScriptsWithNewWindowAPI",
-      new base::StringValue(GetTestUrl("guest_from_opener.html").spec())));
+      new base::Value(GetTestUrl("guest_from_opener.html").spec())));
 }
 
 // https://crbug.com/665512.
@@ -221,7 +220,7 @@
 
   ASSERT_TRUE(WebUIBrowserTest::RunJavascriptAsyncTest(
       "testContentScriptIsInjectedAfterTerminateAndReloadWebView",
-      new base::StringValue(GetTestUrl("empty.html").spec())));
+      new base::Value(GetTestUrl("empty.html").spec())));
 }
 
 // TODO(crbug.com/662673) Flaky on CrOS trybots.
@@ -238,7 +237,7 @@
 
   ASSERT_TRUE(WebUIBrowserTest::RunJavascriptAsyncTest(
       "testContentScriptExistsAsLongAsWebViewTagExists",
-      new base::StringValue(GetTestUrl("empty.html").spec())));
+      new base::Value(GetTestUrl("empty.html").spec())));
 }
 
 IN_PROC_BROWSER_TEST_F(WebUIWebViewBrowserTest, AddContentScriptWithCode) {
@@ -246,7 +245,7 @@
 
   ASSERT_TRUE(WebUIBrowserTest::RunJavascriptAsyncTest(
       "testAddContentScriptWithCode",
-      new base::StringValue(GetTestUrl("empty.html").spec())));
+      new base::Value(GetTestUrl("empty.html").spec())));
 }
 
 #if defined(OS_CHROMEOS)
@@ -261,7 +260,7 @@
 
   ASSERT_TRUE(WebUIBrowserTest::RunJavascriptAsyncTest(
       "testAddContentScript",
-      new base::StringValue(GetTestUrl("empty.html").spec())));
+      new base::Value(GetTestUrl("empty.html").spec())));
 }
 #endif
 
diff --git a/chrome/browser/ui/webui/welcome_win10_handler.cc b/chrome/browser/ui/webui/welcome_win10_handler.cc
index 3fc37d4..eab42d6 100644
--- a/chrome/browser/ui/webui/welcome_win10_handler.cc
+++ b/chrome/browser/ui/webui/welcome_win10_handler.cc
@@ -171,6 +171,6 @@
 }
 
 void WelcomeWin10Handler::SendPinnedToTaskbarStateResult() {
-  ResolveJavascriptCallback(base::StringValue(pinned_state_callback_id_),
+  ResolveJavascriptCallback(base::Value(pinned_state_callback_id_),
                             base::Value(pinned_state_result_.value()));
 }
diff --git a/chrome/common/BUILD.gn b/chrome/common/BUILD.gn
index 856a1d4..947ce713 100644
--- a/chrome/common/BUILD.gn
+++ b/chrome/common/BUILD.gn
@@ -608,6 +608,10 @@
     # implemented in //ui/base, so we need that dependency.
     deps += [ "//ui/base" ]
   }
+
+  if (is_win) {
+    deps += [ "//chrome/install_static:install_static_util" ]
+  }
 }
 
 if (is_win) {
diff --git a/chrome/common/chrome_paths_win.cc b/chrome/common/chrome_paths_win.cc
index 767f967..5cc2f12 100644
--- a/chrome/common/chrome_paths_win.cc
+++ b/chrome/common/chrome_paths_win.cc
@@ -16,7 +16,7 @@
 #include "base/win/scoped_co_mem.h"
 #include "chrome/common/chrome_constants.h"
 #include "chrome/common/chrome_switches.h"
-#include "chrome/installer/util/browser_distribution.h"
+#include "chrome/install_static/install_util.h"
 #include "components/nacl/common/nacl_switches.h"
 
 namespace chrome {
@@ -45,8 +45,7 @@
 bool GetDefaultUserDataDirectory(base::FilePath* result) {
   if (!PathService::Get(base::DIR_LOCAL_APP_DATA, result))
     return false;
-  BrowserDistribution* dist = BrowserDistribution::GetDistribution();
-  *result = result->Append(dist->GetInstallSubDir());
+  *result = result->Append(install_static::GetChromeInstallSubDirectory());
   *result = result->Append(chrome::kUserDataDirname);
   return true;
 }
@@ -54,8 +53,7 @@
 bool GetDefaultRoamingUserDataDirectory(base::FilePath* result) {
   if (!PathService::Get(base::DIR_APP_DATA, result))
     return false;
-  BrowserDistribution* dist = BrowserDistribution::GetDistribution();
-  *result = result->Append(dist->GetInstallSubDir());
+  *result = result->Append(install_static::GetChromeInstallSubDirectory());
   *result = result->Append(chrome::kUserDataDirname);
   return true;
 }
diff --git a/chrome/common/custom_handlers/protocol_handler.cc b/chrome/common/custom_handlers/protocol_handler.cc
index 63f3d9ac..0990f48d 100644
--- a/chrome/common/custom_handlers/protocol_handler.cc
+++ b/chrome/common/custom_handlers/protocol_handler.cc
@@ -61,8 +61,8 @@
 
 std::unique_ptr<base::DictionaryValue> ProtocolHandler::Encode() const {
   auto d = base::MakeUnique<base::DictionaryValue>();
-  d->Set("protocol", new base::StringValue(protocol_));
-  d->Set("url", new base::StringValue(url_.spec()));
+  d->Set("protocol", new base::Value(protocol_));
+  d->Set("url", new base::Value(url_.spec()));
   return d;
 }
 
diff --git a/chrome/common/extensions/manifest_unittest.cc b/chrome/common/extensions/manifest_unittest.cc
index 8c97744..747bf8a4 100644
--- a/chrome/common/extensions/manifest_unittest.cc
+++ b/chrome/common/extensions/manifest_unittest.cc
@@ -114,8 +114,7 @@
   std::unique_ptr<Manifest> manifest2(manifest->DeepCopy());
   EXPECT_TRUE(manifest->Equals(manifest2.get()));
   EXPECT_TRUE(manifest2->Equals(manifest.get()));
-  MutateManifest(
-      &manifest, "foo", new base::StringValue("blah"));
+  MutateManifest(&manifest, "foo", new base::Value("blah"));
   EXPECT_FALSE(manifest->Equals(manifest2.get()));
 }
 
@@ -168,8 +167,7 @@
   AssertType(manifest.get(), Manifest::TYPE_HOSTED_APP);
   MutateManifest(
       &manifest, keys::kWebURLs, NULL);
-  MutateManifest(
-      &manifest, keys::kLaunchWebURL, new base::StringValue("foo"));
+  MutateManifest(&manifest, keys::kLaunchWebURL, new base::Value("foo"));
   AssertType(manifest.get(), Manifest::TYPE_HOSTED_APP);
   MutateManifest(
       &manifest, keys::kLaunchWebURL, NULL);
diff --git a/chrome/common/extensions/sync_type_unittest.cc b/chrome/common/extensions/sync_type_unittest.cc
index 8a85933..2ac283b4 100644
--- a/chrome/common/extensions/sync_type_unittest.cc
+++ b/chrome/common/extensions/sync_type_unittest.cc
@@ -65,7 +65,7 @@
     }
     if (has_plugin_permission) {
       base::ListValue* plugins = new base::ListValue();
-      plugins->Set(0, new base::StringValue("plugin"));
+      plugins->Set(0, new base::Value("plugin"));
       source.Set(keys::kPermissions, plugins);
     }
 
diff --git a/chrome/install_static/install_util.cc b/chrome/install_static/install_util.cc
index 5848021..4ee841e 100644
--- a/chrome/install_static/install_util.cc
+++ b/chrome/install_static/install_util.cc
@@ -311,6 +311,13 @@
   return InstallDetails::Get().system_level();
 }
 
+std::wstring GetChromeInstallSubDirectory() {
+  std::wstring result;
+  AppendChromeInstallSubDirectory(InstallDetails::Get().mode(),
+                                  true /* include_suffix */, &result);
+  return result;
+}
+
 const wchar_t* GetAppGuid() {
   return InstallDetails::Get().app_guid();
 }
diff --git a/chrome/install_static/install_util.h b/chrome/install_static/install_util.h
index 9dc3be1b..fcb41e6 100644
--- a/chrome/install_static/install_util.h
+++ b/chrome/install_static/install_util.h
@@ -54,6 +54,9 @@
 // Returns true if Chrome is running at system level.
 bool IsSystemInstall();
 
+// Returns the string "[kCompanyPathName\]kProductPathName[install_suffix]"
+std::wstring GetChromeInstallSubDirectory();
+
 // Returns the app GUID with which Chrome is registered with Google Update, or
 // an empty string if this brand does not integrate with Google Update. This is
 // a simple convenience wrapper around InstallDetails.
diff --git a/chrome/install_static/install_util_unittest.cc b/chrome/install_static/install_util_unittest.cc
index 1f9b1640..7653e8a 100644
--- a/chrome/install_static/install_util_unittest.cc
+++ b/chrome/install_static/install_util_unittest.cc
@@ -343,6 +343,26 @@
   DISALLOW_COPY_AND_ASSIGN(InstallStaticUtilTest);
 };
 
+TEST_P(InstallStaticUtilTest, GetChromeInstallSubDirectory) {
+#if defined(GOOGLE_CHROME_BUILD)
+  // The directory strings for the brand's install modes; parallel to
+  // kInstallModes.
+  static constexpr const wchar_t* kInstallDirs[] = {
+      L"Google\\Chrome", L"Google\\Chrome SxS",
+  };
+#else
+  // The directory strings for the brand's install modes; parallel to
+  // kInstallModes.
+  static constexpr const wchar_t* kInstallDirs[] = {
+      L"Chromium",
+  };
+#endif
+  static_assert(arraysize(kInstallDirs) == NUM_INSTALL_MODES,
+                "kInstallDirs out of date.");
+  EXPECT_THAT(GetChromeInstallSubDirectory(),
+              StrCaseEq(kInstallDirs[std::get<0>(GetParam())]));
+}
+
 TEST_P(InstallStaticUtilTest, GetAppGuid) {
   // For brands that do not integrate with Omaha/Google Update, the app guid is
   // an empty string.
diff --git a/chrome/installer/setup/install_worker_unittest.cc b/chrome/installer/setup/install_worker_unittest.cc
index 34f3aae..e746e204 100644
--- a/chrome/installer/setup/install_worker_unittest.cc
+++ b/chrome/installer/setup/install_worker_unittest.cc
@@ -198,9 +198,7 @@
     product_state.set_version(new base::Version(*current_version_));
     product_state.set_brand(L"TEST");
     product_state.set_eula_accepted(1);
-    BrowserDistribution* dist = BrowserDistribution::GetDistribution();
-    base::FilePath install_path =
-        installer::GetChromeInstallPath(system_level, dist);
+    base::FilePath install_path = installer::GetChromeInstallPath(system_level);
     product_state.SetUninstallProgram(
       install_path.AppendASCII(current_version_->GetString())
           .Append(installer::kInstallerDir)
diff --git a/chrome/installer/setup/installer_state.cc b/chrome/installer/setup/installer_state.cc
index 0578dbe..6dd4a148 100644
--- a/chrome/installer/setup/installer_state.cc
+++ b/chrome/installer/setup/installer_state.cc
@@ -133,9 +133,10 @@
     return nullptr;
 
   if (target_path_.empty()) {
-    target_path_ = product_dir ? *product_dir : GetChromeInstallPath(
-                                                    system_install(),
-                                                    the_product.distribution());
+    DCHECK_EQ(BrowserDistribution::GetDistribution(),
+              the_product.distribution());
+    target_path_ =
+        product_dir ? *product_dir : GetChromeInstallPath(system_install());
   }
 
   if (state_key_.empty())
diff --git a/chrome/installer/setup/installer_state_unittest.cc b/chrome/installer/setup/installer_state_unittest.cc
index f4d36e3..f13a745 100644
--- a/chrome/installer/setup/installer_state_unittest.cc
+++ b/chrome/installer/setup/installer_state_unittest.cc
@@ -24,6 +24,7 @@
 #include "base/win/registry.h"
 #include "base/win/scoped_handle.h"
 #include "chrome/common/chrome_constants.h"
+#include "chrome/install_static/install_util.h"
 #include "chrome/installer/util/fake_installation_state.h"
 #include "chrome/installer/util/fake_product_state.h"
 #include "chrome/installer/util/google_update_constants.h"
@@ -183,9 +184,8 @@
   EXPECT_EQ(InstallerState::USER_LEVEL, installer_state.level());
   EXPECT_EQ(InstallerState::SINGLE_INSTALL_OR_UPDATE,
             installer_state.operation());
-  EXPECT_TRUE(wcsstr(
-      installer_state.target_path().value().c_str(),
-      BrowserDistribution::GetDistribution()->GetInstallSubDir().c_str()));
+  EXPECT_TRUE(wcsstr(installer_state.target_path().value().c_str(),
+                     install_static::GetChromeInstallSubDirectory().c_str()));
   EXPECT_FALSE(installer_state.verbose_logging());
   EXPECT_EQ(installer_state.state_key(),
             BrowserDistribution::GetDistribution()->GetStateKey());
@@ -202,9 +202,8 @@
   EXPECT_EQ(InstallerState::SYSTEM_LEVEL, installer_state.level());
   EXPECT_EQ(InstallerState::SINGLE_INSTALL_OR_UPDATE,
             installer_state.operation());
-  EXPECT_TRUE(wcsstr(
-      installer_state.target_path().value().c_str(),
-      BrowserDistribution::GetDistribution()->GetInstallSubDir().c_str()));
+  EXPECT_TRUE(wcsstr(installer_state.target_path().value().c_str(),
+                     install_static::GetChromeInstallSubDirectory().c_str()));
   EXPECT_TRUE(installer_state.verbose_logging());
   EXPECT_EQ(installer_state.state_key(),
             BrowserDistribution::GetDistribution()->GetStateKey());
diff --git a/chrome/installer/setup/setup_main.cc b/chrome/installer/setup/setup_main.cc
index 7481e5f..b8d66b6 100644
--- a/chrome/installer/setup/setup_main.cc
+++ b/chrome/installer/setup/setup_main.cc
@@ -490,6 +490,7 @@
     // on top of an existing system-level installation.
     const Product& product = installer_state.product();
     BrowserDistribution* browser_dist = product.distribution();
+    DCHECK_EQ(BrowserDistribution::GetDistribution(), browser_dist);
 
     const ProductState* user_level_product_state =
         original_state.GetProductState(false);
@@ -511,8 +512,7 @@
       // Instruct Google Update to launch the existing system-level Chrome.
       // There should be no error dialog.
       base::FilePath install_path(
-          installer::GetChromeInstallPath(true,  // system
-                                          browser_dist));
+          installer::GetChromeInstallPath(true /* system_install */));
       if (install_path.empty()) {
         // Give up if we failed to construct the install path.
         *status = installer::OS_ERROR;
@@ -590,17 +590,16 @@
     const InstallerState& installer_state,
     const base::FilePath& setup_exe,
     const base::CommandLine& cmd_line) {
+  DCHECK_EQ(BrowserDistribution::GetDistribution(),
+            installer_state.product().distribution());
   // System-level Chrome will be launched via this command if its program gets
   // set below.
   base::CommandLine system_level_cmd(base::CommandLine::NO_PROGRAM);
 
-  const Product& chrome = installer_state.product();
   if (cmd_line.HasSwitch(installer::switches::kSelfDestruct) &&
       !installer_state.system_install()) {
-    BrowserDistribution* dist = chrome.distribution();
     const base::FilePath system_exe_path(
-        installer::GetChromeInstallPath(true, dist)
-            .Append(installer::kChromeExe));
+        installer::GetChromeInstallPath(true).Append(installer::kChromeExe));
     system_level_cmd.SetProgram(system_exe_path);
   }
 
diff --git a/chrome/installer/setup/uninstall.cc b/chrome/installer/setup/uninstall.cc
index 9140d27..b556a4a 100644
--- a/chrome/installer/setup/uninstall.cc
+++ b/chrome/installer/setup/uninstall.cc
@@ -823,6 +823,7 @@
                                const base::CommandLine& cmd_line) {
   InstallStatus status = installer::UNINSTALL_CONFIRMED;
   BrowserDistribution* browser_dist = product.distribution();
+  DCHECK_EQ(BrowserDistribution::GetDistribution(), browser_dist);
   const base::FilePath chrome_exe(
       installer_state.target_path().Append(installer::kChromeExe));
 
@@ -883,7 +884,7 @@
   if (cmd_line.HasSwitch(installer::switches::kSelfDestruct) &&
       !installer_state.system_install()) {
     const base::FilePath system_chrome_path(
-        GetChromeInstallPath(true, browser_dist).Append(installer::kChromeExe));
+        GetChromeInstallPath(true).Append(installer::kChromeExe));
     VLOG(1) << "Retargeting user-generated Chrome shortcuts.";
     if (base::PathExists(system_chrome_path)) {
       RetargetUserShortcutsWithArgs(installer_state, product, chrome_exe,
diff --git a/chrome/installer/util/browser_distribution.cc b/chrome/installer/util/browser_distribution.cc
index 6dda8cd..009b095 100644
--- a/chrome/installer/util/browser_distribution.cc
+++ b/chrome/installer/util/browser_distribution.cc
@@ -20,6 +20,7 @@
 #include "base/win/windows_version.h"
 #include "chrome/common/chrome_icon_resources_win.h"
 #include "chrome/common/env_vars.h"
+#include "chrome/install_static/install_util.h"
 #include "chrome/installer/util/app_registration_data.h"
 #include "chrome/installer/util/google_chrome_distribution.h"
 #include "chrome/installer/util/google_chrome_sxs_distribution.h"
@@ -160,10 +161,6 @@
 }
 
 
-base::string16 BrowserDistribution::GetInstallSubDir() {
-  return L"Chromium";
-}
-
 base::string16 BrowserDistribution::GetPublisherName() {
   return L"Chromium";
 }
@@ -187,7 +184,8 @@
 }
 
 base::string16 BrowserDistribution::GetRegistryPath() {
-  return base::string16(L"Software\\").append(GetInstallSubDir());
+  return base::string16(L"Software\\")
+      .append(install_static::GetChromeInstallSubDirectory());
 }
 
 base::string16 BrowserDistribution::GetUninstallRegPath() {
diff --git a/chrome/installer/util/browser_distribution.h b/chrome/installer/util/browser_distribution.h
index 4a0c40f..5d0978d 100644
--- a/chrome/installer/util/browser_distribution.h
+++ b/chrome/installer/util/browser_distribution.h
@@ -98,8 +98,6 @@
   // Returns the Browser ProgId description.
   virtual base::string16 GetBrowserProgIdDesc();
 
-  virtual base::string16 GetInstallSubDir();
-
   virtual base::string16 GetPublisherName();
 
   virtual base::string16 GetAppDescription();
diff --git a/chrome/installer/util/fake_installation_state.h b/chrome/installer/util/fake_installation_state.h
index 3f64218..e7af25c9 100644
--- a/chrome/installer/util/fake_installation_state.h
+++ b/chrome/installer/util/fake_installation_state.h
@@ -21,8 +21,7 @@
   void AddChrome(bool system_install, base::Version* version) {
     FakeProductState chrome_state;
     chrome_state.set_version(version);
-    base::FilePath setup_exe(GetChromeInstallPath(
-        system_install, BrowserDistribution::GetDistribution()));
+    base::FilePath setup_exe(GetChromeInstallPath(system_install));
     setup_exe = setup_exe
         .AppendASCII(version->GetString())
         .Append(kInstallerDir)
diff --git a/chrome/installer/util/google_chrome_distribution.cc b/chrome/installer/util/google_chrome_distribution.cc
index c4701ed..3134ba7 100644
--- a/chrome/installer/util/google_chrome_distribution.cc
+++ b/chrome/installer/util/google_chrome_distribution.cc
@@ -178,13 +178,6 @@
   return kBrowserProgIdDesc;
 }
 
-base::string16 GoogleChromeDistribution::GetInstallSubDir() {
-  base::string16 sub_dir(installer::kGoogleChromeInstallSubDir1);
-  sub_dir.append(L"\\");
-  sub_dir.append(installer::kGoogleChromeInstallSubDir2);
-  return sub_dir;
-}
-
 base::string16 GoogleChromeDistribution::GetPublisherName() {
   const base::string16& publisher_name =
       installer::GetLocalizedString(IDS_ABOUT_VERSION_COMPANY_NAME_BASE);
diff --git a/chrome/installer/util/google_chrome_distribution.h b/chrome/installer/util/google_chrome_distribution.h
index 415d570..3763ee1e 100644
--- a/chrome/installer/util/google_chrome_distribution.h
+++ b/chrome/installer/util/google_chrome_distribution.h
@@ -51,8 +51,6 @@
 
   base::string16 GetBrowserProgIdDesc() override;
 
-  base::string16 GetInstallSubDir() override;
-
   base::string16 GetPublisherName() override;
 
   base::string16 GetAppDescription() override;
diff --git a/chrome/installer/util/google_chrome_distribution_dummy.cc b/chrome/installer/util/google_chrome_distribution_dummy.cc
index f2e8ec7..7844c6f 100644
--- a/chrome/installer/util/google_chrome_distribution_dummy.cc
+++ b/chrome/installer/util/google_chrome_distribution_dummy.cc
@@ -64,10 +64,6 @@
   return base::string16();
 }
 
-base::string16 GoogleChromeDistribution::GetInstallSubDir() {
-  return base::string16();
-}
-
 base::string16 GoogleChromeDistribution::GetPublisherName() {
   return base::string16();
 }
diff --git a/chrome/installer/util/google_chrome_sxs_distribution.cc b/chrome/installer/util/google_chrome_sxs_distribution.cc
index 4401118..2646e6e 100644
--- a/chrome/installer/util/google_chrome_sxs_distribution.cc
+++ b/chrome/installer/util/google_chrome_sxs_distribution.cc
@@ -59,11 +59,6 @@
   return kBrowserProgIdDesc;
 }
 
-base::string16 GoogleChromeSxSDistribution::GetInstallSubDir() {
-  return GoogleChromeDistribution::GetInstallSubDir().append(
-      installer::kSxSSuffix);
-}
-
 base::string16 GoogleChromeSxSDistribution::GetUninstallRegPath() {
   return GoogleChromeDistribution::GetUninstallRegPath().append(
       installer::kSxSSuffix);
diff --git a/chrome/installer/util/google_chrome_sxs_distribution.h b/chrome/installer/util/google_chrome_sxs_distribution.h
index 9992d5e..55ca0745 100644
--- a/chrome/installer/util/google_chrome_sxs_distribution.h
+++ b/chrome/installer/util/google_chrome_sxs_distribution.h
@@ -27,7 +27,6 @@
   base::string16 GetBaseAppId() override;
   base::string16 GetBrowserProgIdPrefix() override;
   base::string16 GetBrowserProgIdDesc() override;
-  base::string16 GetInstallSubDir() override;
   base::string16 GetUninstallRegPath() override;
   DefaultBrowserControlPolicy GetDefaultBrowserControlPolicy() override;
   base::string16 GetCommandExecuteImplClsid() override;
diff --git a/chrome/installer/util/helper.cc b/chrome/installer/util/helper.cc
index e8159d8c..1b5b94e 100644
--- a/chrome/installer/util/helper.cc
+++ b/chrome/installer/util/helper.cc
@@ -5,13 +5,12 @@
 #include "chrome/installer/util/helper.h"
 
 #include "base/path_service.h"
-#include "chrome/installer/util/browser_distribution.h"
+#include "chrome/install_static/install_util.h"
 #include "chrome/installer/util/util_constants.h"
 
 namespace installer {
 
-base::FilePath GetChromeInstallPath(bool system_install,
-                                    BrowserDistribution* dist) {
+base::FilePath GetChromeInstallPath(bool system_install) {
   base::FilePath install_path;
 #if defined(_WIN64)
   // TODO(wfh): Place Chrome binaries into DIR_PROGRAM_FILESX86 until the code
@@ -22,7 +21,8 @@
   int key = system_install ? base::DIR_PROGRAM_FILES : base::DIR_LOCAL_APP_DATA;
 #endif
   if (PathService::Get(key, &install_path)) {
-    install_path = install_path.Append(dist->GetInstallSubDir());
+    install_path =
+        install_path.Append(install_static::GetChromeInstallSubDirectory());
     install_path = install_path.Append(kInstallBinaryDir);
   }
   return install_path;
diff --git a/chrome/installer/util/helper.h b/chrome/installer/util/helper.h
index c2c74e7e..5dadc32 100644
--- a/chrome/installer/util/helper.h
+++ b/chrome/installer/util/helper.h
@@ -9,8 +9,6 @@
 
 #include "base/files/file_path.h"
 
-class BrowserDistribution;
-
 namespace installer {
 
 // This function returns the install path for Chrome depending on whether its
@@ -18,8 +16,7 @@
 // system_install: if true, the function returns system wide location
 //                 (ProgramFiles\Google). Otherwise it returns user specific
 //                 location (Document And Settings\<user>\Local Settings...)
-base::FilePath GetChromeInstallPath(bool system_install,
-                                    BrowserDistribution* dist);
+base::FilePath GetChromeInstallPath(bool system_install);
 
 }  // namespace installer
 
diff --git a/chrome/installer/util/util_constants.cc b/chrome/installer/util/util_constants.cc
index 22a5465..27b6743 100644
--- a/chrome/installer/util/util_constants.cc
+++ b/chrome/installer/util/util_constants.cc
@@ -202,8 +202,6 @@
 const wchar_t kChromeOldExe[] = L"old_chrome.exe";
 const wchar_t kCmdOnOsUpgrade[] = L"on-os-upgrade";
 const wchar_t kEULASentinelFile[] = L"EULA Accepted";
-const wchar_t kGoogleChromeInstallSubDir1[] = L"Google";
-const wchar_t kGoogleChromeInstallSubDir2[] = L"Chrome";
 const wchar_t kInstallBinaryDir[] = L"Application";
 const wchar_t kInstallerDir[] = L"Installer";
 const wchar_t kInstallTempDir[] = L"Temp";
diff --git a/chrome/installer/util/util_constants.h b/chrome/installer/util/util_constants.h
index 4d8e4521..644c7b33 100644
--- a/chrome/installer/util/util_constants.h
+++ b/chrome/installer/util/util_constants.h
@@ -205,8 +205,6 @@
 extern const wchar_t kChromeOldExe[];
 extern const wchar_t kCmdOnOsUpgrade[];
 extern const wchar_t kEULASentinelFile[];
-extern const wchar_t kGoogleChromeInstallSubDir1[];
-extern const wchar_t kGoogleChromeInstallSubDir2[];
 extern const wchar_t kInstallBinaryDir[];
 extern const wchar_t kInstallerDir[];
 extern const wchar_t kInstallTempDir[];
diff --git a/chrome/service/service_process_prefs.cc b/chrome/service/service_process_prefs.cc
index 71886cfb..e829880f 100644
--- a/chrome/service/service_process_prefs.cc
+++ b/chrome/service/service_process_prefs.cc
@@ -40,7 +40,7 @@
 
 void ServiceProcessPrefs::SetString(const std::string& key,
                                     const std::string& value) {
-  prefs_->SetValue(key, base::MakeUnique<base::StringValue>(value),
+  prefs_->SetValue(key, base::MakeUnique<base::Value>(value),
                    WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
 }
 
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index a5f5007e..8872fe5 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -572,18 +572,6 @@
           "base/interactive_test_utils_views.cc",
         ]
       }
-      if (is_win || is_linux) {
-        # TODO(crbug.com/679127): Investigate why these tests currently break
-        # on Mac, and enable them.
-        sources += [
-          "../browser/ui/views/payments/payment_method_view_controller_interactive_uitest.cc",
-          "../browser/ui/views/payments/payment_request_credit_card_editor_interactive_uitest.cc",
-          "../browser/ui/views/payments/payment_request_interactive_uitest.cc",
-          "../browser/ui/views/payments/payment_request_interactive_uitest_base.cc",
-          "../browser/ui/views/payments/payment_request_interactive_uitest_base.h",
-          "../browser/ui/views/payments/payment_sheet_view_controller_interactive_uitest.cc",
-        ]
-      }
       if (is_linux) {
         if (!is_chromeos) {
           # Desktop linux.
@@ -2147,6 +2135,12 @@
         "../browser/ui/views/frame/browser_non_client_frame_view_browsertest_win.cc",
         "../browser/ui/views/frame/browser_window_property_manager_browsertest_win.cc",
         "../browser/ui/views/location_bar/content_setting_bubble_dialog_browsertest.cc",
+        "../browser/ui/views/payments/credit_card_editor_view_controller_browsertest.cc",
+        "../browser/ui/views/payments/payment_method_view_controller_browsertest.cc",
+        "../browser/ui/views/payments/payment_request_browsertest.cc",
+        "../browser/ui/views/payments/payment_request_browsertest_base.cc",
+        "../browser/ui/views/payments/payment_request_browsertest_base.h",
+        "../browser/ui/views/payments/payment_sheet_view_controller_browsertest.cc",
         "../browser/ui/views/select_file_dialog_extension_browsertest.cc",
         "../browser/ui/views/sync/profile_signin_confirmation_dialog_views_browsertest.cc",
       ]
@@ -3125,6 +3119,7 @@
     "../browser/browsing_data/browsing_data_service_worker_helper_unittest.cc",
     "../browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc",
     "../browser/browsing_data/cookies_tree_model_unittest.cc",
+    "../browser/browsing_data/site_data_counting_helper_unittest.cc",
     "../browser/browsing_data/site_data_size_collector_unittest.cc",
     "../browser/budget_service/budget_database_unittest.cc",
     "../browser/budget_service/budget_manager_unittest.cc",
diff --git a/chrome/test/base/extension_js_browser_test.cc b/chrome/test/base/extension_js_browser_test.cc
index 48c9c9b4..403b48c7 100644
--- a/chrome/test/base/extension_js_browser_test.cc
+++ b/chrome/test/base/extension_js_browser_test.cc
@@ -33,8 +33,8 @@
   if (!load_waiter_->browser_context())
     return false;
   ConstValueVector args;
-  args.push_back(new base::StringValue(test_fixture));
-  args.push_back(new base::StringValue(test_name));
+  args.push_back(new base::Value(test_fixture));
+  args.push_back(new base::Value(test_name));
   std::vector<base::string16> scripts;
   if (!libs_loaded_) {
     BuildJavascriptLibraries(&scripts);
diff --git a/chrome/test/base/javascript_browser_test.cc b/chrome/test/base/javascript_browser_test.cc
index f0deef37..3d762f2 100644
--- a/chrome/test/base/javascript_browser_test.cc
+++ b/chrome/test/base/javascript_browser_test.cc
@@ -108,7 +108,7 @@
   ConstValueVector arguments;
   base::Value* is_async_arg = new base::Value(is_async);
   arguments.push_back(is_async_arg);
-  base::StringValue* function_name_arg = new base::StringValue(function_name);
+  base::Value* function_name_arg = new base::Value(function_name);
   arguments.push_back(function_name_arg);
   base::ListValue* baked_argument_list = new base::ListValue();
   ConstValueVector::const_iterator arguments_iterator;
diff --git a/chrome/test/base/v8_unit_test.cc b/chrome/test/base/v8_unit_test.cc
index 92c3ae58..2e7976a1 100644
--- a/chrome/test/base/v8_unit_test.cc
+++ b/chrome/test/base/v8_unit_test.cc
@@ -6,6 +6,8 @@
 
 #include "base/files/file_util.h"
 #include "base/logging.h"
+#include "base/memory/ptr_util.h"
+#include "base/message_loop/message_loop.h"
 #include "base/path_service.h"
 #include "base/strings/string_piece.h"
 #include "base/strings/stringprintf.h"
@@ -192,6 +194,8 @@
   console->Set(v8::String::NewFromUtf8(isolate, "error"), error_function);
 
   context_.Reset(isolate, v8::Context::New(isolate, NULL, global));
+
+  loop_ = base::MakeUnique<base::MessageLoop>();
 }
 
 void V8UnitTest::SetGlobalStringVar(const std::string& var_name,
diff --git a/chrome/test/base/v8_unit_test.h b/chrome/test/base/v8_unit_test.h
index 830da54..2184973 100644
--- a/chrome/test/base/v8_unit_test.h
+++ b/chrome/test/base/v8_unit_test.h
@@ -13,6 +13,10 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "v8/include/v8.h"
 
+namespace base {
+class MessageLoop;
+}  // namespace base
+
 // A superclass for unit tests that involve running JavaScript.  This class
 // sets up V8 context and has methods that make it easy to execute scripts in
 // this context as well as call functions in the context.
@@ -82,6 +86,8 @@
 
   // User added libraries.
   std::vector<base::FilePath> user_libraries_;
+
+  std::unique_ptr<base::MessageLoop> loop_;
 };
 
 #endif  // CHROME_TEST_BASE_V8_UNIT_TEST_H_
diff --git a/chrome/test/base/web_ui_browser_test.cc b/chrome/test/base/web_ui_browser_test.cc
index 4c8d5bc7..fd4e69d5 100644
--- a/chrome/test/base/web_ui_browser_test.cc
+++ b/chrome/test/base/web_ui_browser_test.cc
@@ -126,8 +126,8 @@
                                           const std::string& test_fixture,
                                           const std::string& test_name) {
   ConstValueVector args;
-  args.push_back(new base::StringValue(test_fixture));
-  args.push_back(new base::StringValue(test_name));
+  args.push_back(new base::Value(test_fixture));
+  args.push_back(new base::Value(test_name));
 
   if (is_async)
     return RunJavascriptAsyncTest("RUN_TEST_F", args);
@@ -207,8 +207,8 @@
     RenderViewHost* preload_host) {
   ASSERT_FALSE(libraries_preloaded_);
   ConstValueVector args;
-  args.push_back(new base::StringValue(preload_test_fixture));
-  args.push_back(new base::StringValue(preload_test_name));
+  args.push_back(new base::Value(preload_test_fixture));
+  args.push_back(new base::Value(preload_test_name));
   RunJavascriptUsingHandler(
       "preloadJavascriptLibraries", args, false, false, preload_host);
   libraries_preloaded_ = true;
diff --git a/chrome/test/base/web_ui_browser_test_browsertest.cc b/chrome/test/base/web_ui_browser_test_browsertest.cc
index 5b7f673..0f8906e 100644
--- a/chrome/test/base/web_ui_browser_test_browsertest.cc
+++ b/chrome/test/base/web_ui_browser_test_browsertest.cc
@@ -90,12 +90,12 @@
 
   // Starts a failing test.
   void RunTestFailsAssert() {
-    RunJavascriptFunction("runAsync", new base::StringValue("testFailsAssert"));
+    RunJavascriptFunction("runAsync", new base::Value("testFailsAssert"));
   }
 
   // Starts a passing test.
   void RunTestPasses() {
-    RunJavascriptFunction("runAsync", new base::StringValue("testPasses"));
+    RunJavascriptFunction("runAsync", new base::Value("testPasses"));
   }
 
  protected:
@@ -165,8 +165,8 @@
 // message). (Async version).
 IN_PROC_BROWSER_TEST_F(WebUIBrowserAsyncTest, TestAsyncFailsAssert) {
   EXPECT_CALL(message_handler_, HandleTestFails(::testing::_));
-  ASSERT_FALSE(RunJavascriptAsyncTest(
-      "startAsyncTest", new base::StringValue("testFailsAssert")));
+  ASSERT_FALSE(RunJavascriptAsyncTest("startAsyncTest",
+                                      new base::Value("testFailsAssert")));
 }
 
 // Test that expectations continue the function, but fail the test.
@@ -174,8 +174,8 @@
   ::testing::InSequence s;
   EXPECT_CALL(message_handler_, HandleTestContinues(::testing::_));
   EXPECT_CALL(message_handler_, HandleTestFails(::testing::_));
-  ASSERT_FALSE(RunJavascriptAsyncTest(
-      "startAsyncTest", new base::StringValue("testFailsExpect")));
+  ASSERT_FALSE(RunJavascriptAsyncTest("startAsyncTest",
+                                      new base::Value("testFailsExpect")));
 }
 
 // Test that test continues and passes. (Sync version).
@@ -191,8 +191,8 @@
   EXPECT_CALL(message_handler_, HandleTestPasses(::testing::_))
       .WillOnce(::testing::InvokeWithoutArgs(
           this, &WebUIBrowserAsyncTest::TestDone));
-  ASSERT_TRUE(RunJavascriptAsyncTest(
-      "startAsyncTest", new base::StringValue("testPasses")));
+  ASSERT_TRUE(
+      RunJavascriptAsyncTest("startAsyncTest", new base::Value("testPasses")));
 }
 
 // Test that two tests pass.
@@ -206,8 +206,8 @@
   EXPECT_CALL(message_handler_, HandleTestPasses(::testing::_))
       .WillOnce(::testing::InvokeWithoutArgs(
           this, &WebUIBrowserAsyncTest::TestDone));
-  ASSERT_TRUE(RunJavascriptAsyncTest(
-      "startAsyncTest", new base::StringValue("testPasses")));
+  ASSERT_TRUE(
+      RunJavascriptAsyncTest("startAsyncTest", new base::Value("testPasses")));
 }
 
 // Test that first test passes; second fails.
@@ -218,8 +218,8 @@
       .WillOnce(::testing::InvokeWithoutArgs(
           this, &WebUIBrowserAsyncTest::RunTestFailsAssert));
   EXPECT_CALL(message_handler_, HandleTestFails(::testing::_));
-  ASSERT_FALSE(RunJavascriptAsyncTest(
-      "startAsyncTest", new base::StringValue("testPasses")));
+  ASSERT_FALSE(
+      RunJavascriptAsyncTest("startAsyncTest", new base::Value("testPasses")));
 }
 
 // Test that testDone() with failure first then sync pass still fails.
@@ -231,7 +231,7 @@
   // Call runAsync directly instead of deferring through startAsyncTest. It will
   // call testDone() on failure, then return.
   ASSERT_FALSE(RunJavascriptAsyncTest(
-      "runAsync", new base::StringValue("testAsyncDoneFailFirstSyncPass")));
+      "runAsync", new base::Value("testAsyncDoneFailFirstSyncPass")));
 }
 
 // Test that calling testDone during RunJavascriptAsyncTest still completes
diff --git a/chrome/test/chromedriver/alert_commands.cc b/chrome/test/chromedriver/alert_commands.cc
index 9910dd77..682ab962 100644
--- a/chrome/test/chromedriver/alert_commands.cc
+++ b/chrome/test/chromedriver/alert_commands.cc
@@ -57,7 +57,7 @@
       web_view->GetJavaScriptDialogManager()->GetDialogMessage(&message);
   if (status.IsError())
     return status;
-  value->reset(new base::StringValue(message));
+  value->reset(new base::Value(message));
   return Status(kOk);
 }
 
diff --git a/chrome/test/chromedriver/chrome/log.cc b/chrome/test/chromedriver/chrome/log.cc
index c98ab48..93024c0 100644
--- a/chrome/test/chromedriver/chrome/log.cc
+++ b/chrome/test/chromedriver/chrome/log.cc
@@ -72,7 +72,7 @@
     return std::move(list_copy);
   } else if (value->GetAsString(&data)) {
     TruncateString(&data);
-    return std::unique_ptr<base::Value>(new base::StringValue(data));
+    return std::unique_ptr<base::Value>(new base::Value(data));
   }
   return std::unique_ptr<base::Value>(value->DeepCopy());
 }
@@ -110,6 +110,6 @@
 std::string FormatJsonForDisplay(const std::string& json) {
   std::unique_ptr<base::Value> value = base::JSONReader::Read(json);
   if (!value)
-    value.reset(new base::StringValue(json));
+    value.reset(new base::Value(json));
   return FormatValueForDisplay(*value);
 }
diff --git a/chrome/test/chromedriver/commands.cc b/chrome/test/chromedriver/commands.cc
index 64a8aee..3087083 100644
--- a/chrome/test/chromedriver/commands.cc
+++ b/chrome/test/chromedriver/commands.cc
@@ -92,7 +92,7 @@
   (*session_remaining_count)--;
 
   std::unique_ptr<base::DictionaryValue> session(new base::DictionaryValue());
-  session->Set("id", new base::StringValue(session_id));
+  session->Set("id", new base::Value(session_id));
   session->Set("capabilities", value->DeepCopy());
   session_list->Append(std::move(session));
 
diff --git a/chrome/test/chromedriver/commands_unittest.cc b/chrome/test/chromedriver/commands_unittest.cc
index af76682..8f61845 100644
--- a/chrome/test/chromedriver/commands_unittest.cc
+++ b/chrome/test/chromedriver/commands_unittest.cc
@@ -71,8 +71,8 @@
   std::unique_ptr<base::DictionaryValue> capabilities(
       new base::DictionaryValue());
 
-  capabilities->Set("capability1", new base::StringValue("test1"));
-  capabilities->Set("capability2", new base::StringValue("test2"));
+  capabilities->Set("capability1", new base::Value("test1"));
+  capabilities->Set("capability2", new base::Value("test2"));
 
   callback.Run(Status(kOk), std::move(capabilities), session_id, false);
 }
diff --git a/chrome/test/chromedriver/element_commands.cc b/chrome/test/chromedriver/element_commands.cc
index 7f3d164..403e721 100644
--- a/chrome/test/chromedriver/element_commands.cc
+++ b/chrome/test/chromedriver/element_commands.cc
@@ -515,7 +515,7 @@
       session, web_view, element_id, property_name, &property_value);
   if (status.IsError())
     return status;
-  value->reset(new base::StringValue(property_value));
+  value->reset(new base::Value(property_value));
   return Status(kOk);
 }
 
diff --git a/chrome/test/chromedriver/session_commands.cc b/chrome/test/chromedriver/session_commands.cc
index 528603c..1a39f53 100644
--- a/chrome/test/chromedriver/session_commands.cc
+++ b/chrome/test/chromedriver/session_commands.cc
@@ -279,8 +279,7 @@
   if (status.IsError())
     return status;
 
-  value->reset(
-      new base::StringValue(WebViewIdToWindowHandle(web_view->GetId())));
+  value->reset(new base::Value(WebViewIdToWindowHandle(web_view->GetId())));
   return Status(kOk);
 }
 
@@ -822,7 +821,7 @@
   if (status.IsError())
     return Status(kUnknownError, "unable to unzip 'file'", status);
 
-  value->reset(new base::StringValue(upload.value()));
+  value->reset(new base::Value(upload.value()));
   return Status(kOk);
 }
 
diff --git a/chrome/test/chromedriver/window_commands.cc b/chrome/test/chromedriver/window_commands.cc
index 5aa83bc..7444d47 100644
--- a/chrome/test/chromedriver/window_commands.cc
+++ b/chrome/test/chromedriver/window_commands.cc
@@ -486,7 +486,7 @@
         return status;
     }
   }
-  value->reset(new base::StringValue(url));
+  value->reset(new base::Value(url));
   return Status(kOk);
 }
 
@@ -885,7 +885,7 @@
   if (status.IsError())
     return status;
 
-  value->reset(new base::StringValue(screenshot));
+  value->reset(new base::Value(screenshot));
   return Status(kOk);
 }
 
diff --git a/chrome/test/data/extensions/api_test/platform_keys/ca.cnf b/chrome/test/data/extensions/api_test/platform_keys/ca.cnf
index ddac803..57fa960 100644
--- a/chrome/test/data/extensions/api_test/platform_keys/ca.cnf
+++ b/chrome/test/data/extensions/api_test/platform_keys/ca.cnf
@@ -27,6 +27,7 @@
 subjectKeyIdentifier   = hash
 authorityKeyIdentifier = keyid:always
 extendedKeyUsage       = serverAuth, clientAuth
+subjectAltName         = DNS:${ENV::CN}
 
 [ca_cert]
 # Extensions to add when signing a request for an intermediate/CA cert
@@ -54,4 +55,4 @@
 distinguished_name = dn
 
 [dn]
-CN = $ENV::CN
+CN = ${ENV::CN}
diff --git a/chrome/test/data/extensions/api_test/platform_keys/l1_interm.der b/chrome/test/data/extensions/api_test/platform_keys/l1_interm.der
index f56ea482..501208c 100644
--- a/chrome/test/data/extensions/api_test/platform_keys/l1_interm.der
+++ b/chrome/test/data/extensions/api_test/platform_keys/l1_interm.der
Binary files differ
diff --git a/chrome/test/data/extensions/api_test/platform_keys/l1_leaf.der b/chrome/test/data/extensions/api_test/platform_keys/l1_leaf.der
index 358380c..7cb81071f 100644
--- a/chrome/test/data/extensions/api_test/platform_keys/l1_leaf.der
+++ b/chrome/test/data/extensions/api_test/platform_keys/l1_leaf.der
Binary files differ
diff --git a/chrome/test/data/extensions/api_test/platform_keys/l2_leaf.der b/chrome/test/data/extensions/api_test/platform_keys/l2_leaf.der
index 04774369..e1ad77e 100644
--- a/chrome/test/data/extensions/api_test/platform_keys/l2_leaf.der
+++ b/chrome/test/data/extensions/api_test/platform_keys/l2_leaf.der
Binary files differ
diff --git a/chrome/test/data/extensions/api_test/platform_keys/root.pem b/chrome/test/data/extensions/api_test/platform_keys/root.pem
index 8681990..2f10875 100644
--- a/chrome/test/data/extensions/api_test/platform_keys/root.pem
+++ b/chrome/test/data/extensions/api_test/platform_keys/root.pem
@@ -1,19 +1,19 @@
 -----BEGIN CERTIFICATE-----
-MIIDBDCCAeygAwIBAgIJAPzptz/6abHIMA0GCSqGSIb3DQEBCwUAMA8xDTALBgNV
-BAMMBHJvb3QwHhcNMTUwNTE5MDkzMTQwWhcNMjUwNTE2MDkzMTQwWjAPMQ0wCwYD
-VQQDDARyb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqFm0ruJH
-FcsiLRY+j1LaW2StdCyKSG0LVqb4RYrzuVi1rPbAC9+L9QP1zQL8iwQSGplpvUR6
-lZW2ykL9OgUroje6BQYl9RkUyHF3a3iG5wqHB1ileUmu69+fcCl1ohUfwgWW3QWf
-Kglp1wyThOOaiOclV2K9e/JxEoq8Ng6BvBE4coGr7tHQxajbcjoDkyMC+yXneghn
-yyeNS1qZ+kY3Aw3KQVc+wJ5EyuErM3ARDaT1fVOfiyS2kbpRCqFlhYGdCFp8ebuk
-PY7FJLFvmPp8A41bEqLXgJ4l9ynGHqyYmf+n7PKg6HChRnWGIrha2SsPaIfDX8Sh
-Cf8vaxR3KPAFMwIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRT
-t0RZWqsOg9uMi/BtiODSFRcV2DAfBgNVHSMEGDAWgBRTt0RZWqsOg9uMi/BtiODS
-FRcV2DAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAFX09PBL4l+T
-Wp1GjA/oVYtF8D6ZJ0w9+5bcTk8QlwBbNjKa55b6q6vzyx02kXsldJzcQjMoWWLg
-YQ+c1tngd6UoMEdQzGnc93WR2DDNXEZgEGbFfydxRx6PHNtGWN5vRSwANScCG6NA
-PEcIDOT3gZ9sXaogYqzwXwpc0bv3r6Ema9ZPO7QzCVnqJVFyDXHdGDSSZ55jDAep
-yqTSzGLalPWTfkqCULIzRtOT6aAtYUtbNNp3XbxOtw8EMxfBvmD5Rniy0yw43KMI
-raG5YyEDaV72xTKpYs/UDImvT7LgS0XFRP7jH5agqjKkCLy1gBYnue0BAI7qusWA
-3CqAWWi3btw=
+MIIDBDCCAeygAwIBAgIJAPOnDaWbXYCtMA0GCSqGSIb3DQEBBQUAMA8xDTALBgNV
+BAMMBHJvb3QwHhcNMTcwMzAzMDY1NzAxWhcNMjcwMzAxMDY1NzAxWjAPMQ0wCwYD
+VQQDDARyb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqAI+E44b
+WMGGLZxDxKjuOHtOlKxW7V5zrfoLOY+4zoabJ7AsIO6wvNAT8QBkwaEUYvQlkmgT
+f0VtBlxkcS+l+lKHNAlTAPWr1JnL2rckL/s7ll5jGOCeXoaRTNoFm1SSvouN0iKz
+8Ph0Z68F2iC6Z/EdykDvMfkz4sXBcVv2VS9Hf7ruOXed25HMiXtQU/RnhGr72rGx
+TIn7ttb5Yg7Jykey94vIHaOd6+LOWYnTS2wucvR/JQp5u4RfcEnyw2KYknmTJguM
+Y7l72Pcp7lZepvlMdB34oniBD9IkRxxY9qoQF+7PII046jwNgs/mlv8HrkF3ZP8J
+xX150krIhvIbjQIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRm
+k2ll7KjvWLmhuU1kp6q2NzNVOjAfBgNVHSMEGDAWgBRmk2ll7KjvWLmhuU1kp6q2
+NzNVOjAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBAErO+cG1AMXW
+nYmXUGQNYVqfYjXGGOf8HNoi6nGmYmw7gvR1EVP5OQAQDWH2Ae4RYmPZ685RX3i9
+Y5xOnwc6SDjYEekhkryjm/RdittgdK3bmVmpJ1bh8j3cy8QwMwT1fZaD3oI1Q4Ql
+QeqWkKCE2AP2poKOtYh22/L9BUhMe+F3ZTi8VroV+CEeZcBxO1GRVgL2A8H0QPyz
+vaCBvHSRJWmkXhukPg3qntbJtB8eCSJLHyl4yVRbG6X1H1QByOPZChCUGevRF5Zf
+PrPhzJnBXAatHIYCI9ZlVEaXVScqwXEpnpwcFVcRPKblLX2wTLG4lg01RZYc//vL
+VoN+PcoAMMg=
 -----END CERTIFICATE-----
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json
index 6e04df2..2ad48a9 100644
--- a/chrome/test/data/policy/policy_test_cases.json
+++ b/chrome/test/data/policy/policy_test_cases.json
@@ -693,6 +693,16 @@
     ]
   },
 
+  "EnableCommonNameFallbackForLocalAnchors": {
+    "os": ["win", "linux", "mac", "chromeos", "android"],
+    "test_policy": { "EnableCommonNameFallbackForLocalAnchors": true },
+    "pref_mappings": [
+      { "pref": "ssl.common_name_fallback_enabled_for_local_anchors",
+        "local_state": true
+      }
+    ]
+  },
+
   "AuthSchemes": {
     "os": ["win", "linux", "mac", "chromeos", "android"],
     "test_policy": { "AuthSchemes": "AuthSchemes" },
diff --git a/chrome/test/data/webui/settings/controlled_button_tests.js b/chrome/test/data/webui/settings/controlled_button_tests.js
index 3a66529..100bc4c9 100644
--- a/chrome/test/data/webui/settings/controlled_button_tests.js
+++ b/chrome/test/data/webui/settings/controlled_button_tests.js
@@ -40,7 +40,7 @@
     controlledButton.pref = extensionControlledPref;
     Polymer.dom.flush();
     assertTrue(controlledButton.$$('paper-button').disabled);
-    assertFalse(!!controlledButton.$$('cr-policy-pref-indicator'));
+    assertTrue(!!controlledButton.$$('cr-policy-pref-indicator'));
 
     controlledButton.pref = policyControlledPref;
     Polymer.dom.flush();
diff --git a/chromecast/browser/url_request_context_factory.cc b/chromecast/browser/url_request_context_factory.cc
index a7628f1..b6def5f 100644
--- a/chromecast/browser/url_request_context_factory.cc
+++ b/chromecast/browser/url_request_context_factory.cc
@@ -73,6 +73,11 @@
   }
 };
 
+bool IgnoreCertificateErrors() {
+  base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
+  return cmd_line->HasSwitch(switches::kIgnoreCertificateErrors);
+}
+
 }  // namespace
 
 // Private classes to expose URLRequestContextGetter that call back to the
@@ -336,7 +341,7 @@
   DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
   InitializeSystemContextDependencies();
   net::HttpNetworkSession::Params system_params;
-  PopulateNetworkSessionParams(false, &system_params);
+  PopulateNetworkSessionParams(IgnoreCertificateErrors(), &system_params);
   system_transaction_factory_.reset(new net::HttpNetworkLayer(
       new net::HttpNetworkSession(system_params)));
   system_job_factory_.reset(new net::URLRequestJobFactoryImpl());
@@ -392,13 +397,8 @@
   DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
   InitializeSystemContextDependencies();
 
-  bool ignore_certificate_errors = false;
-  base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
-  if (cmd_line->HasSwitch(switches::kIgnoreCertificateErrors)) {
-    ignore_certificate_errors = true;
-  }
   net::HttpNetworkSession::Params network_session_params;
-  PopulateNetworkSessionParams(ignore_certificate_errors,
+  PopulateNetworkSessionParams(IgnoreCertificateErrors(),
                                &network_session_params);
   InitializeMainContextDependencies(
       new net::HttpNetworkLayer(
diff --git a/chromecast/net/DEPS b/chromecast/net/DEPS
index cd66c1f..90e91a5 100644
--- a/chromecast/net/DEPS
+++ b/chromecast/net/DEPS
@@ -1,4 +1,4 @@
 include_rules = [
-  "+net",
   "+components/proxy_config",
+  "+net",
 ]
diff --git a/chromecast/net/connectivity_checker_impl.cc b/chromecast/net/connectivity_checker_impl.cc
index 6c1b234..17e7c5b 100644
--- a/chromecast/net/connectivity_checker_impl.cc
+++ b/chromecast/net/connectivity_checker_impl.cc
@@ -15,9 +15,11 @@
 #include "chromecast/chromecast_features.h"
 #include "chromecast/net/net_switches.h"
 #include "net/base/request_priority.h"
+#include "net/http/http_network_session.h"
 #include "net/http/http_response_headers.h"
 #include "net/http/http_response_info.h"
 #include "net/http/http_status_code.h"
+#include "net/http/http_transaction_factory.h"
 #include "net/socket/ssl_client_socket.h"
 #include "net/url_request/url_request_context.h"
 #include "net/url_request/url_request_context_builder.h"
@@ -212,6 +214,15 @@
     net::URLRequest* request,
     const net::SSLInfo& ssl_info,
     bool fatal) {
+  if (url_request_context_->http_transaction_factory()
+          ->GetSession()
+          ->params()
+          .ignore_certificate_errors) {
+    LOG(WARNING) << "OnSSLCertificateError: ignore cert_status="
+                 << ssl_info.cert_status;
+    request->ContinueDespiteLastError();
+    return;
+  }
   DCHECK(task_runner_->BelongsToCurrentThread());
   LOG(ERROR) << "OnSSLCertificateError: cert_status=" << ssl_info.cert_status;
   net::SSLClientSocket::ClearSessionCache();
diff --git a/chromecast/renderer/cast_content_renderer_client.cc b/chromecast/renderer/cast_content_renderer_client.cc
index 57089ad..2092aa1 100644
--- a/chromecast/renderer/cast_content_renderer_client.cc
+++ b/chromecast/renderer/cast_content_renderer_client.cc
@@ -26,6 +26,7 @@
 #include "services/service_manager/public/cpp/interface_provider.h"
 #include "third_party/WebKit/public/platform/WebColor.h"
 #include "third_party/WebKit/public/web/WebFrameWidget.h"
+#include "third_party/WebKit/public/web/WebRuntimeFeatures.h"
 #include "third_party/WebKit/public/web/WebSettings.h"
 #include "third_party/WebKit/public/web/WebView.h"
 
@@ -98,9 +99,6 @@
     blink::WebFrameWidget* web_frame_widget = render_view->GetWebFrameWidget();
     web_frame_widget->setBaseBackgroundColor(kColorBlack);
 
-    // Settings for ATV (Android defaults are not what we want):
-    webview->settings()->setMediaControlsOverlayPlayButtonEnabled(false);
-
     // Disable application cache as Chromecast doesn't support off-line
     // application running.
     webview->settings()->setOfflineWebApplicationCacheEnabled(false);
@@ -148,5 +146,11 @@
   return false;
 }
 
+void CastContentRendererClient::
+    SetRuntimeFeaturesDefaultsBeforeBlinkInitialization() {
+  // Settings for ATV (Android defaults are not what we want).
+  blink::WebRuntimeFeatures::enableMediaControlsOverlayPlayButton(false);
+}
+
 }  // namespace shell
 }  // namespace chromecast
diff --git a/chromecast/renderer/cast_content_renderer_client.h b/chromecast/renderer/cast_content_renderer_client.h
index ecc58a1..8f6aba4 100644
--- a/chromecast/renderer/cast_content_renderer_client.h
+++ b/chromecast/renderer/cast_content_renderer_client.h
@@ -43,6 +43,7 @@
                       bool render_frame_has_played_media_before,
                       const base::Closure& closure) override;
   bool AllowMediaSuspend() override;
+  void SetRuntimeFeaturesDefaultsBeforeBlinkInitialization() override;
 
  protected:
   CastContentRendererClient();
diff --git a/chromeos/components/tether/BUILD.gn b/chromeos/components/tether/BUILD.gn
index 031b805..3a14c145 100644
--- a/chromeos/components/tether/BUILD.gn
+++ b/chromeos/components/tether/BUILD.gn
@@ -24,6 +24,8 @@
     "host_scan_scheduler.h",
     "host_scanner.cc",
     "host_scanner.h",
+    "host_scanner_operation.cc",
+    "host_scanner_operation.h",
     "initializer.cc",
     "initializer.h",
     "local_device_data_provider.cc",
@@ -60,6 +62,8 @@
   sources = [
     "fake_ble_connection_manager.cc",
     "fake_ble_connection_manager.h",
+    "fake_tether_host_fetcher.cc",
+    "fake_tether_host_fetcher.h",
     "mock_local_device_data_provider.cc",
     "mock_local_device_data_provider.h",
   ]
@@ -86,6 +90,8 @@
     "connect_tethering_operation_unittest.cc",
     "host_scan_device_prioritizer_unittest.cc",
     "host_scan_scheduler_unittest.cc",
+    "host_scanner_operation_unittest.cc",
+    "host_scanner_unittest.cc",
     "local_device_data_provider_unittest.cc",
     "message_transfer_operation_unittest.cc",
     "message_wrapper_unittest.cc",
diff --git a/chromeos/components/tether/fake_tether_host_fetcher.cc b/chromeos/components/tether/fake_tether_host_fetcher.cc
new file mode 100644
index 0000000..79de8516
--- /dev/null
+++ b/chromeos/components/tether/fake_tether_host_fetcher.cc
@@ -0,0 +1,55 @@
+// 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 "chromeos/components/tether/fake_tether_host_fetcher.h"
+
+#include "base/memory/ptr_util.h"
+
+namespace chromeos {
+
+namespace tether {
+
+FakeTetherHostFetcher::FakeTetherHostFetcher(
+    std::vector<cryptauth::RemoteDevice> tether_hosts,
+    bool synchronously_reply_with_results)
+    : TetherHostFetcher("", "", nullptr, nullptr),
+      tether_hosts_(tether_hosts),
+      synchronously_reply_with_results_(synchronously_reply_with_results) {}
+
+FakeTetherHostFetcher::FakeTetherHostFetcher(
+    bool synchronously_reply_with_results)
+    : FakeTetherHostFetcher(std::vector<cryptauth::RemoteDevice>(),
+                            synchronously_reply_with_results) {}
+
+FakeTetherHostFetcher::~FakeTetherHostFetcher() {}
+
+void FakeTetherHostFetcher::SetTetherHosts(
+    const std::vector<cryptauth::RemoteDevice> tether_hosts) {
+  tether_hosts_ = tether_hosts;
+}
+
+void FakeTetherHostFetcher::InvokePendingCallbacks() {
+  OnRemoteDevicesLoaded(tether_hosts_);
+}
+
+void FakeTetherHostFetcher::FetchAllTetherHosts(
+    const TetherHostFetcher::TetherHostListCallback& callback) {
+  requests_.push_back(TetherHostFetchRequest(callback));
+  if (synchronously_reply_with_results_) {
+    InvokePendingCallbacks();
+  }
+}
+
+void FakeTetherHostFetcher::FetchTetherHost(
+    const std::string& device_id,
+    const TetherHostFetcher::TetherHostCallback& callback) {
+  requests_.push_back(TetherHostFetchRequest(device_id, callback));
+  if (synchronously_reply_with_results_) {
+    InvokePendingCallbacks();
+  }
+}
+
+}  // namespace tether
+
+}  // namespace chromeos
diff --git a/chromeos/components/tether/fake_tether_host_fetcher.h b/chromeos/components/tether/fake_tether_host_fetcher.h
new file mode 100644
index 0000000..a75c9905
--- /dev/null
+++ b/chromeos/components/tether/fake_tether_host_fetcher.h
@@ -0,0 +1,50 @@
+// Copyright 2017 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 CHROMEOS_COMPONENTS_TETHER_FAKE_TETHER_HOST_FETCHER_H_
+#define CHROMEOS_COMPONENTS_TETHER_FAKE_TETHER_HOST_FETCHER_H_
+
+#include <vector>
+
+#include "base/macros.h"
+#include "chromeos/components/tether/tether_host_fetcher.h"
+#include "components/cryptauth/remote_device.h"
+
+namespace chromeos {
+
+namespace tether {
+
+// Test double for TetherHostFetcher.
+class FakeTetherHostFetcher : public TetherHostFetcher {
+ public:
+  FakeTetherHostFetcher(std::vector<cryptauth::RemoteDevice> tether_hosts,
+                        bool synchronously_reply_with_results);
+  FakeTetherHostFetcher(bool synchronously_reply_with_results);
+  ~FakeTetherHostFetcher() override;
+
+  void SetTetherHosts(const std::vector<cryptauth::RemoteDevice> tether_hosts);
+
+  // If |sychronously_reply_with_results| is false, calling this method will
+  // actually invoke the callbacks.
+  void InvokePendingCallbacks();
+
+  // TetherHostFetcher:
+  void FetchAllTetherHosts(
+      const TetherHostFetcher::TetherHostListCallback& callback) override;
+  void FetchTetherHost(
+      const std::string& device_id,
+      const TetherHostFetcher::TetherHostCallback& callback) override;
+
+ private:
+  std::vector<cryptauth::RemoteDevice> tether_hosts_;
+  bool synchronously_reply_with_results_;
+
+  DISALLOW_COPY_AND_ASSIGN(FakeTetherHostFetcher);
+};
+
+}  // namespace tether
+
+}  // namespace chromeos
+
+#endif  // CHROMEOS_COMPONENTS_TETHER_FAKE_TETHER_HOST_FETCHER_H_
diff --git a/chromeos/components/tether/host_scan_device_prioritizer.h b/chromeos/components/tether/host_scan_device_prioritizer.h
index 0c89f33e..9457446 100644
--- a/chromeos/components/tether/host_scan_device_prioritizer.h
+++ b/chromeos/components/tether/host_scan_device_prioritizer.h
@@ -28,7 +28,7 @@
   // Note: The PrefService* passed here must be created using the same registry
   // passed to RegisterPrefs().
   HostScanDevicePrioritizer(PrefService* pref_service);
-  ~HostScanDevicePrioritizer();
+  virtual ~HostScanDevicePrioritizer();
 
   // Registers the prefs used by this class to |registry|. Must be called before
   // this class is utilized.
@@ -46,7 +46,7 @@
       const cryptauth::RemoteDevice& remote_device);
 
   // Prioritizes |remote_devices| using the rules described above.
-  void SortByHostScanOrder(
+  virtual void SortByHostScanOrder(
       std::vector<cryptauth::RemoteDevice>* remote_devices) const;
 
  private:
diff --git a/chromeos/components/tether/host_scan_scheduler_unittest.cc b/chromeos/components/tether/host_scan_scheduler_unittest.cc
index 7a39a27..142149e 100644
--- a/chromeos/components/tether/host_scan_scheduler_unittest.cc
+++ b/chromeos/components/tether/host_scan_scheduler_unittest.cc
@@ -81,7 +81,8 @@
 
   class FakeHostScanner : public HostScanner {
    public:
-    FakeHostScanner() : num_scans_started_(0) {}
+    FakeHostScanner()
+        : HostScanner(nullptr, nullptr, nullptr), num_scans_started_(0) {}
     ~FakeHostScanner() override {}
 
     void StartScan() override { num_scans_started_++; }
diff --git a/chromeos/components/tether/host_scanner.cc b/chromeos/components/tether/host_scanner.cc
index 27ccfa91..7296d847 100644
--- a/chromeos/components/tether/host_scanner.cc
+++ b/chromeos/components/tether/host_scanner.cc
@@ -4,15 +4,71 @@
 
 #include "chromeos/components/tether/host_scanner.h"
 
+#include "base/bind.h"
+#include "chromeos/components/tether/tether_host_fetcher.h"
+#include "components/cryptauth/remote_device_loader.h"
+
 namespace chromeos {
 
 namespace tether {
 
-HostScanner::HostScanner() {}
+HostScanner::HostScanner(
+    TetherHostFetcher* tether_host_fetcher,
+    BleConnectionManager* connection_manager,
+    HostScanDevicePrioritizer* host_scan_device_prioritizer)
+    : tether_host_fetcher_(tether_host_fetcher),
+      connection_manager_(connection_manager),
+      host_scan_device_prioritizer_(host_scan_device_prioritizer),
+      is_fetching_hosts_(false),
+      weak_ptr_factory_(this) {}
 
 HostScanner::~HostScanner() {}
 
-void HostScanner::StartScan() {}
+void HostScanner::StartScan() {
+  if (host_scanner_operation_) {
+    // If a scan is already active, do not continue.
+    return;
+  }
+
+  if (is_fetching_hosts_) {
+    // If fetching tether hosts is active, stop and wait for them to load.
+    return;
+  }
+  is_fetching_hosts_ = true;
+
+  tether_host_fetcher_->FetchAllTetherHosts(base::Bind(
+      &HostScanner::OnTetherHostsFetched, weak_ptr_factory_.GetWeakPtr()));
+}
+
+bool HostScanner::IsScanActive() {
+  return is_fetching_hosts_ || host_scanner_operation_;
+}
+
+void HostScanner::OnTetherHostsFetched(
+    const cryptauth::RemoteDeviceList& tether_hosts) {
+  is_fetching_hosts_ = false;
+
+  host_scanner_operation_ = HostScannerOperation::Factory::NewInstance(
+      tether_hosts, connection_manager_, host_scan_device_prioritizer_);
+  host_scanner_operation_->AddObserver(this);
+  host_scanner_operation_->Initialize();
+}
+
+void HostScanner::OnTetherAvailabilityResponse(
+    std::vector<HostScannerOperation::ScannedDeviceInfo>&
+        scanned_device_list_so_far,
+    bool is_final_scan_result) {
+  most_recent_scan_results_ = scanned_device_list_so_far;
+
+  // TODO(hansberry): Hook up to networking code.
+
+  if (is_final_scan_result) {
+    // If the final scan result has been received, the operation is finished.
+    // Delete it.
+    host_scanner_operation_->RemoveObserver(this);
+    host_scanner_operation_.reset();
+  }
+}
 
 }  // namespace tether
 
diff --git a/chromeos/components/tether/host_scanner.h b/chromeos/components/tether/host_scanner.h
index 18f4e25..c21a1964 100644
--- a/chromeos/components/tether/host_scanner.h
+++ b/chromeos/components/tether/host_scanner.h
@@ -5,18 +5,66 @@
 #ifndef CHROMEOS_COMPONENTS_TETHER_HOST_SCANNER_H
 #define CHROMEOS_COMPONENTS_TETHER_HOST_SCANNER_H
 
+#include <vector>
+
+#include "base/memory/weak_ptr.h"
+#include "chromeos/components/tether/host_scanner_operation.h"
+#include "components/cryptauth/remote_device.h"
+
 namespace chromeos {
 
 namespace tether {
 
+class BleConnectionManager;
+class HostScanDevicePrioritizer;
+class TetherHostFetcher;
+
 // Scans for nearby tether hosts.
-// TODO(khorimoto): Implement.
-class HostScanner {
+// TODO(khorimoto): Add some sort of "staleness" timeout which removes scan
+//                  results which occurred long enough ago that they are no
+//                  longer valid.
+// TODO(hansberry): Implement handling for scan results.
+class HostScanner : public HostScannerOperation::Observer {
  public:
-  HostScanner();
+  HostScanner(TetherHostFetcher* tether_host_fetcher,
+              BleConnectionManager* connection_manager,
+              HostScanDevicePrioritizer* host_scan_device_prioritizer);
   virtual ~HostScanner();
 
+  // Starts a host scan if there is no current scan. If a scan is ongoing, this
+  // function is a no-op.
   virtual void StartScan();
+
+  bool IsScanActive();
+
+  std::vector<HostScannerOperation::ScannedDeviceInfo>
+  most_recent_scan_results() {
+    return most_recent_scan_results_;
+  }
+
+  // HostScannerOperation::Observer:
+  void OnTetherAvailabilityResponse(
+      std::vector<HostScannerOperation::ScannedDeviceInfo>&
+          scanned_device_list_so_far,
+      bool is_final_scan_result) override;
+
+ private:
+  friend class HostScannerTest;
+
+  void OnTetherHostsFetched(const cryptauth::RemoteDeviceList& tether_hosts);
+
+  TetherHostFetcher* tether_host_fetcher_;
+  BleConnectionManager* connection_manager_;
+  HostScanDevicePrioritizer* host_scan_device_prioritizer_;
+
+  bool is_fetching_hosts_;
+  std::unique_ptr<HostScannerOperation> host_scanner_operation_;
+  std::vector<HostScannerOperation::ScannedDeviceInfo>
+      most_recent_scan_results_;
+
+  base::WeakPtrFactory<HostScanner> weak_ptr_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(HostScanner);
 };
 
 }  // namespace tether
diff --git a/chromeos/components/tether/host_scanner_operation.cc b/chromeos/components/tether/host_scanner_operation.cc
new file mode 100644
index 0000000..fa19e0a
--- /dev/null
+++ b/chromeos/components/tether/host_scanner_operation.cc
@@ -0,0 +1,195 @@
+// Copyright 2017 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 "chromeos/components/tether/host_scanner_operation.h"
+
+#include "chromeos/components/tether/host_scan_device_prioritizer.h"
+#include "chromeos/components/tether/message_wrapper.h"
+#include "chromeos/components/tether/proto/tether.pb.h"
+#include "components/proximity_auth/logging/logging.h"
+
+namespace chromeos {
+
+namespace tether {
+
+namespace {
+
+std::vector<cryptauth::RemoteDevice> PrioritizeDevices(
+    const std::vector<cryptauth::RemoteDevice>& devices_to_connect,
+    HostScanDevicePrioritizer* host_scan_device_prioritizer) {
+  std::vector<cryptauth::RemoteDevice> mutable_devices_to_connect =
+      devices_to_connect;
+  host_scan_device_prioritizer->SortByHostScanOrder(
+      &mutable_devices_to_connect);
+  return mutable_devices_to_connect;
+}
+
+bool IsTetheringAvailableWithValidDeviceStatus(
+    const TetherAvailabilityResponse* response) {
+  if (!response) {
+    return false;
+  }
+
+  if (!response->has_device_status()) {
+    return false;
+  }
+
+  if (!response->has_response_code()) {
+    return false;
+  }
+
+  const TetherAvailabilityResponse_ResponseCode response_code =
+      response->response_code();
+  if (response_code ==
+          TetherAvailabilityResponse_ResponseCode::
+              TetherAvailabilityResponse_ResponseCode_SETUP_NEEDED ||
+      response_code ==
+          TetherAvailabilityResponse_ResponseCode::
+              TetherAvailabilityResponse_ResponseCode_TETHER_AVAILABLE) {
+    return true;
+  }
+
+  return false;
+}
+
+}  // namespace
+
+// static
+HostScannerOperation::Factory*
+    HostScannerOperation::Factory::factory_instance_ = nullptr;
+
+// static
+std::unique_ptr<HostScannerOperation>
+HostScannerOperation::Factory::NewInstance(
+    const std::vector<cryptauth::RemoteDevice>& devices_to_connect,
+    BleConnectionManager* connection_manager,
+    HostScanDevicePrioritizer* host_scan_device_prioritizer) {
+  if (!factory_instance_) {
+    factory_instance_ = new Factory();
+  }
+  return factory_instance_->BuildInstance(
+      devices_to_connect, connection_manager, host_scan_device_prioritizer);
+}
+
+// static
+void HostScannerOperation::Factory::SetInstanceForTesting(Factory* factory) {
+  factory_instance_ = factory;
+}
+
+std::unique_ptr<HostScannerOperation>
+HostScannerOperation::Factory::BuildInstance(
+    const std::vector<cryptauth::RemoteDevice>& devices_to_connect,
+    BleConnectionManager* connection_manager,
+    HostScanDevicePrioritizer* host_scan_device_prioritizer) {
+  return base::MakeUnique<HostScannerOperation>(
+      devices_to_connect, connection_manager, host_scan_device_prioritizer);
+}
+
+HostScannerOperation::ScannedDeviceInfo::ScannedDeviceInfo(
+    const cryptauth::RemoteDevice& remote_device,
+    const DeviceStatus& device_status,
+    bool set_up_required)
+    : remote_device(remote_device),
+      device_status(device_status),
+      set_up_required(set_up_required) {}
+
+HostScannerOperation::ScannedDeviceInfo::~ScannedDeviceInfo() {}
+
+bool operator==(const HostScannerOperation::ScannedDeviceInfo& first,
+                const HostScannerOperation::ScannedDeviceInfo& second) {
+  return first.remote_device == second.remote_device &&
+         first.device_status.SerializeAsString() ==
+             second.device_status.SerializeAsString() &&
+         first.set_up_required == second.set_up_required;
+}
+
+HostScannerOperation::HostScannerOperation(
+    const std::vector<cryptauth::RemoteDevice>& devices_to_connect,
+    BleConnectionManager* connection_manager,
+    HostScanDevicePrioritizer* host_scan_device_prioritizer)
+    : MessageTransferOperation(
+          PrioritizeDevices(devices_to_connect, host_scan_device_prioritizer),
+          connection_manager) {}
+
+HostScannerOperation::~HostScannerOperation() {}
+
+void HostScannerOperation::AddObserver(Observer* observer) {
+  observer_list_.AddObserver(observer);
+}
+
+void HostScannerOperation::RemoveObserver(Observer* observer) {
+  observer_list_.RemoveObserver(observer);
+}
+
+void HostScannerOperation::NotifyObserversOfScannedDeviceList(
+    bool is_final_scan_result) {
+  for (auto& observer : observer_list_) {
+    observer.OnTetherAvailabilityResponse(scanned_device_list_so_far_,
+                                          is_final_scan_result);
+  }
+}
+
+void HostScannerOperation::OnDeviceAuthenticated(
+    const cryptauth::RemoteDevice& remote_device) {
+  SendMessageToDevice(remote_device, base::MakeUnique<MessageWrapper>(
+                                         TetherAvailabilityRequest()));
+}
+
+void HostScannerOperation::OnMessageReceived(
+    std::unique_ptr<MessageWrapper> message_wrapper,
+    const cryptauth::RemoteDevice& remote_device) {
+  if (message_wrapper->GetMessageType() !=
+      MessageType::TETHER_AVAILABILITY_RESPONSE) {
+    // If another type of message has been received, ignore it.
+    return;
+  }
+
+  TetherAvailabilityResponse* response =
+      static_cast<TetherAvailabilityResponse*>(
+          message_wrapper->GetProto().get());
+  if (!IsTetheringAvailableWithValidDeviceStatus(response)) {
+    // If the received message is invalid or if it states that tethering is
+    // unavailable, ignore it.
+    PA_LOG(INFO) << "Received TetherAvailabilityResponse from device with ID "
+                 << remote_device.GetTruncatedDeviceIdForLogs() << " which "
+                 << "indicates that tethering is not available.";
+  } else {
+    bool set_up_required =
+        response->response_code() ==
+        TetherAvailabilityResponse_ResponseCode::
+            TetherAvailabilityResponse_ResponseCode_SETUP_NEEDED;
+
+    PA_LOG(INFO) << "Received TetherAvailabilityResponse from device with ID "
+                 << remote_device.GetTruncatedDeviceIdForLogs() << " which "
+                 << "indicates that tethering is available. set_up_required = "
+                 << set_up_required;
+
+    scanned_device_list_so_far_.push_back(ScannedDeviceInfo(
+        remote_device, response->device_status(), set_up_required));
+    NotifyObserversOfScannedDeviceList(false /* is_final_scan_result */);
+  }
+
+  // Unregister the device after a TetherAvailabilityResponse has been received.
+  UnregisterDevice(remote_device);
+}
+
+void HostScannerOperation::OnOperationStarted() {
+  DCHECK(scanned_device_list_so_far_.empty());
+
+  // Send out an empty device list scan to let observers know that the operation
+  // has begun.
+  NotifyObserversOfScannedDeviceList(false /* is_final_scan_result */);
+}
+
+void HostScannerOperation::OnOperationFinished() {
+  NotifyObserversOfScannedDeviceList(true /* is_final_scan_result */);
+}
+
+MessageType HostScannerOperation::GetMessageTypeForConnection() {
+  return MessageType::TETHER_AVAILABILITY_REQUEST;
+}
+
+}  // namespace tether
+
+}  // namespace chromeos
diff --git a/chromeos/components/tether/host_scanner_operation.h b/chromeos/components/tether/host_scanner_operation.h
new file mode 100644
index 0000000..bc774c5
--- /dev/null
+++ b/chromeos/components/tether/host_scanner_operation.h
@@ -0,0 +1,112 @@
+// Copyright 2017 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 CHROMEOS_COMPONENTS_TETHER_HOST_SCANNER_OPERATION_H_
+#define CHROMEOS_COMPONENTS_TETHER_HOST_SCANNER_OPERATION_H_
+
+#include <map>
+#include <vector>
+
+#include "base/macros.h"
+#include "base/observer_list.h"
+#include "chromeos/components/tether/ble_connection_manager.h"
+#include "chromeos/components/tether/message_transfer_operation.h"
+#include "components/cryptauth/remote_device.h"
+
+namespace chromeos {
+
+namespace tether {
+
+class HostScanDevicePrioritizer;
+class MessageWrapper;
+
+// Operation used to perform a host scan. Attempts to connect to each of the
+// devices passed and sends a TetherAvailabilityRequest to each connected device
+// once an authenticated channel has been established; once a response has been
+// received, HostScannerOperation alerts observers of devices which can provide
+// a tethering connection.
+// TODO(khorimoto): Add a timeout which gives up if no response is received in
+// a reasonable amount of time.
+class HostScannerOperation : public MessageTransferOperation {
+ public:
+  class Factory {
+   public:
+    static std::unique_ptr<HostScannerOperation> NewInstance(
+        const std::vector<cryptauth::RemoteDevice>& devices_to_connect,
+        BleConnectionManager* connection_manager,
+        HostScanDevicePrioritizer* host_scan_device_prioritizer);
+
+    static void SetInstanceForTesting(Factory* factory);
+
+   protected:
+    virtual std::unique_ptr<HostScannerOperation> BuildInstance(
+        const std::vector<cryptauth::RemoteDevice>& devices_to_connect,
+        BleConnectionManager* connection_manager,
+        HostScanDevicePrioritizer* host_scan_device_prioritizer);
+
+   private:
+    static Factory* factory_instance_;
+  };
+
+  struct ScannedDeviceInfo {
+    ScannedDeviceInfo(const cryptauth::RemoteDevice& remote_device,
+                      const DeviceStatus& device_status,
+                      bool set_up_required);
+    ~ScannedDeviceInfo();
+
+    friend bool operator==(const ScannedDeviceInfo& first,
+                           const ScannedDeviceInfo& second);
+
+    cryptauth::RemoteDevice remote_device;
+    DeviceStatus device_status;
+    bool set_up_required;
+  };
+
+  class Observer {
+   public:
+    // Invoked once with an empty list when the operation begins, then invoked
+    // repeatedly once each result comes in. After all devices have been
+    // processed, the callback is invoked one final time with
+    // |is_final_scan_result| = true.
+    virtual void OnTetherAvailabilityResponse(
+        std::vector<ScannedDeviceInfo>& scanned_device_list_so_far,
+        bool is_final_scan_result) = 0;
+  };
+
+  HostScannerOperation(
+      const std::vector<cryptauth::RemoteDevice>& devices_to_connect,
+      BleConnectionManager* connection_manager,
+      HostScanDevicePrioritizer* host_scan_device_prioritizer);
+  ~HostScannerOperation() override;
+
+  void AddObserver(Observer* observer);
+  void RemoveObserver(Observer* observer);
+
+ protected:
+  void NotifyObserversOfScannedDeviceList(bool is_final_scan_result);
+
+  // MessageTransferOperation:
+  void OnDeviceAuthenticated(
+      const cryptauth::RemoteDevice& remote_device) override;
+  void OnMessageReceived(std::unique_ptr<MessageWrapper> message_wrapper,
+                         const cryptauth::RemoteDevice& remote_device) override;
+  void OnOperationStarted() override;
+  void OnOperationFinished() override;
+  MessageType GetMessageTypeForConnection() override;
+
+  std::vector<ScannedDeviceInfo> scanned_device_list_so_far_;
+
+ private:
+  friend class HostScannerOperationTest;
+
+  base::ObserverList<Observer> observer_list_;
+
+  DISALLOW_COPY_AND_ASSIGN(HostScannerOperation);
+};
+
+}  // namespace tether
+
+}  // namespace chromeos
+
+#endif  // CHROMEOS_COMPONENTS_TETHER_HOST_SCANNER_OPERATION_H_
diff --git a/chromeos/components/tether/host_scanner_operation_unittest.cc b/chromeos/components/tether/host_scanner_operation_unittest.cc
new file mode 100644
index 0000000..918c9c22
--- /dev/null
+++ b/chromeos/components/tether/host_scanner_operation_unittest.cc
@@ -0,0 +1,325 @@
+// 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 "chromeos/components/tether/host_scanner_operation.h"
+
+#include <algorithm>
+#include <memory>
+#include <vector>
+
+#include "base/logging.h"
+#include "chromeos/components/tether/ble_constants.h"
+#include "chromeos/components/tether/fake_ble_connection_manager.h"
+#include "chromeos/components/tether/host_scan_device_prioritizer.h"
+#include "chromeos/components/tether/message_wrapper.h"
+#include "chromeos/components/tether/proto/tether.pb.h"
+#include "components/cryptauth/remote_device_test_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace chromeos {
+
+namespace tether {
+
+namespace {
+
+const char kDefaultCarrier[] = "Google Fi";
+
+class FakeHostScanDevicePrioritizer : public HostScanDevicePrioritizer {
+ public:
+  FakeHostScanDevicePrioritizer() : HostScanDevicePrioritizer(nullptr) {}
+  ~FakeHostScanDevicePrioritizer() override {}
+
+  // Simply reverses the device order.
+  void SortByHostScanOrder(
+      std::vector<cryptauth::RemoteDevice>* remote_devices) const override {
+    for (size_t i = 0; i < remote_devices->size() / 2; ++i) {
+      std::iter_swap(remote_devices->begin() + i,
+                     remote_devices->end() - i - 1);
+    }
+  }
+
+  void VerifyHasBeenPrioritized(
+      const std::vector<cryptauth::RemoteDevice>& original,
+      const std::vector<cryptauth::RemoteDevice>& prioritized) {
+    std::vector<cryptauth::RemoteDevice> copy_of_original = original;
+    SortByHostScanOrder(&copy_of_original);
+    EXPECT_EQ(copy_of_original, prioritized);
+  }
+};
+
+class TestObserver : public HostScannerOperation::Observer {
+ public:
+  TestObserver()
+      : has_received_update(false), has_final_scan_result_been_sent(false) {}
+
+  void OnTetherAvailabilityResponse(
+      std::vector<HostScannerOperation::ScannedDeviceInfo>&
+          scanned_device_list_so_far,
+      bool is_final_scan_result) override {
+    has_received_update = true;
+    scanned_devices_so_far = scanned_device_list_so_far;
+    has_final_scan_result_been_sent = is_final_scan_result;
+  }
+
+  bool has_received_update;
+  std::vector<HostScannerOperation::ScannedDeviceInfo> scanned_devices_so_far;
+  bool has_final_scan_result_been_sent;
+};
+
+std::string CreateTetherAvailabilityRequestString() {
+  TetherAvailabilityRequest request;
+  return MessageWrapper(request).ToRawMessage();
+}
+
+DeviceStatus CreateFakeDeviceStatus(std::string cell_provider_name) {
+  WifiStatus wifi_status;
+  wifi_status.set_status_code(
+      WifiStatus_StatusCode::WifiStatus_StatusCode_CONNECTED);
+  wifi_status.set_ssid("Google A");
+
+  DeviceStatus device_status;
+  device_status.set_battery_percentage(75);
+  device_status.set_cell_provider(cell_provider_name);
+  device_status.set_connection_strength(4);
+  device_status.mutable_wifi_status()->CopyFrom(wifi_status);
+
+  return device_status;
+}
+
+std::string CreateTetherAvailabilityResponseString(
+    TetherAvailabilityResponse_ResponseCode response_code,
+    const std::string& cell_provider_name) {
+  TetherAvailabilityResponse response;
+  response.set_response_code(response_code);
+  response.mutable_device_status()->CopyFrom(
+      CreateFakeDeviceStatus(cell_provider_name));
+  return MessageWrapper(response).ToRawMessage();
+}
+
+}  // namespace
+
+class HostScannerOperationTest : public testing::Test {
+ protected:
+  HostScannerOperationTest()
+      : tether_availability_request_string_(
+            CreateTetherAvailabilityRequestString()),
+        test_devices_(cryptauth::GenerateTestRemoteDevices(5)) {
+    // These tests are written under the assumption that there are a maximum of
+    // 3 connection attempts; they need to be edited if this value changes.
+    EXPECT_EQ(3u, MessageTransferOperation::kMaxConnectionAttemptsPerDevice);
+  }
+
+  void SetUp() override {
+    fake_ble_connection_manager_ = base::MakeUnique<FakeBleConnectionManager>();
+    fake_host_scan_device_prioritizer_ =
+        base::MakeUnique<FakeHostScanDevicePrioritizer>();
+    test_observer_ = base::WrapUnique(new TestObserver());
+  }
+
+  void ConstructOperation(
+      const std::vector<cryptauth::RemoteDevice>& remote_devices) {
+    operation_ = base::WrapUnique(new HostScannerOperation(
+        remote_devices, fake_ble_connection_manager_.get(),
+        fake_host_scan_device_prioritizer_.get()));
+    operation_->AddObserver(test_observer_.get());
+
+    // Verify that the devices have been correctly prioritized.
+    fake_host_scan_device_prioritizer_->VerifyHasBeenPrioritized(
+        remote_devices, operation_->remote_devices());
+
+    EXPECT_FALSE(test_observer_->has_received_update);
+    operation_->Initialize();
+    EXPECT_TRUE(test_observer_->has_received_update);
+    EXPECT_TRUE(test_observer_->scanned_devices_so_far.empty());
+    EXPECT_FALSE(test_observer_->has_final_scan_result_been_sent);
+  }
+
+  void SimulateDeviceAuthenticationAndVerifyMessageSent(
+      const cryptauth::RemoteDevice& remote_device,
+      size_t expected_num_messages_sent) {
+    // Verify that before the authentication, one fewer than the expected number
+    // of messages has been sent.
+    EXPECT_EQ(expected_num_messages_sent - 1,
+              fake_ble_connection_manager_->sent_messages().size());
+
+    operation_->OnDeviceAuthenticated(remote_device);
+
+    // Now, verify that the message was sent successfully.
+    std::vector<FakeBleConnectionManager::SentMessage>& sent_messages =
+        fake_ble_connection_manager_->sent_messages();
+    ASSERT_EQ(expected_num_messages_sent, sent_messages.size());
+    EXPECT_EQ(remote_device,
+              sent_messages[expected_num_messages_sent - 1].remote_device);
+    EXPECT_EQ(tether_availability_request_string_,
+              sent_messages[expected_num_messages_sent - 1].message);
+  }
+
+  void SimulateResponseReceivedAndVerifyObserverCallbackInvoked(
+      const cryptauth::RemoteDevice& remote_device,
+      TetherAvailabilityResponse_ResponseCode response_code,
+      const std::string& cell_provider_name,
+      bool expected_to_be_last_scan_result) {
+    size_t num_scanned_device_results_so_far =
+        test_observer_->scanned_devices_so_far.size();
+
+    fake_ble_connection_manager_->ReceiveMessage(
+        remote_device, CreateTetherAvailabilityResponseString(
+                           response_code, cell_provider_name));
+
+    bool tether_available =
+        response_code ==
+        TetherAvailabilityResponse_ResponseCode::
+            TetherAvailabilityResponse_ResponseCode_TETHER_AVAILABLE;
+    bool set_up_required =
+        response_code ==
+        TetherAvailabilityResponse_ResponseCode::
+            TetherAvailabilityResponse_ResponseCode_SETUP_NEEDED;
+    if (tether_available || set_up_required) {
+      // If tether is available or set up is needed, the observer callback
+      // should be invoked with an updated list.
+      EXPECT_EQ(num_scanned_device_results_so_far + 1,
+                test_observer_->scanned_devices_so_far.size());
+
+      HostScannerOperation::ScannedDeviceInfo last_received_info =
+          test_observer_->scanned_devices_so_far
+              [test_observer_->scanned_devices_so_far.size() - 1];
+      EXPECT_EQ(cell_provider_name,
+                last_received_info.device_status.cell_provider());
+      EXPECT_EQ(set_up_required, last_received_info.set_up_required);
+    }
+
+    EXPECT_EQ(expected_to_be_last_scan_result,
+              test_observer_->has_final_scan_result_been_sent);
+  }
+
+  void TestOperationWithOneDevice(
+      TetherAvailabilityResponse_ResponseCode response_code) {
+    ConstructOperation(std::vector<cryptauth::RemoteDevice>{test_devices_[0]});
+    SimulateDeviceAuthenticationAndVerifyMessageSent(test_devices_[0], 1u);
+    SimulateResponseReceivedAndVerifyObserverCallbackInvoked(
+        test_devices_[0], response_code, std::string(kDefaultCarrier), true);
+  }
+
+  const std::string tether_availability_request_string_;
+  const std::vector<cryptauth::RemoteDevice> test_devices_;
+
+  std::unique_ptr<FakeBleConnectionManager> fake_ble_connection_manager_;
+  std::unique_ptr<FakeHostScanDevicePrioritizer>
+      fake_host_scan_device_prioritizer_;
+  std::unique_ptr<TestObserver> test_observer_;
+  std::unique_ptr<HostScannerOperation> operation_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(HostScannerOperationTest);
+};
+
+TEST_F(HostScannerOperationTest, TestDevicesArePrioritizedDuringConstruction) {
+  // Verification of device order prioritization occurs in ConstructOperation().
+  ConstructOperation(test_devices_);
+}
+
+TEST_F(HostScannerOperationTest, TestOperation_OneDevice_UnknownError) {
+  TestOperationWithOneDevice(
+      TetherAvailabilityResponse_ResponseCode ::
+          TetherAvailabilityResponse_ResponseCode_UNKNOWN_ERROR);
+}
+
+TEST_F(HostScannerOperationTest, TestOperation_OneDevice_TetherAvailable) {
+  TestOperationWithOneDevice(
+      TetherAvailabilityResponse_ResponseCode ::
+          TetherAvailabilityResponse_ResponseCode_TETHER_AVAILABLE);
+}
+
+TEST_F(HostScannerOperationTest, TestOperation_OneDevice_SetupNeeded) {
+  TestOperationWithOneDevice(
+      TetherAvailabilityResponse_ResponseCode ::
+          TetherAvailabilityResponse_ResponseCode_SETUP_NEEDED);
+}
+
+TEST_F(HostScannerOperationTest, TestOperation_OneDevice_NoReception) {
+  TestOperationWithOneDevice(
+      TetherAvailabilityResponse_ResponseCode ::
+          TetherAvailabilityResponse_ResponseCode_NO_RECEPTION);
+}
+
+TEST_F(HostScannerOperationTest, TestOperation_OneDevice_NoSimCard) {
+  TestOperationWithOneDevice(
+      TetherAvailabilityResponse_ResponseCode ::
+          TetherAvailabilityResponse_ResponseCode_NO_SIM_CARD);
+}
+
+TEST_F(HostScannerOperationTest, TestMultipleDevices) {
+  ConstructOperation(test_devices_);
+
+  // Simulate devices 0 and 2 authenticating successfully. Use different carrier
+  // names to ensure that the DeviceStatus is being stored correctly.
+  SimulateDeviceAuthenticationAndVerifyMessageSent(test_devices_[0], 1u);
+  SimulateResponseReceivedAndVerifyObserverCallbackInvoked(
+      test_devices_[0],
+      TetherAvailabilityResponse_ResponseCode ::
+          TetherAvailabilityResponse_ResponseCode_TETHER_AVAILABLE,
+      "firstCarrierName", false /* expected_to_be_last_scan_result */);
+
+  SimulateDeviceAuthenticationAndVerifyMessageSent(test_devices_[2], 2u);
+  SimulateResponseReceivedAndVerifyObserverCallbackInvoked(
+      test_devices_[2],
+      TetherAvailabilityResponse_ResponseCode ::
+          TetherAvailabilityResponse_ResponseCode_TETHER_AVAILABLE,
+      "secondCarrierName", false /* expected_to_be_last_scan_result */);
+
+  // Simulate device 1 failing to connect.
+  fake_ble_connection_manager_->SetDeviceStatus(
+      test_devices_[1], cryptauth::SecureChannel::Status::CONNECTING);
+  fake_ble_connection_manager_->SetDeviceStatus(
+      test_devices_[1], cryptauth::SecureChannel::Status::DISCONNECTED);
+  fake_ble_connection_manager_->SetDeviceStatus(
+      test_devices_[1], cryptauth::SecureChannel::Status::CONNECTING);
+  fake_ble_connection_manager_->SetDeviceStatus(
+      test_devices_[1], cryptauth::SecureChannel::Status::DISCONNECTED);
+  fake_ble_connection_manager_->SetDeviceStatus(
+      test_devices_[1], cryptauth::SecureChannel::Status::CONNECTING);
+  fake_ble_connection_manager_->SetDeviceStatus(
+      test_devices_[1], cryptauth::SecureChannel::Status::DISCONNECTED);
+
+  // The scan should still not be over, and no new scan results should have
+  // come in.
+  EXPECT_FALSE(test_observer_->has_final_scan_result_been_sent);
+  EXPECT_EQ(2u, test_observer_->scanned_devices_so_far.size());
+
+  // Simulate device 3 failing to connect.
+  fake_ble_connection_manager_->SetDeviceStatus(
+      test_devices_[3], cryptauth::SecureChannel::Status::CONNECTING);
+  fake_ble_connection_manager_->SetDeviceStatus(
+      test_devices_[3], cryptauth::SecureChannel::Status::DISCONNECTED);
+  fake_ble_connection_manager_->SetDeviceStatus(
+      test_devices_[3], cryptauth::SecureChannel::Status::CONNECTING);
+  fake_ble_connection_manager_->SetDeviceStatus(
+      test_devices_[3], cryptauth::SecureChannel::Status::DISCONNECTED);
+  fake_ble_connection_manager_->SetDeviceStatus(
+      test_devices_[3], cryptauth::SecureChannel::Status::CONNECTING);
+  fake_ble_connection_manager_->SetDeviceStatus(
+      test_devices_[3], cryptauth::SecureChannel::Status::DISCONNECTED);
+
+  // The scan should still not be over, and no new scan results should have
+  // come in.
+  EXPECT_FALSE(test_observer_->has_final_scan_result_been_sent);
+  EXPECT_EQ(2u, test_observer_->scanned_devices_so_far.size());
+
+  // Simulate device 4 connecting successfully but responding with a code
+  // indicating that reception is not available.
+  SimulateDeviceAuthenticationAndVerifyMessageSent(test_devices_[4], 3u);
+  SimulateResponseReceivedAndVerifyObserverCallbackInvoked(
+      test_devices_[4],
+      TetherAvailabilityResponse_ResponseCode ::
+          TetherAvailabilityResponse_ResponseCode_NO_RECEPTION,
+      "noService", true /* expected_to_be_last_scan_result */);
+
+  // The scan should be over, and still no new scan results should have come in.
+  EXPECT_TRUE(test_observer_->has_final_scan_result_been_sent);
+  EXPECT_EQ(2u, test_observer_->scanned_devices_so_far.size());
+}
+
+}  // namespace tether
+
+}  // namespace cryptauth
diff --git a/chromeos/components/tether/host_scanner_unittest.cc b/chromeos/components/tether/host_scanner_unittest.cc
new file mode 100644
index 0000000..aea739f
--- /dev/null
+++ b/chromeos/components/tether/host_scanner_unittest.cc
@@ -0,0 +1,311 @@
+// 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 "chromeos/components/tether/host_scanner.h"
+
+#include <algorithm>
+#include <memory>
+#include <vector>
+
+#include "base/memory/ptr_util.h"
+#include "chromeos/components/tether/fake_ble_connection_manager.h"
+#include "chromeos/components/tether/fake_tether_host_fetcher.h"
+#include "chromeos/components/tether/host_scan_device_prioritizer.h"
+#include "components/cryptauth/remote_device_test_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace chromeos {
+
+namespace tether {
+
+namespace {
+
+class FakeHostScanDevicePrioritizer : public HostScanDevicePrioritizer {
+ public:
+  FakeHostScanDevicePrioritizer() : HostScanDevicePrioritizer(nullptr) {}
+  ~FakeHostScanDevicePrioritizer() override {}
+
+  // Simply leave |remote_devices| as-is.
+  void SortByHostScanOrder(
+      std::vector<cryptauth::RemoteDevice>* remote_devices) const override {}
+};
+
+class FakeHostScannerOperation : public HostScannerOperation {
+ public:
+  FakeHostScannerOperation(
+      const std::vector<cryptauth::RemoteDevice>& devices_to_connect,
+      BleConnectionManager* connection_manager,
+      HostScanDevicePrioritizer* host_scan_device_prioritizer)
+      : HostScannerOperation(devices_to_connect,
+                             connection_manager,
+                             host_scan_device_prioritizer) {}
+
+  ~FakeHostScannerOperation() override {}
+
+  void SendScannedDeviceListUpdate(
+      const std::vector<HostScannerOperation::ScannedDeviceInfo>&
+          scanned_device_list_so_far,
+      bool is_final_scan_result) {
+    scanned_device_list_so_far_ = scanned_device_list_so_far;
+    NotifyObserversOfScannedDeviceList(is_final_scan_result);
+  }
+};
+
+class FakeHostScannerOperationFactory : public HostScannerOperation::Factory {
+ public:
+  FakeHostScannerOperationFactory(
+      const std::vector<cryptauth::RemoteDevice>& test_devices)
+      : expected_devices_(test_devices) {}
+  virtual ~FakeHostScannerOperationFactory() {}
+
+  std::vector<FakeHostScannerOperation*>& created_operations() {
+    return created_operations_;
+  }
+
+ protected:
+  // HostScannerOperation::Factory:
+  std::unique_ptr<HostScannerOperation> BuildInstance(
+      const std::vector<cryptauth::RemoteDevice>& devices_to_connect,
+      BleConnectionManager* connection_manager,
+      HostScanDevicePrioritizer* host_scan_device_prioritizer) override {
+    EXPECT_EQ(expected_devices_, devices_to_connect);
+    FakeHostScannerOperation* operation = new FakeHostScannerOperation(
+        devices_to_connect, connection_manager, host_scan_device_prioritizer);
+    created_operations_.push_back(operation);
+    return base::WrapUnique(operation);
+  }
+
+ private:
+  const std::vector<cryptauth::RemoteDevice>& expected_devices_;
+  std::vector<FakeHostScannerOperation*> created_operations_;
+};
+
+std::string GenerateCellProviderForDevice(
+    const cryptauth::RemoteDevice& remote_device) {
+  // Return a string unique to |remote_device|.
+  return "cellProvider" + remote_device.GetTruncatedDeviceIdForLogs();
+}
+
+DeviceStatus CreateFakeDeviceStatus(const std::string& cell_provider_name) {
+  WifiStatus wifi_status;
+  wifi_status.set_status_code(
+      WifiStatus_StatusCode::WifiStatus_StatusCode_CONNECTED);
+  wifi_status.set_ssid("Google A");
+
+  DeviceStatus device_status;
+  device_status.set_battery_percentage(75);
+  device_status.set_cell_provider(cell_provider_name);
+  device_status.set_connection_strength(4);
+  device_status.mutable_wifi_status()->CopyFrom(wifi_status);
+
+  return device_status;
+}
+
+std::vector<HostScannerOperation::ScannedDeviceInfo>
+CreateFakeScannedDeviceInfos(
+    const std::vector<cryptauth::RemoteDevice>& remote_devices) {
+  std::vector<HostScannerOperation::ScannedDeviceInfo> scanned_device_infos;
+  for (size_t i = 0; i < remote_devices.size(); ++i) {
+    DeviceStatus device_status = CreateFakeDeviceStatus(
+        GenerateCellProviderForDevice(remote_devices[i]));
+    // Require set-up for odd-numbered device indices.
+    bool set_up_required = i % 2 == 0;
+    scanned_device_infos.push_back(HostScannerOperation::ScannedDeviceInfo(
+        remote_devices[i], device_status, set_up_required));
+  }
+  return scanned_device_infos;
+}
+
+}  // namespace
+
+class HostScannerTest : public testing::Test {
+ protected:
+  HostScannerTest()
+      : test_devices_(cryptauth::GenerateTestRemoteDevices(4)),
+        test_scanned_device_infos(CreateFakeScannedDeviceInfos(test_devices_)) {
+  }
+
+  void SetUp() override {
+    scanned_device_infos_so_far_.clear();
+
+    fake_tether_host_fetcher_ = base::MakeUnique<FakeTetherHostFetcher>(
+        test_devices_, false /* synchronously_reply_with_results */);
+    fake_ble_connection_manager_ = base::MakeUnique<FakeBleConnectionManager>();
+    fake_host_scan_device_prioritizer_ =
+        base::MakeUnique<FakeHostScanDevicePrioritizer>();
+
+    fake_host_scanner_operation_factory_ =
+        base::WrapUnique(new FakeHostScannerOperationFactory(test_devices_));
+    HostScannerOperation::Factory::SetInstanceForTesting(
+        fake_host_scanner_operation_factory_.get());
+
+    host_scanner_ = base::MakeUnique<HostScanner>(
+        fake_tether_host_fetcher_.get(), fake_ble_connection_manager_.get(),
+        fake_host_scan_device_prioritizer_.get());
+  }
+
+  // Causes |fake_operation| to receive the scan result in
+  // |test_scanned_device_infos| vector at the index |test_device_index| with
+  // the "final result" value of |is_final_scan_result|.
+  void ReceiveScanResultAndVerifySuccess(
+      FakeHostScannerOperation* fake_operation,
+      size_t test_device_index,
+      bool is_final_scan_result) {
+    scanned_device_infos_so_far_.push_back(
+        test_scanned_device_infos[test_device_index]);
+    fake_operation->SendScannedDeviceListUpdate(scanned_device_infos_so_far_,
+                                                is_final_scan_result);
+    EXPECT_EQ(scanned_device_infos_so_far_,
+              host_scanner_->most_recent_scan_results());
+  }
+
+  const std::vector<cryptauth::RemoteDevice> test_devices_;
+  const std::vector<HostScannerOperation::ScannedDeviceInfo>
+      test_scanned_device_infos;
+
+  std::unique_ptr<FakeTetherHostFetcher> fake_tether_host_fetcher_;
+  std::unique_ptr<FakeBleConnectionManager> fake_ble_connection_manager_;
+  std::unique_ptr<HostScanDevicePrioritizer> fake_host_scan_device_prioritizer_;
+
+  std::unique_ptr<FakeHostScannerOperationFactory>
+      fake_host_scanner_operation_factory_;
+
+  std::vector<HostScannerOperation::ScannedDeviceInfo>
+      scanned_device_infos_so_far_;
+
+  std::unique_ptr<HostScanner> host_scanner_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(HostScannerTest);
+};
+
+TEST_F(HostScannerTest, TestScan_ResultsFromAllDevices) {
+  EXPECT_FALSE(host_scanner_->IsScanActive());
+  host_scanner_->StartScan();
+  EXPECT_TRUE(host_scanner_->IsScanActive());
+
+  fake_tether_host_fetcher_->InvokePendingCallbacks();
+  ASSERT_EQ(1u,
+            fake_host_scanner_operation_factory_->created_operations().size());
+  EXPECT_TRUE(host_scanner_->IsScanActive());
+
+  ReceiveScanResultAndVerifySuccess(
+      fake_host_scanner_operation_factory_->created_operations()[0],
+      0u /* test_device_index */, false /* is_final_scan_result */);
+  EXPECT_TRUE(host_scanner_->IsScanActive());
+  ReceiveScanResultAndVerifySuccess(
+      fake_host_scanner_operation_factory_->created_operations()[0],
+      1u /* test_device_index */, false /* is_final_scan_result */);
+  EXPECT_TRUE(host_scanner_->IsScanActive());
+  ReceiveScanResultAndVerifySuccess(
+      fake_host_scanner_operation_factory_->created_operations()[0],
+      2u /* test_device_index */, false /* is_final_scan_result */);
+  EXPECT_TRUE(host_scanner_->IsScanActive());
+  ReceiveScanResultAndVerifySuccess(
+      fake_host_scanner_operation_factory_->created_operations()[0],
+      3u /* test_device_index */, true /* is_final_scan_result */);
+  EXPECT_FALSE(host_scanner_->IsScanActive());
+}
+
+TEST_F(HostScannerTest, TestScan_ResultsFromNoDevices) {
+  EXPECT_FALSE(host_scanner_->IsScanActive());
+  host_scanner_->StartScan();
+  EXPECT_TRUE(host_scanner_->IsScanActive());
+
+  fake_tether_host_fetcher_->InvokePendingCallbacks();
+  ASSERT_EQ(1u,
+            fake_host_scanner_operation_factory_->created_operations().size());
+  EXPECT_TRUE(host_scanner_->IsScanActive());
+
+  fake_host_scanner_operation_factory_->created_operations()[0]
+      ->SendScannedDeviceListUpdate(
+          std::vector<HostScannerOperation::ScannedDeviceInfo>(),
+          true /* is_final_scan_result */);
+  EXPECT_TRUE(host_scanner_->most_recent_scan_results().empty());
+  EXPECT_FALSE(host_scanner_->IsScanActive());
+}
+
+TEST_F(HostScannerTest, TestScan_ResultsFromSomeDevices) {
+  EXPECT_FALSE(host_scanner_->IsScanActive());
+  host_scanner_->StartScan();
+  EXPECT_TRUE(host_scanner_->IsScanActive());
+
+  fake_tether_host_fetcher_->InvokePendingCallbacks();
+  ASSERT_EQ(1u,
+            fake_host_scanner_operation_factory_->created_operations().size());
+  EXPECT_TRUE(host_scanner_->IsScanActive());
+
+  // Only receive updates from the 0th and 1st device.
+  ReceiveScanResultAndVerifySuccess(
+      fake_host_scanner_operation_factory_->created_operations()[0],
+      0u /* test_device_index */, false /* is_final_scan_result */);
+  EXPECT_TRUE(host_scanner_->IsScanActive());
+  ReceiveScanResultAndVerifySuccess(
+      fake_host_scanner_operation_factory_->created_operations()[0],
+      1u /* test_device_index */, false /* is_final_scan_result */);
+  EXPECT_TRUE(host_scanner_->IsScanActive());
+
+  fake_host_scanner_operation_factory_->created_operations()[0]
+      ->SendScannedDeviceListUpdate(scanned_device_infos_so_far_,
+                                    true /* is_final_scan_result */);
+  EXPECT_EQ(scanned_device_infos_so_far_,
+            host_scanner_->most_recent_scan_results());
+  EXPECT_FALSE(host_scanner_->IsScanActive());
+}
+
+TEST_F(HostScannerTest, TestScan_MultipleScanCallsDuringOperation) {
+  EXPECT_FALSE(host_scanner_->IsScanActive());
+  host_scanner_->StartScan();
+  EXPECT_TRUE(host_scanner_->IsScanActive());
+
+  // Call StartScan() again before the tether host fetcher has finished. This
+  // should be a no-op.
+  host_scanner_->StartScan();
+  EXPECT_TRUE(host_scanner_->IsScanActive());
+
+  // No devices should have been received yet.
+  EXPECT_EQ(std::vector<HostScannerOperation::ScannedDeviceInfo>(),
+            host_scanner_->most_recent_scan_results());
+
+  fake_tether_host_fetcher_->InvokePendingCallbacks();
+  ASSERT_EQ(1u,
+            fake_host_scanner_operation_factory_->created_operations().size());
+  EXPECT_TRUE(host_scanner_->IsScanActive());
+
+  // Call StartScan again after the tether host fetcher has finished but before
+  // the final scan result has been received. This should be a no-op.
+  host_scanner_->StartScan();
+  EXPECT_TRUE(host_scanner_->IsScanActive());
+
+  // No devices should have been received yet.
+  EXPECT_EQ(std::vector<HostScannerOperation::ScannedDeviceInfo>(),
+            host_scanner_->most_recent_scan_results());
+
+  // Receive updates from the 0th device.
+  ReceiveScanResultAndVerifySuccess(
+      fake_host_scanner_operation_factory_->created_operations()[0],
+      0u /* test_device_index */, false /* is_final_scan_result */);
+  EXPECT_TRUE(host_scanner_->IsScanActive());
+
+  // Call StartScan again after a scan result has been received but before
+  // the final scan result ha been received. This should be a no-op.
+  host_scanner_->StartScan();
+  EXPECT_TRUE(host_scanner_->IsScanActive());
+
+  // No devices should have been received yet.
+  EXPECT_EQ(scanned_device_infos_so_far_,
+            host_scanner_->most_recent_scan_results());
+
+  // Finally, finish the scan.
+  fake_host_scanner_operation_factory_->created_operations()[0]
+      ->SendScannedDeviceListUpdate(scanned_device_infos_so_far_,
+                                    true /* is_final_scan_result */);
+  EXPECT_EQ(scanned_device_infos_so_far_,
+            host_scanner_->most_recent_scan_results());
+  EXPECT_FALSE(host_scanner_->IsScanActive());
+}
+
+}  // namespace tether
+
+}  // namespace cryptauth
diff --git a/chromeos/components/tether/message_transfer_operation.h b/chromeos/components/tether/message_transfer_operation.h
index 28594906..30ba00c 100644
--- a/chromeos/components/tether/message_transfer_operation.h
+++ b/chromeos/components/tether/message_transfer_operation.h
@@ -75,8 +75,9 @@
   }
 
  private:
-  friend class MessageTransferOperationTest;
   friend class ConnectTetheringOperationTest;
+  friend class HostScannerOperationTest;
+  friend class MessageTransferOperationTest;
 
   static uint32_t kMaxConnectionAttemptsPerDevice;
 
diff --git a/chromeos/components/tether/tether_host_fetcher.h b/chromeos/components/tether/tether_host_fetcher.h
index e176c810..3555af3 100644
--- a/chromeos/components/tether/tether_host_fetcher.h
+++ b/chromeos/components/tether/tether_host_fetcher.h
@@ -51,7 +51,7 @@
   virtual void FetchTetherHost(const std::string& device_id,
                                const TetherHostCallback& callback);
 
- private:
+ protected:
   struct TetherHostFetchRequest {
     TetherHostFetchRequest(const TetherHostListCallback& list_callback);
     TetherHostFetchRequest(const std::string& device_id,
@@ -69,16 +69,18 @@
     TetherHostCallback single_callback;
   };
 
-  void StartLoadingDevicesIfNeeded();
   void OnRemoteDevicesLoaded(const cryptauth::RemoteDeviceList& remote_devices);
 
+  std::vector<TetherHostFetchRequest> requests_;
+
+ private:
+  void StartLoadingDevicesIfNeeded();
+
   const std::string user_id_;
   const std::string user_private_key_;
   std::unique_ptr<Delegate> delegate_;
   cryptauth::CryptAuthDeviceManager* device_manager_;
 
-  std::vector<TetherHostFetchRequest> requests_;
-
   std::unique_ptr<cryptauth::RemoteDeviceLoader> remote_device_loader_;
 
   base::WeakPtrFactory<TetherHostFetcher> weak_ptr_factory_;
diff --git a/chromeos/dbus/fake_shill_device_client.cc b/chromeos/dbus/fake_shill_device_client.cc
index f1d0e18..c567864 100644
--- a/chromeos/dbus/fake_shill_device_client.cc
+++ b/chromeos/dbus/fake_shill_device_client.cc
@@ -266,7 +266,7 @@
                                        const base::Closure& callback,
                                        const ErrorCallback& error_callback) {
   SetPropertyInternal(device_path, shill::kCarrierProperty,
-                      base::StringValue(carrier), callback, error_callback);
+                      base::Value(carrier), callback, error_callback);
 }
 
 void FakeShillDeviceClient::Reset(const dbus::ObjectPath& device_path,
diff --git a/chromeos/dbus/fake_shill_manager_client.cc b/chromeos/dbus/fake_shill_manager_client.cc
index bd8190d4..0c103e71 100644
--- a/chromeos/dbus/fake_shill_manager_client.cc
+++ b/chromeos/dbus/fake_shill_manager_client.cc
@@ -111,10 +111,11 @@
 }
 
 void UpdatePortaledWifiState(const std::string& service_path) {
-  DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface()
-      ->SetServiceProperty(service_path,
-                           shill::kStateProperty,
-                           base::StringValue(shill::kStatePortal));
+  DBusThreadManager::Get()
+      ->GetShillServiceClient()
+      ->GetTestInterface()
+      ->SetServiceProperty(service_path, shill::kStateProperty,
+                           base::Value(shill::kStatePortal));
 }
 
 bool IsCellularTechnology(const std::string& type) {
@@ -383,14 +384,13 @@
 
 void FakeShillManagerClient::AddDevice(const std::string& device_path) {
   if (GetListProperty(shill::kDevicesProperty)
-          ->AppendIfNotPresent(
-              base::MakeUnique<base::StringValue>(device_path))) {
+          ->AppendIfNotPresent(base::MakeUnique<base::Value>(device_path))) {
     CallNotifyObserversPropertyChanged(shill::kDevicesProperty);
   }
 }
 
 void FakeShillManagerClient::RemoveDevice(const std::string& device_path) {
-  base::StringValue device_path_value(device_path);
+  base::Value device_path_value(device_path);
   if (GetListProperty(shill::kDevicesProperty)->Remove(
       device_path_value, NULL)) {
     CallNotifyObserversPropertyChanged(shill::kDevicesProperty);
@@ -405,20 +405,20 @@
 void FakeShillManagerClient::AddTechnology(const std::string& type,
                                            bool enabled) {
   if (GetListProperty(shill::kAvailableTechnologiesProperty)
-          ->AppendIfNotPresent(base::MakeUnique<base::StringValue>(type))) {
+          ->AppendIfNotPresent(base::MakeUnique<base::Value>(type))) {
     CallNotifyObserversPropertyChanged(
         shill::kAvailableTechnologiesProperty);
   }
   if (enabled &&
       GetListProperty(shill::kEnabledTechnologiesProperty)
-          ->AppendIfNotPresent(base::MakeUnique<base::StringValue>(type))) {
+          ->AppendIfNotPresent(base::MakeUnique<base::Value>(type))) {
     CallNotifyObserversPropertyChanged(
         shill::kEnabledTechnologiesProperty);
   }
 }
 
 void FakeShillManagerClient::RemoveTechnology(const std::string& type) {
-  base::StringValue type_value(type);
+  base::Value type_value(type);
   if (GetListProperty(shill::kAvailableTechnologiesProperty)->Remove(
       type_value, NULL)) {
     CallNotifyObserversPropertyChanged(
@@ -435,13 +435,13 @@
                                                        bool initializing) {
   if (initializing) {
     if (GetListProperty(shill::kUninitializedTechnologiesProperty)
-            ->AppendIfNotPresent(base::MakeUnique<base::StringValue>(type))) {
+            ->AppendIfNotPresent(base::MakeUnique<base::Value>(type))) {
       CallNotifyObserversPropertyChanged(
           shill::kUninitializedTechnologiesProperty);
     }
   } else {
-    if (GetListProperty(shill::kUninitializedTechnologiesProperty)->Remove(
-            base::StringValue(type), NULL)) {
+    if (GetListProperty(shill::kUninitializedTechnologiesProperty)
+            ->Remove(base::Value(type), NULL)) {
       CallNotifyObserversPropertyChanged(
           shill::kUninitializedTechnologiesProperty);
     }
@@ -463,7 +463,7 @@
 void FakeShillManagerClient::AddProfile(const std::string& profile_path) {
   const char* key = shill::kProfilesProperty;
   if (GetListProperty(key)->AppendIfNotPresent(
-          base::MakeUnique<base::StringValue>(profile_path))) {
+          base::MakeUnique<base::Value>(profile_path))) {
     CallNotifyObserversPropertyChanged(key);
   }
 }
@@ -483,7 +483,7 @@
     bool notify_observers) {
   VLOG(2) << "AddManagerService: " << service_path;
   GetListProperty(shill::kServiceCompleteListProperty)
-      ->AppendIfNotPresent(base::MakeUnique<base::StringValue>(service_path));
+      ->AppendIfNotPresent(base::MakeUnique<base::Value>(service_path));
   SortManagerServices(false);
   if (notify_observers)
     CallNotifyObserversPropertyChanged(shill::kServiceCompleteListProperty);
@@ -492,7 +492,7 @@
 void FakeShillManagerClient::RemoveManagerService(
     const std::string& service_path) {
   VLOG(2) << "RemoveManagerService: " << service_path;
-  base::StringValue service_path_value(service_path);
+  base::Value service_path_value(service_path);
   GetListProperty(shill::kServiceCompleteListProperty)->Remove(
       service_path_value, NULL);
   CallNotifyObserversPropertyChanged(shill::kServiceCompleteListProperty);
@@ -510,7 +510,7 @@
   if (service_path == default_service_ && !IsConnectedState(state)) {
     // Default service is no longer connected; clear.
     default_service_.clear();
-    base::StringValue default_service_value(default_service_);
+    base::Value default_service_value(default_service_);
     SetManagerProperty(shill::kDefaultServiceProperty, default_service_value);
   }
 }
@@ -572,7 +572,7 @@
   }
   if (default_service_ != new_default_service) {
     default_service_ = new_default_service;
-    base::StringValue default_service_value(default_service_);
+    base::Value default_service_value(default_service_);
     SetManagerProperty(shill::kDefaultServiceProperty, default_service_value);
   }
 }
@@ -647,9 +647,8 @@
     AddTechnology(shill::kTypeEthernet, enabled);
     devices->AddDevice(
         "/device/eth1", shill::kTypeEthernet, "stub_eth_device1");
-    devices->SetDeviceProperty("/device/eth1",
-                               shill::kAddressProperty,
-                               base::StringValue("0123456789ab"));
+    devices->SetDeviceProperty("/device/eth1", shill::kAddressProperty,
+                               base::Value("0123456789ab"));
     base::ListValue eth_ip_configs;
     eth_ip_configs.AppendString("ipconfig_v4_path");
     eth_ip_configs.AppendString("ipconfig_v6_path");
@@ -683,9 +682,8 @@
     }
     AddTechnology(shill::kTypeWifi, enabled);
     devices->AddDevice("/device/wifi1", shill::kTypeWifi, "stub_wifi_device1");
-    devices->SetDeviceProperty("/device/wifi1",
-                               shill::kAddressProperty,
-                               base::StringValue("23456789abcd"));
+    devices->SetDeviceProperty("/device/wifi1", shill::kAddressProperty,
+                               base::Value("23456789abcd"));
     base::ListValue wifi_ip_configs;
     wifi_ip_configs.AppendString("ipconfig_v4_path");
     wifi_ip_configs.AppendString("ipconfig_v6_path");
@@ -700,9 +698,8 @@
                          shill::kTypeWifi,
                          state,
                          add_to_visible);
-    services->SetServiceProperty(kWifi1Path,
-                                 shill::kSecurityClassProperty,
-                                 base::StringValue(shill::kSecurityWep));
+    services->SetServiceProperty(kWifi1Path, shill::kSecurityClassProperty,
+                                 base::Value(shill::kSecurityWep));
     services->SetServiceProperty(kWifi1Path, shill::kConnectableProperty,
                                  base::Value(true));
     profiles->AddService(shared_profile, kWifi1Path);
@@ -713,17 +710,16 @@
                          shill::kTypeWifi, shill::kStateIdle, add_to_visible);
     if (s_dynamic_wep) {
       services->SetServiceProperty(kWifi2Path, shill::kSecurityClassProperty,
-                                   base::StringValue(shill::kSecurityWep));
-      services->SetServiceProperty(
-          kWifi2Path, shill::kEapKeyMgmtProperty,
-          base::StringValue(shill::kKeyManagementIEEE8021X));
+                                   base::Value(shill::kSecurityWep));
+      services->SetServiceProperty(kWifi2Path, shill::kEapKeyMgmtProperty,
+                                   base::Value(shill::kKeyManagementIEEE8021X));
       services->SetServiceProperty(kWifi2Path, shill::kEapMethodProperty,
-                                   base::StringValue(shill::kEapMethodPEAP));
+                                   base::Value(shill::kEapMethodPEAP));
       services->SetServiceProperty(kWifi2Path, shill::kEapIdentityProperty,
-                                   base::StringValue("John Doe"));
+                                   base::Value("John Doe"));
     } else {
       services->SetServiceProperty(kWifi2Path, shill::kSecurityClassProperty,
-                                   base::StringValue(shill::kSecurityPsk));
+                                   base::Value(shill::kSecurityPsk));
     }
     services->SetServiceProperty(kWifi2Path, shill::kSignalStrengthProperty,
                                  base::Value(80));
@@ -746,7 +742,7 @@
                            shill::kStateIdle, add_to_visible);
       services->SetServiceProperty(kPortaledWifiPath,
                                    shill::kSecurityClassProperty,
-                                   base::StringValue(shill::kSecurityNone));
+                                   base::Value(shill::kSecurityNone));
       services->SetConnectBehavior(
           kPortaledWifiPath,
           base::Bind(&UpdatePortaledWifiState, kPortaledWifiPath));
@@ -794,9 +790,8 @@
     AddTechnology(shill::kTypeCellular, enabled);
     devices->AddDevice(
         "/device/cellular1", shill::kTypeCellular, "stub_cellular_device1");
-    devices->SetDeviceProperty("/device/cellular1",
-                               shill::kCarrierProperty,
-                               base::StringValue(shill::kCarrierSprint));
+    devices->SetDeviceProperty("/device/cellular1", shill::kCarrierProperty,
+                               base::Value(shill::kCarrierSprint));
     base::ListValue carrier_list;
     carrier_list.AppendString(shill::kCarrierSprint);
     carrier_list.AppendString(shill::kCarrierGenericUMTS);
@@ -823,7 +818,7 @@
                          shill::kTypeCellular,
                          state,
                          add_to_visible);
-    base::StringValue technology_value(cellular_technology_);
+    base::Value technology_value(cellular_technology_);
     devices->SetDeviceProperty("/device/cellular1",
                                shill::kTechnologyFamilyProperty,
                                technology_value);
@@ -836,16 +831,14 @@
 
     if (activated) {
       services->SetServiceProperty(
-          kCellularServicePath,
-          shill::kActivationStateProperty,
-          base::StringValue(shill::kActivationStateActivated));
+          kCellularServicePath, shill::kActivationStateProperty,
+          base::Value(shill::kActivationStateActivated));
       services->SetServiceProperty(
           kCellularServicePath, shill::kConnectableProperty, base::Value(true));
     } else {
       services->SetServiceProperty(
-          kCellularServicePath,
-          shill::kActivationStateProperty,
-          base::StringValue(shill::kActivationStateNotActivated));
+          kCellularServicePath, shill::kActivationStateProperty,
+          base::Value(shill::kActivationStateNotActivated));
     }
 
     std::string shill_roaming_state;
@@ -857,7 +850,7 @@
       shill_roaming_state = roaming_state_;
     services->SetServiceProperty(kCellularServicePath,
                                  shill::kRoamingStateProperty,
-                                 base::StringValue(shill_roaming_state));
+                                 base::Value(shill_roaming_state));
 
     base::DictionaryValue apn;
     apn.SetStringWithoutPathExpansion(shill::kApnProperty, "testapn");
@@ -1000,7 +993,7 @@
   const base::ListValue* technologies;
   if (stub_properties_.GetListWithoutPathExpansion(
           shill::kEnabledTechnologiesProperty, &technologies)) {
-    base::StringValue type_value(type);
+    base::Value type_value(type);
     if (technologies->Find(type_value) != technologies->end())
       enabled = true;
   }
@@ -1014,9 +1007,9 @@
   base::ListValue* enabled_list =
       GetListProperty(shill::kEnabledTechnologiesProperty);
   if (enabled)
-    enabled_list->AppendIfNotPresent(base::MakeUnique<base::StringValue>(type));
+    enabled_list->AppendIfNotPresent(base::MakeUnique<base::Value>(type));
   else
-    enabled_list->Remove(base::StringValue(type), NULL);
+    enabled_list->Remove(base::Value(type), NULL);
   CallNotifyObserversPropertyChanged(
       shill::kEnabledTechnologiesProperty);
   base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback);
@@ -1112,9 +1105,9 @@
     }
     shill_device_property_map_[shill::kTypeCellular]
                               [shill::kSIMLockStatusProperty] = simlock_dict;
-    shill_device_property_map_
-        [shill::kTypeCellular][shill::kTechnologyFamilyProperty] =
-            new base::StringValue(shill::kNetworkTechnologyGsm);
+    shill_device_property_map_[shill::kTypeCellular]
+                              [shill::kTechnologyFamilyProperty] =
+                                  new base::Value(shill::kNetworkTechnologyGsm);
     return true;
   } else if (arg0 == "sim_present") {
     bool present = (arg1 == "1");
diff --git a/chromeos/dbus/fake_shill_profile_client.cc b/chromeos/dbus/fake_shill_profile_client.cc
index fef353d..9a5fe1a 100644
--- a/chromeos/dbus/fake_shill_profile_client.cc
+++ b/chromeos/dbus/fake_shill_profile_client.cc
@@ -109,7 +109,7 @@
     return;
   }
 
-  base::StringValue profile_path_value("");
+  base::Value profile_path_value("");
   DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface()->
       SetServiceProperty(entry_path,
                          shill::kProfileProperty,
@@ -194,7 +194,7 @@
   service_properties->GetStringWithoutPathExpansion(shill::kProfileProperty,
                                                     &service_profile_path);
   if (service_profile_path.empty()) {
-    base::StringValue profile_path_value(profile_path);
+    base::Value profile_path_value(profile_path);
     service_test->SetServiceProperty(service_path,
                                      shill::kProfileProperty,
                                      profile_path_value);
diff --git a/chromeos/dbus/fake_shill_service_client.cc b/chromeos/dbus/fake_shill_service_client.cc
index 00735b4..254f603 100644
--- a/chromeos/dbus/fake_shill_service_client.cc
+++ b/chromeos/dbus/fake_shill_service_client.cc
@@ -190,7 +190,7 @@
   service_properties->SetStringWithoutPathExpansion(shill::kErrorProperty, "");
 
   // Set Associating.
-  base::StringValue associating_value(shill::kStateAssociation);
+  base::Value associating_value(shill::kStateAssociation);
   SetServiceProperty(service_path.value(), shill::kStateProperty,
                      associating_value);
 
@@ -213,7 +213,7 @@
     return;
   }
   // Set Idle after a delay
-  base::StringValue idle_value(shill::kStateIdle);
+  base::Value idle_value(shill::kStateIdle);
   base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
       FROM_HERE, base::Bind(&FakeShillServiceClient::SetProperty,
                             weak_ptr_factory_.GetWeakPtr(), service_path,
@@ -240,9 +240,8 @@
     LOG(ERROR) << "Service not found: " << service_path.value();
     error_callback.Run("Error.InvalidService", "Invalid Service");
   }
-  SetServiceProperty(service_path.value(),
-                     shill::kActivationStateProperty,
-                     base::StringValue(shill::kActivationStateActivating));
+  SetServiceProperty(service_path.value(), shill::kActivationStateProperty,
+                     base::Value(shill::kActivationStateActivating));
   // Set Activated after a delay
   base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
       FROM_HERE,
@@ -323,9 +322,8 @@
   }
 
   if (!ipconfig_path.empty()) {
-    properties->SetWithoutPathExpansion(
-        shill::kIPConfigProperty,
-        new base::StringValue(ipconfig_path));
+    properties->SetWithoutPathExpansion(shill::kIPConfigProperty,
+                                        new base::Value(ipconfig_path));
   }
 
   DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface()->
@@ -571,20 +569,17 @@
     properties->GetString(shill::kTypeProperty, &type);
     if (type != service_type)
       continue;
-    properties->SetWithoutPathExpansion(
-        shill::kStateProperty,
-        new base::StringValue(shill::kStateIdle));
+    properties->SetWithoutPathExpansion(shill::kStateProperty,
+                                        new base::Value(shill::kStateIdle));
   }
 }
 
 void FakeShillServiceClient::SetCellularActivated(
     const dbus::ObjectPath& service_path,
     const ErrorCallback& error_callback) {
-  SetProperty(service_path,
-              shill::kActivationStateProperty,
-              base::StringValue(shill::kActivationStateActivated),
-              base::Bind(&base::DoNothing),
-              error_callback);
+  SetProperty(service_path, shill::kActivationStateProperty,
+              base::Value(shill::kActivationStateActivated),
+              base::Bind(&base::DoNothing), error_callback);
   SetProperty(service_path, shill::kConnectableProperty, base::Value(true),
               base::Bind(&base::DoNothing), error_callback);
 }
@@ -612,20 +607,20 @@
   if (passphrase == "failure") {
     // Simulate a password failure.
     SetServiceProperty(service_path, shill::kErrorProperty,
-                       base::StringValue(shill::kErrorBadPassphrase));
+                       base::Value(shill::kErrorBadPassphrase));
     SetServiceProperty(service_path, shill::kStateProperty,
-                       base::StringValue(shill::kStateFailure));
+                       base::Value(shill::kStateFailure));
     base::ThreadTaskRunnerHandle::Get()->PostTask(
         FROM_HERE,
         base::Bind(
             base::IgnoreResult(&FakeShillServiceClient::SetServiceProperty),
             weak_ptr_factory_.GetWeakPtr(), service_path, shill::kErrorProperty,
-            base::StringValue(shill::kErrorBadPassphrase)));
+            base::Value(shill::kErrorBadPassphrase)));
   } else {
     // Set Online.
     VLOG(1) << "Setting state to Online " << service_path;
     SetServiceProperty(service_path, shill::kStateProperty,
-                       base::StringValue(shill::kStateOnline));
+                       base::Value(shill::kStateOnline));
   }
 }
 
diff --git a/chromeos/dbus/gsm_sms_client_unittest.cc b/chromeos/dbus/gsm_sms_client_unittest.cc
index 5cadf58..fb52c37 100644
--- a/chromeos/dbus/gsm_sms_client_unittest.cc
+++ b/chromeos/dbus/gsm_sms_client_unittest.cc
@@ -256,10 +256,10 @@
   response_ = response.get();
   // Create expected result.
   base::DictionaryValue expected_result;
-  expected_result.SetWithoutPathExpansion(
-      kNumberKey, new base::StringValue(kExampleNumber));
+  expected_result.SetWithoutPathExpansion(kNumberKey,
+                                          new base::Value(kExampleNumber));
   expected_result.SetWithoutPathExpansion(kTextKey,
-                                          new base::StringValue(kExampleText));
+                                          new base::Value(kExampleText));
   expected_result_ = &expected_result;
   // Call Get.
   client_->Get(kServiceName, dbus::ObjectPath(kObjectPath), kIndex,
@@ -298,9 +298,8 @@
   // Create expected result.
   base::ListValue expected_result;
   auto sms = base::MakeUnique<base::DictionaryValue>();
-  sms->SetWithoutPathExpansion(kNumberKey,
-                               new base::StringValue(kExampleNumber));
-  sms->SetWithoutPathExpansion(kTextKey, new base::StringValue(kExampleText));
+  sms->SetWithoutPathExpansion(kNumberKey, new base::Value(kExampleNumber));
+  sms->SetWithoutPathExpansion(kTextKey, new base::Value(kExampleText));
   expected_result.Append(std::move(sms));
   expected_result_ = &expected_result;
   // Call List.
diff --git a/chromeos/dbus/shill_client_unittest_base.cc b/chromeos/dbus/shill_client_unittest_base.cc
index c4bb922..c8120be 100644
--- a/chromeos/dbus/shill_client_unittest_base.cc
+++ b/chromeos/dbus/shill_client_unittest_base.cc
@@ -42,7 +42,7 @@
         !entry_reader.PopString(&key) ||
         !entry_reader.PopString(&value))
       return NULL;
-    result->SetWithoutPathExpansion(key, new base::StringValue(value));
+    result->SetWithoutPathExpansion(key, new base::Value(value));
   }
   return result.release();
 }
@@ -316,15 +316,14 @@
   base::DictionaryValue* properties = new base::DictionaryValue;
   properties->SetWithoutPathExpansion(
       shill::kGuidProperty,
-      new base::StringValue("00000000-0000-0000-0000-000000000000"));
-  properties->SetWithoutPathExpansion(
-      shill::kModeProperty, new base::StringValue(shill::kModeManaged));
+      new base::Value("00000000-0000-0000-0000-000000000000"));
+  properties->SetWithoutPathExpansion(shill::kModeProperty,
+                                      new base::Value(shill::kModeManaged));
   properties->SetWithoutPathExpansion(shill::kTypeProperty,
-                                      new base::StringValue(shill::kTypeWifi));
+                                      new base::Value(shill::kTypeWifi));
   shill_property_util::SetSSID("testssid", properties);
-  properties->SetWithoutPathExpansion(
-      shill::kSecurityClassProperty,
-      new base::StringValue(shill::kSecurityPsk));
+  properties->SetWithoutPathExpansion(shill::kSecurityClassProperty,
+                                      new base::Value(shill::kSecurityPsk));
   return properties;
 }
 
diff --git a/chromeos/dbus/shill_ipconfig_client_unittest.cc b/chromeos/dbus/shill_ipconfig_client_unittest.cc
index 8f884d7..dd79e2c 100644
--- a/chromeos/dbus/shill_ipconfig_client_unittest.cc
+++ b/chromeos/dbus/shill_ipconfig_client_unittest.cc
@@ -106,7 +106,7 @@
   // Create the expected value.
   base::DictionaryValue value;
   value.SetWithoutPathExpansion(shill::kAddressProperty,
-                                new base::StringValue(kAddress));
+                                new base::Value(kAddress));
   value.SetWithoutPathExpansion(shill::kMtuProperty, new base::Value(kMtu));
 
   // Set expectations.
@@ -127,7 +127,7 @@
   std::unique_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
 
   // Set expectations.
-  base::StringValue value(kAddress);
+  base::Value value(kAddress);
   PrepareForMethodCall(shill::kSetPropertyFunction,
                        base::Bind(&ExpectStringAndValueArguments,
                                   shill::kAddressProperty,
diff --git a/chromeos/dbus/shill_manager_client_unittest.cc b/chromeos/dbus/shill_manager_client_unittest.cc
index f46cad6..67e2c7c 100644
--- a/chromeos/dbus/shill_manager_client_unittest.cc
+++ b/chromeos/dbus/shill_manager_client_unittest.cc
@@ -184,8 +184,7 @@
   base::ListValue* type_entry_value = new base::ListValue;
   auto property_dict_value = base::MakeUnique<base::DictionaryValue>();
   property_dict_value->SetWithoutPathExpansion(
-      shill::kGeoMacAddressProperty,
-      new base::StringValue("01:23:45:67:89:AB"));
+      shill::kGeoMacAddressProperty, new base::Value("01:23:45:67:89:AB"));
   type_entry_value->Append(std::move(property_dict_value));
   type_dict_value.SetWithoutPathExpansion("wifi", type_entry_value);
 
@@ -205,7 +204,7 @@
   // Create response.
   std::unique_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
   // Set expectations.
-  base::StringValue value("portal list");
+  base::Value value("portal list");
   PrepareForMethodCall(shill::kSetPropertyFunction,
                        base::Bind(ExpectStringAndValueArguments,
                                   shill::kCheckPortalListProperty,
diff --git a/chromeos/dbus/shill_profile_client_unittest.cc b/chromeos/dbus/shill_profile_client_unittest.cc
index 5be2b33..24932cc 100644
--- a/chromeos/dbus/shill_profile_client_unittest.cc
+++ b/chromeos/dbus/shill_profile_client_unittest.cc
@@ -143,7 +143,7 @@
   // Create the expected value.
   base::DictionaryValue value;
   value.SetWithoutPathExpansion(shill::kTypeProperty,
-                                new base::StringValue(shill::kTypeWifi));
+                                new base::Value(shill::kTypeWifi));
   // Set expectations.
   PrepareForMethodCall(shill::kGetEntryFunction,
                        base::Bind(&ExpectStringArgument, kExampleEntryPath),
diff --git a/chromeos/dbus/shill_service_client_unittest.cc b/chromeos/dbus/shill_service_client_unittest.cc
index b53e5ca..7adc828 100644
--- a/chromeos/dbus/shill_service_client_unittest.cc
+++ b/chromeos/dbus/shill_service_client_unittest.cc
@@ -117,7 +117,7 @@
   std::unique_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
 
   // Set expectations.
-  const base::StringValue value(kValue);
+  const base::Value value(kValue);
   PrepareForMethodCall(shill::kSetPropertyFunction,
                        base::Bind(&ExpectStringAndValueArguments,
                                   shill::kPassphraseProperty,
diff --git a/chromeos/network/client_cert_resolver_unittest.cc b/chromeos/network/client_cert_resolver_unittest.cc
index 0fe79c15..8caac7a 100644
--- a/chromeos/network/client_cert_resolver_unittest.cc
+++ b/chromeos/network/client_cert_resolver_unittest.cc
@@ -172,8 +172,8 @@
                                         true /* visible */);
     // Set an arbitrary cert id, so that we can check afterwards whether we
     // cleared the property or not.
-    service_test_->SetServiceProperty(
-        kWifiStub, shill::kEapCertIdProperty, base::StringValue("invalid id"));
+    service_test_->SetServiceProperty(kWifiStub, shill::kEapCertIdProperty,
+                                      base::Value("invalid id"));
     profile_test_->AddService(kUserProfilePath, kWifiStub);
 
     DBusThreadManager::Get()
@@ -260,7 +260,7 @@
 
   void SetWifiState(const std::string& state) {
     ASSERT_TRUE(service_test_->SetServiceProperty(
-        kWifiStub, shill::kStateProperty, base::StringValue(state)));
+        kWifiStub, shill::kStateProperty, base::Value(state)));
   }
 
   void GetServiceProperty(const std::string& prop_name,
diff --git a/chromeos/network/host_resolver_impl_chromeos_unittest.cc b/chromeos/network/host_resolver_impl_chromeos_unittest.cc
index 0ec0fb46..ca48394 100644
--- a/chromeos/network/host_resolver_impl_chromeos_unittest.cc
+++ b/chromeos/network/host_resolver_impl_chromeos_unittest.cc
@@ -127,11 +127,11 @@
                    const std::string& method,
                    const std::string& address) {
     DBusThreadManager::Get()->GetShillIPConfigClient()->SetProperty(
-        dbus::ObjectPath(path), shill::kAddressProperty,
-        base::StringValue(address), base::Bind(&DoNothingWithCallStatus));
+        dbus::ObjectPath(path), shill::kAddressProperty, base::Value(address),
+        base::Bind(&DoNothingWithCallStatus));
     DBusThreadManager::Get()->GetShillIPConfigClient()->SetProperty(
-        dbus::ObjectPath(path), shill::kMethodProperty,
-        base::StringValue(method), base::Bind(&DoNothingWithCallStatus));
+        dbus::ObjectPath(path), shill::kMethodProperty, base::Value(method),
+        base::Bind(&DoNothingWithCallStatus));
   }
 
   std::unique_ptr<NetworkStateHandler> network_state_handler_;
diff --git a/chromeos/network/network_cert_migrator_unittest.cc b/chromeos/network/network_cert_migrator_unittest.cc
index 006027b0..d57a4ae 100644
--- a/chromeos/network/network_cert_migrator_unittest.cc
+++ b/chromeos/network/network_cert_migrator_unittest.cc
@@ -107,24 +107,22 @@
 
     // Ensure that the service appears as 'configured', i.e. is associated to a
     // Shill profile.
-    service_test_->SetServiceProperty(
-        network_id, shill::kProfileProperty, base::StringValue(kProfile));
+    service_test_->SetServiceProperty(network_id, shill::kProfileProperty,
+                                      base::Value(kProfile));
   }
 
   void SetupNetworkWithEapCertId(bool wifi, const std::string& cert_id) {
     std::string type = wifi ? shill::kTypeWifi: shill::kTypeEthernetEap;
     std::string name = wifi ? kWifiStub : kEthernetEapStub;
     AddService(name, type, shill::kStateOnline);
-    service_test_->SetServiceProperty(
-        name, shill::kEapCertIdProperty, base::StringValue(cert_id));
-    service_test_->SetServiceProperty(
-        name, shill::kEapKeyIdProperty, base::StringValue(cert_id));
+    service_test_->SetServiceProperty(name, shill::kEapCertIdProperty,
+                                      base::Value(cert_id));
+    service_test_->SetServiceProperty(name, shill::kEapKeyIdProperty,
+                                      base::Value(cert_id));
 
     if (wifi) {
-      service_test_->SetServiceProperty(
-          name,
-          shill::kSecurityClassProperty,
-          base::StringValue(shill::kSecurity8021x));
+      service_test_->SetServiceProperty(name, shill::kSecurityClassProperty,
+                                        base::Value(shill::kSecurity8021x));
     }
   }
 
diff --git a/chromeos/network/network_configuration_handler.cc b/chromeos/network/network_configuration_handler.cc
index bdc8c0c..271bcb0f 100644
--- a/chromeos/network/network_configuration_handler.cc
+++ b/chromeos/network/network_configuration_handler.cc
@@ -365,7 +365,7 @@
     const network_handler::ErrorCallback& error_callback) {
   NET_LOG(USER) << "SetNetworkProfile: " << service_path << ": "
                 << profile_path;
-  base::StringValue profile_path_value(profile_path);
+  base::Value profile_path_value(profile_path);
   DBusThreadManager::Get()->GetShillServiceClient()->SetProperty(
       dbus::ObjectPath(service_path), shill::kProfileProperty,
       profile_path_value,
diff --git a/chromeos/network/network_configuration_handler_unittest.cc b/chromeos/network/network_configuration_handler_unittest.cc
index 3b00374..2ae84f3 100644
--- a/chromeos/network/network_configuration_handler_unittest.cc
+++ b/chromeos/network/network_configuration_handler_unittest.cc
@@ -305,11 +305,10 @@
   std::string expected_json = "{\n   \"SSID\": \"MyNetwork\"\n}\n";
   std::string networkName = "MyNetwork";
   std::string key = "SSID";
-  std::unique_ptr<base::StringValue> networkNameValue(
-      new base::StringValue(networkName));
+  std::unique_ptr<base::Value> networkNameValue(new base::Value(networkName));
 
   base::DictionaryValue value;
-  value.Set(key, new base::StringValue(networkName));
+  value.Set(key, new base::Value(networkName));
   dictionary_value_result_ = &value;
   EXPECT_CALL(*mock_service_client_,
               SetProperty(dbus::ObjectPath(service_path), key,
@@ -334,11 +333,10 @@
   std::string service_path = "/service/1";
   std::string networkName = "MyNetwork";
   std::string key = "SSID";
-  std::unique_ptr<base::StringValue> networkNameValue(
-      new base::StringValue(networkName));
+  std::unique_ptr<base::Value> networkNameValue(new base::Value(networkName));
 
   base::DictionaryValue value;
-  value.Set(key, new base::StringValue(networkName));
+  value.Set(key, new base::Value(networkName));
   dictionary_value_result_ = &value;
   EXPECT_CALL(*mock_service_client_, SetProperties(_, _, _, _))
       .WillOnce(
@@ -354,12 +352,11 @@
   std::string service_path = "/service/1";
   std::string networkName = "MyNetwork";
   std::string key = "SSID";
-  std::unique_ptr<base::StringValue> networkNameValue(
-      new base::StringValue(networkName));
+  std::unique_ptr<base::Value> networkNameValue(new base::Value(networkName));
 
   // First set up a value to clear.
   base::DictionaryValue value;
-  value.Set(key, new base::StringValue(networkName));
+  value.Set(key, new base::Value(networkName));
   dictionary_value_result_ = &value;
   EXPECT_CALL(*mock_service_client_, SetProperties(_, _, _, _))
       .WillOnce(
@@ -386,12 +383,11 @@
   std::string service_path = "/service/1";
   std::string networkName = "MyNetwork";
   std::string key = "SSID";
-  std::unique_ptr<base::StringValue> networkNameValue(
-      new base::StringValue(networkName));
+  std::unique_ptr<base::Value> networkNameValue(new base::Value(networkName));
 
   // First set up a value to clear.
   base::DictionaryValue value;
-  value.Set(key, new base::StringValue(networkName));
+  value.Set(key, new base::Value(networkName));
   dictionary_value_result_ = &value;
   EXPECT_CALL(*mock_service_client_, SetProperties(_, _, _, _))
       .WillOnce(
@@ -421,10 +417,9 @@
   std::string profile = "profile path";
   base::DictionaryValue value;
   shill_property_util::SetSSID(networkName, &value);
-  value.SetWithoutPathExpansion(shill::kTypeProperty,
-                                new base::StringValue(type));
+  value.SetWithoutPathExpansion(shill::kTypeProperty, new base::Value(type));
   value.SetWithoutPathExpansion(shill::kProfileProperty,
-                                new base::StringValue(profile));
+                                new base::Value(profile));
 
   EXPECT_CALL(*mock_manager_client_,
               ConfigureServiceForProfile(dbus::ObjectPath(profile), _, _, _))
diff --git a/chromeos/network/network_connect_unittest.cc b/chromeos/network/network_connect_unittest.cc
index d39a9321..0a3cd44 100644
--- a/chromeos/network/network_connect_unittest.cc
+++ b/chromeos/network/network_connect_unittest.cc
@@ -106,9 +106,9 @@
                             "stub_wifi_device1");
     device_test_->AddDevice(kCellular1DevicePath, shill::kTypeCellular,
                             "stub_cellular_device1");
-    device_test_->SetDeviceProperty(
-        kCellular1DevicePath, shill::kTechnologyFamilyProperty,
-        base::StringValue(shill::kNetworkTechnologyGsm));
+    device_test_->SetDeviceProperty(kCellular1DevicePath,
+                                    shill::kTechnologyFamilyProperty,
+                                    base::Value(shill::kNetworkTechnologyGsm));
 
     service_test_ =
         DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
@@ -121,12 +121,11 @@
                               add_to_visible);
     service_test_->SetServiceProperty(kWiFi1ServicePath,
                                       shill::kSecurityClassProperty,
-                                      base::StringValue(shill::kSecurityWep));
+                                      base::Value(shill::kSecurityWep));
     service_test_->SetServiceProperty(
         kWiFi1ServicePath, shill::kConnectableProperty, base::Value(true));
-    service_test_->SetServiceProperty(kWiFi1ServicePath,
-                                      shill::kPassphraseProperty,
-                                      base::StringValue("password"));
+    service_test_->SetServiceProperty(
+        kWiFi1ServicePath, shill::kPassphraseProperty, base::Value("password"));
 
     // Create a cellular network.
     service_test_->AddService(kCellular1ServicePath, kCellular1Guid,
@@ -136,7 +135,7 @@
         kCellular1ServicePath, shill::kConnectableProperty, base::Value(true));
     service_test_->SetServiceProperty(
         kCellular1ServicePath, shill::kActivationStateProperty,
-        base::StringValue(shill::kActivationStateActivated));
+        base::Value(shill::kActivationStateActivated));
     service_test_->SetServiceProperty(kCellular1ServicePath,
                                       shill::kOutOfCreditsProperty,
                                       base::Value(false));
@@ -249,7 +248,7 @@
 
   service_test_->SetServiceProperty(
       kCellular1ServicePath, shill::kActivationStateProperty,
-      base::StringValue(shill::kActivationStateNotActivated));
+      base::Value(shill::kActivationStateNotActivated));
   base::RunLoop().RunUntilIdle();
 
   NetworkConnect::Get()->ConnectToNetworkId(kCellular1Guid);
@@ -260,10 +259,10 @@
 
   service_test_->SetServiceProperty(
       kCellular1ServicePath, shill::kActivationStateProperty,
-      base::StringValue(shill::kActivationStateNotActivated));
+      base::Value(shill::kActivationStateNotActivated));
   service_test_->SetServiceProperty(
       kCellular1ServicePath, shill::kActivationTypeProperty,
-      base::StringValue(shill::kActivationTypeNonCellular));
+      base::Value(shill::kActivationTypeNonCellular));
   base::RunLoop().RunUntilIdle();
 
   NetworkConnect::Get()->ConnectToNetworkId(kCellular1Guid);
diff --git a/chromeos/network/network_state_handler_unittest.cc b/chromeos/network/network_state_handler_unittest.cc
index d62e288..e2784e0 100644
--- a/chromeos/network/network_state_handler_unittest.cc
+++ b/chromeos/network/network_state_handler_unittest.cc
@@ -546,7 +546,7 @@
   ASSERT_TRUE(ethernet);
   EXPECT_EQ("", ethernet->security_class());
   EXPECT_EQ(1, test_observer_->PropertyUpdatesForService(eth1));
-  base::StringValue security_class_value("TestSecurityClass");
+  base::Value security_class_value("TestSecurityClass");
   SetServiceProperty(eth1, shill::kSecurityClassProperty, security_class_value);
   base::RunLoop().RunUntilIdle();
   ethernet = network_state_handler_->GetNetworkState(eth1);
@@ -634,7 +634,7 @@
   EXPECT_EQ(0, test_observer_->ConnectionStateChangesForService(eth1));
 
   // Change a network state.
-  base::StringValue connection_state_idle_value(shill::kStateIdle);
+  base::Value connection_state_idle_value(shill::kStateIdle);
   service_test_->SetServiceProperty(eth1, shill::kStateProperty,
                                    connection_state_idle_value);
   base::RunLoop().RunUntilIdle();
@@ -655,7 +655,7 @@
 
   EXPECT_EQ(0u, test_observer_->default_network_change_count());
   // Disconnect ethernet.
-  base::StringValue connection_state_idle_value(shill::kStateIdle);
+  base::Value connection_state_idle_value(shill::kStateIdle);
   service_test_->SetServiceProperty(eth1, shill::kStateProperty,
                                     connection_state_idle_value);
   base::RunLoop().RunUntilIdle();
@@ -678,7 +678,7 @@
   const std::string wifi1 = kShillManagerClientStubDefaultWifi;
 
   // Disconnect ethernet and wifi.
-  base::StringValue connection_state_idle_value(shill::kStateIdle);
+  base::Value connection_state_idle_value(shill::kStateIdle);
   service_test_->SetServiceProperty(eth1, shill::kStateProperty,
                                     connection_state_idle_value);
   service_test_->SetServiceProperty(wifi1, shill::kStateProperty,
@@ -688,7 +688,7 @@
 
   // Connect ethernet, should become the default network.
   test_observer_->reset_change_counts();
-  base::StringValue connection_state_ready_value(shill::kStateReady);
+  base::Value connection_state_ready_value(shill::kStateReady);
   service_test_->SetServiceProperty(eth1, shill::kStateProperty,
                                     connection_state_ready_value);
   base::RunLoop().RunUntilIdle();
@@ -708,9 +708,9 @@
   // DefaultService property changes.
   const std::string wifi1 = kShillManagerClientStubDefaultWifi;
   SetServiceProperty(eth1, shill::kStateProperty,
-                     base::StringValue(shill::kStateIdle));
+                     base::Value(shill::kStateIdle));
   manager_test_->SetManagerProperty(shill::kDefaultServiceProperty,
-                                    base::StringValue(wifi1));
+                                    base::Value(wifi1));
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(wifi1, test_observer_->default_network());
   EXPECT_EQ(1u, test_observer_->default_network_change_count());
@@ -719,7 +719,7 @@
   // default network notification.
   test_observer_->reset_change_counts();
   service_test_->SetServiceProperty(wifi1, shill::kStateProperty,
-                                    base::StringValue(shill::kStateReady));
+                                    base::Value(shill::kStateReady));
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(shill::kStateReady,
             test_observer_->default_network_connection_state());
@@ -729,7 +729,7 @@
   // a default network change.
   test_observer_->reset_change_counts();
   SetServiceProperty(wifi1, shill::kSecurityClassProperty,
-                     base::StringValue("TestSecurityClass"));
+                     base::Value("TestSecurityClass"));
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(1u, test_observer_->default_network_change_count());
 
@@ -744,19 +744,19 @@
   // fire once when the network is connected.
   test_observer_->reset_change_counts();
   SetServiceProperty(wifi1, shill::kStateProperty,
-                     base::StringValue(shill::kStateIdle));
+                     base::Value(shill::kStateIdle));
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(1u, test_observer_->default_network_change_count());
   EXPECT_EQ(std::string(), test_observer_->default_network());
 
   const std::string wifi2 = kShillManagerClientStubWifi2;
   manager_test_->SetManagerProperty(shill::kDefaultServiceProperty,
-                                    base::StringValue(wifi2));
+                                    base::Value(wifi2));
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(1u, test_observer_->default_network_change_count());
   // Change the connection state of the default network, observer should fire.
   SetServiceProperty(wifi2, shill::kStateProperty,
-                     base::StringValue(shill::kStateReady));
+                     base::Value(shill::kStateReady));
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(wifi2, test_observer_->default_network());
   EXPECT_EQ(2u, test_observer_->default_network_change_count());
@@ -878,9 +878,9 @@
   device_test_->SetDeviceProperty(
       kShillManagerClientStubWifiDevice, shill::kIPConfigsProperty,
       device_ip_configs);
-  service_test_->SetServiceProperty(
-      kShillManagerClientStubDefaultWifi, shill::kIPConfigProperty,
-      base::StringValue(kIPConfigPath));
+  service_test_->SetServiceProperty(kShillManagerClientStubDefaultWifi,
+                                    shill::kIPConfigProperty,
+                                    base::Value(kIPConfigPath));
   UpdateManagerProperties();
   EXPECT_EQ(1, test_observer_->PropertyUpdatesForDevice(
       kShillManagerClientStubWifiDevice));
diff --git a/chromeos/network/onc/onc_translator_onc_to_shill.cc b/chromeos/network/onc/onc_translator_onc_to_shill.cc
index 606fe32..39e75c9 100644
--- a/chromeos/network/onc/onc_translator_onc_to_shill.cc
+++ b/chromeos/network/onc/onc_translator_onc_to_shill.cc
@@ -31,12 +31,11 @@
 
 namespace {
 
-std::unique_ptr<base::StringValue> ConvertValueToString(
-    const base::Value& value) {
+std::unique_ptr<base::Value> ConvertValueToString(const base::Value& value) {
   std::string str;
   if (!value.GetAsString(&str))
     base::JSONWriter::Write(value, &str);
-  return base::MakeUnique<base::StringValue>(str);
+  return base::MakeUnique<base::Value>(str);
 }
 
 // This class is responsible to translate the local fields of the given
diff --git a/chromeos/network/onc/onc_translator_shill_to_onc.cc b/chromeos/network/onc/onc_translator_shill_to_onc.cc
index d923b5d..ce403666 100644
--- a/chromeos/network/onc/onc_translator_shill_to_onc.cc
+++ b/chromeos/network/onc/onc_translator_shill_to_onc.cc
@@ -33,7 +33,7 @@
                                                   base::Value::Type type) {
   std::unique_ptr<base::Value> value;
   if (type == base::Value::Type::STRING) {
-    value.reset(new base::StringValue(str));
+    value.reset(new base::Value(str));
   } else {
     value = base::JSONReader::Read(str);
   }
diff --git a/chromeos/network/onc/onc_utils.cc b/chromeos/network/onc/onc_utils.cc
index 4f956c4..a2c2d32 100644
--- a/chromeos/network/onc/onc_utils.cc
+++ b/chromeos/network/onc/onc_utils.cc
@@ -353,7 +353,7 @@
       bool* found_unknown_field,
       bool* error) override {
     if (FieldIsCredential(object_signature, field_name)) {
-      return std::unique_ptr<base::Value>(new base::StringValue(mask_));
+      return std::unique_ptr<base::Value>(new base::Value(mask_));
     } else {
       return Mapper::MapField(field_name, object_signature, onc_value,
                               found_unknown_field, error);
@@ -790,8 +790,8 @@
 
   const base::ListValue* recommended_keys = nullptr;
   return (onc->GetList(recommended_property_key, &recommended_keys) &&
-          recommended_keys->Find(base::StringValue(property_basename)) !=
-          recommended_keys->end());
+          recommended_keys->Find(base::Value(property_basename)) !=
+              recommended_keys->end());
 }
 
 namespace {
diff --git a/chromeos/network/proxy/proxy_config_handler.cc b/chromeos/network/proxy/proxy_config_handler.cc
index cc3a276..ed96a8b3 100644
--- a/chromeos/network/proxy/proxy_config_handler.cc
+++ b/chromeos/network/proxy/proxy_config_handler.cc
@@ -115,7 +115,7 @@
     base::JSONWriter::Write(proxy_config.GetDictionary(), &proxy_config_str);
     shill_service_client->SetProperty(
         dbus::ObjectPath(network.path()), shill::kProxyConfigProperty,
-        base::StringValue(proxy_config_str),
+        base::Value(proxy_config_str),
         base::Bind(&NotifyNetworkStateHandler, network.path()),
         base::Bind(&network_handler::ShillErrorCallbackFunction,
                    "SetProxyConfig.SetProperty Failed", network.path(),
diff --git a/chromeos/network/shill_property_handler.cc b/chromeos/network/shill_property_handler.cc
index d913d30..74ea70a 100644
--- a/chromeos/network/shill_property_handler.cc
+++ b/chromeos/network/shill_property_handler.cc
@@ -202,7 +202,7 @@
   // Send updated prohibited technology list to shill.
   const std::string prohibited_list =
       base::JoinString(prohibited_technologies, ",");
-  base::StringValue value(prohibited_list);
+  base::Value value(prohibited_list);
   shill_manager_->SetProperty(
       "ProhibitedTechnologies", value, base::Bind(&base::DoNothing),
       base::Bind(&network_handler::ShillErrorCallbackFunction,
@@ -212,7 +212,7 @@
 
 void ShillPropertyHandler::SetCheckPortalList(
     const std::string& check_portal_list) {
-  base::StringValue value(check_portal_list);
+  base::Value value(check_portal_list);
   shill_manager_->SetProperty(
       shill::kCheckPortalListProperty, value, base::Bind(&base::DoNothing),
       base::Bind(&network_handler::ShillErrorCallbackFunction,
diff --git a/chromeos/network/shill_property_handler_unittest.cc b/chromeos/network/shill_property_handler_unittest.cc
index 35d8c74..0778663 100644
--- a/chromeos/network/shill_property_handler_unittest.cc
+++ b/chromeos/network/shill_property_handler_unittest.cc
@@ -420,7 +420,7 @@
   // Set the properties for an IP Config object.
   const std::string kTestIPConfigPath("test_ip_config_path");
 
-  base::StringValue ip_address("192.168.1.1");
+  base::Value ip_address("192.168.1.1");
   DBusThreadManager::Get()->GetShillIPConfigClient()->SetProperty(
       dbus::ObjectPath(kTestIPConfigPath),
       shill::kAddressProperty, ip_address,
@@ -437,7 +437,7 @@
       dbus::ObjectPath(kTestIPConfigPath),
       shill::kPrefixlenProperty, prefixlen,
       base::Bind(&DoNothingWithCallStatus));
-  base::StringValue gateway("192.0.0.1");
+  base::Value gateway("192.0.0.1");
   DBusThreadManager::Get()->GetShillIPConfigClient()->SetProperty(
       dbus::ObjectPath(kTestIPConfigPath),
       shill::kGatewayProperty, gateway,
@@ -453,10 +453,9 @@
   EXPECT_EQ(1, listener_->initial_property_updates(
       shill::kServiceCompleteListProperty)[kTestServicePath1]);
   DBusThreadManager::Get()->GetShillServiceClient()->SetProperty(
-      dbus::ObjectPath(kTestServicePath1),
-      shill::kIPConfigProperty,
-      base::StringValue(kTestIPConfigPath),
-      base::Bind(&base::DoNothing), base::Bind(&ErrorCallbackFunction));
+      dbus::ObjectPath(kTestServicePath1), shill::kIPConfigProperty,
+      base::Value(kTestIPConfigPath), base::Bind(&base::DoNothing),
+      base::Bind(&ErrorCallbackFunction));
   base::RunLoop().RunUntilIdle();
   // IPConfig property change on the service should trigger an IPConfigs update.
   EXPECT_EQ(1, listener_->property_updates(
diff --git a/components/arc/bluetooth/bluetooth_type_converters_unittest.cc b/components/arc/bluetooth/bluetooth_type_converters_unittest.cc
index c89ad8a..7971556 100644
--- a/components/arc/bluetooth/bluetooth_type_converters_unittest.cc
+++ b/components/arc/bluetooth/bluetooth_type_converters_unittest.cc
@@ -362,7 +362,7 @@
   std::string actualUUID;
   auto uuidAttributeBlueZ = bluez::BluetoothServiceAttributeValueBlueZ(
       bluez::BluetoothServiceAttributeValueBlueZ::UUID, sizeof(uint16_t),
-      base::MakeUnique<base::StringValue>(valueUUID));
+      base::MakeUnique<base::Value>(valueUUID));
 
   auto uuidAttributeMojo =
       ConvertTo<arc::mojom::BluetoothSdpAttributePtr>(uuidAttributeBlueZ);
@@ -379,7 +379,7 @@
   std::string actualString;
   auto stringAttributeBlueZ = bluez::BluetoothServiceAttributeValueBlueZ(
       bluez::BluetoothServiceAttributeValueBlueZ::STRING, valueString.length(),
-      base::MakeUnique<base::StringValue>(valueString));
+      base::MakeUnique<base::Value>(valueString));
 
   auto stringAttributeMojo =
       ConvertTo<arc::mojom::BluetoothSdpAttributePtr>(stringAttributeBlueZ);
@@ -400,7 +400,7 @@
       sequence(new bluez::BluetoothServiceAttributeValueBlueZ::Sequence());
   sequence->push_back(bluez::BluetoothServiceAttributeValueBlueZ(
       bluez::BluetoothServiceAttributeValueBlueZ::UUID, sizeof(uint16_t),
-      base::MakeUnique<base::StringValue>(l2capUUID)));
+      base::MakeUnique<base::Value>(l2capUUID)));
   sequence->push_back(bluez::BluetoothServiceAttributeValueBlueZ(
       bluez::BluetoothServiceAttributeValueBlueZ::UINT, sizeof(uint16_t),
       base::MakeUnique<base::Value>(l2capChannel)));
diff --git a/components/autofill/content/renderer/password_form_conversion_utils.cc b/components/autofill/content/renderer/password_form_conversion_utils.cc
index 3aa8e5b3..b92ff5f 100644
--- a/components/autofill/content/renderer/password_form_conversion_utils.cc
+++ b/components/autofill/content/renderer/password_form_conversion_utils.cc
@@ -680,10 +680,11 @@
   SyntheticForm synthetic_form;
   PopulateSyntheticFormFromWebForm(web_form, &synthetic_form);
 
-  WebFormElementToFormData(web_form, blink::WebFormControlElement(),
-                           field_value_and_properties_map,
-                           form_util::EXTRACT_NONE, &password_form->form_data,
-                           NULL /* FormFieldData */);
+  if (!WebFormElementToFormData(
+          web_form, blink::WebFormControlElement(),
+          field_value_and_properties_map, form_util::EXTRACT_NONE,
+          &password_form->form_data, NULL /* FormFieldData */))
+    return std::unique_ptr<PasswordForm>();
 
   if (!GetPasswordForm(synthetic_form, password_form.get(),
                        field_value_and_properties_map, form_predictions))
@@ -705,10 +706,12 @@
     return std::unique_ptr<PasswordForm>();
 
   std::unique_ptr<PasswordForm> password_form(new PasswordForm());
-  UnownedPasswordFormElementsAndFieldSetsToFormData(
-      synthetic_form.fieldsets, synthetic_form.control_elements, nullptr,
-      frame.document(), field_value_and_properties_map, form_util::EXTRACT_NONE,
-      &password_form->form_data, nullptr /* FormFieldData */);
+  if (!UnownedPasswordFormElementsAndFieldSetsToFormData(
+          synthetic_form.fieldsets, synthetic_form.control_elements, nullptr,
+          frame.document(), field_value_and_properties_map,
+          form_util::EXTRACT_NONE, &password_form->form_data,
+          nullptr /* FormFieldData */))
+    return std::unique_ptr<PasswordForm>();
   if (!GetPasswordForm(synthetic_form, password_form.get(),
                        field_value_and_properties_map, form_predictions))
     return std::unique_ptr<PasswordForm>();
diff --git a/components/autofill/content/renderer/password_form_conversion_utils_browsertest.cc b/components/autofill/content/renderer/password_form_conversion_utils_browsertest.cc
index ead2796..3a3ac4b 100644
--- a/components/autofill/content/renderer/password_form_conversion_utils_browsertest.cc
+++ b/components/autofill/content/renderer/password_form_conversion_utils_browsertest.cc
@@ -1470,4 +1470,13 @@
   EXPECT_FALSE(password_form->does_look_like_signup_form);
 }
 
+TEST_F(MAYBE_PasswordFormConversionUtilsTest, TooManyFieldsToParseForm) {
+  PasswordFormBuilder builder(kTestFormActionURL);
+  for (size_t i = 0; i < form_util::kMaxParseableFields + 1; ++i)
+    builder.AddTextField("id", "value", "autocomplete");
+  std::unique_ptr<PasswordForm> password_form =
+      LoadHTMLAndConvertForm(builder.ProduceHTML(), nullptr, false);
+  EXPECT_FALSE(password_form);
+}
+
 }  // namespace autofill
diff --git a/components/autofill/content/renderer/renderer_save_password_progress_logger.cc b/components/autofill/content/renderer/renderer_save_password_progress_logger.cc
index bd71dbc..361552614 100644
--- a/components/autofill/content/renderer/renderer_save_password_progress_logger.cc
+++ b/components/autofill/content/renderer/renderer_save_password_progress_logger.cc
@@ -25,8 +25,8 @@
 void RendererSavePasswordProgressLogger::LogElementName(
     StringID label,
     const blink::WebFormControlElement& element) {
-  LogValue(label, base::StringValue(
-                      ScrubElementID((element.nameForAutofill().utf16()))));
+  LogValue(label,
+           base::Value(ScrubElementID((element.nameForAutofill().utf16()))));
 }
 
 }  // namespace autofill
diff --git a/components/autofill/core/common/save_password_progress_logger.cc b/components/autofill/core/common/save_password_progress_logger.cc
index 5fc676c..73be9b49 100644
--- a/components/autofill/core/common/save_password_progress_logger.cc
+++ b/components/autofill/core/common/save_password_progress_logger.cc
@@ -18,7 +18,6 @@
 using base::checked_cast;
 using base::Value;
 using base::DictionaryValue;
-using base::StringValue;
 
 namespace autofill {
 
@@ -94,7 +93,7 @@
 void SavePasswordProgressLogger::LogURL(
     SavePasswordProgressLogger::StringID label,
     const GURL& url) {
-  LogValue(label, StringValue(ScrubURL(url)));
+  LogValue(label, Value(ScrubURL(url)));
 }
 
 void SavePasswordProgressLogger::LogBoolean(
@@ -117,7 +116,7 @@
 
 void SavePasswordProgressLogger::LogMessage(
     SavePasswordProgressLogger::StringID message) {
-  LogValue(STRING_MESSAGE, StringValue(GetStringFromID(message)));
+  LogValue(STRING_MESSAGE, Value(GetStringFromID(message)));
 }
 
 // static
@@ -144,7 +143,7 @@
 // static
 std::string SavePasswordProgressLogger::ScrubElementID(std::string element_id) {
   std::replace_if(element_id.begin(), element_id.end(), IsUnwantedInElementID,
-                  ' ');
+                  '_');
   return element_id;
 }
 
diff --git a/components/autofill/core/common/save_password_progress_logger_unittest.cc b/components/autofill/core/common/save_password_progress_logger_unittest.cc
index f047183d..a20d119 100644
--- a/components/autofill/core/common/save_password_progress_logger_unittest.cc
+++ b/components/autofill/core/common/save_password_progress_logger_unittest.cc
@@ -63,11 +63,11 @@
   TestLogger logger;
   PasswordForm form;
   const std::string kHTMLInside("Username <script> element");
-  const std::string kHTMLInsideExpected("Username  script  element");
+  const std::string kHTMLInsideExpected("Username__script__element");
   const std::string kIPAddressInside("y128.0.0.1Y");
-  const std::string kIPAddressInsideExpected("y128 0 0 1Y");
+  const std::string kIPAddressInsideExpected("y128_0_0_1Y");
   const std::string kSpecialCharsInside("X@#a$%B&*c()D;:e+!x");
-  const std::string kSpecialCharsInsideExpected("X  a  B  c  D  e  x");
+  const std::string kSpecialCharsInsideExpected("X__a__B__c__D__e__x");
   form.username_element = UTF8ToUTF16(kHTMLInside);
   form.password_element = UTF8ToUTF16(kIPAddressInside);
   form.new_password_element = UTF8ToUTF16(kSpecialCharsInside);
diff --git a/components/bookmarks/browser/bookmark_codec.cc b/components/bookmarks/browser/bookmark_codec.cc
index 38a3784..abbb1cd 100644
--- a/components/bookmarks/browser/bookmark_codec.cc
+++ b/components/bookmarks/browser/bookmark_codec.cc
@@ -89,7 +89,7 @@
   // We are going to store the computed checksum. So set stored checksum to be
   // the same as computed checksum.
   stored_checksum_ = computed_checksum_;
-  main->Set(kChecksumKey, new base::StringValue(computed_checksum_));
+  main->Set(kChecksumKey, new base::Value(computed_checksum_));
   main->Set(kRootsKey, roots);
   return main;
 }
diff --git a/components/bookmarks/browser/bookmark_expanded_state_tracker.cc b/components/bookmarks/browser/bookmark_expanded_state_tracker.cc
index 427f2d3..c08d8335 100644
--- a/components/bookmarks/browser/bookmark_expanded_state_tracker.cc
+++ b/components/bookmarks/browser/bookmark_expanded_state_tracker.cc
@@ -107,7 +107,7 @@
   base::ListValue values;
   for (Nodes::const_iterator i = nodes.begin(); i != nodes.end(); ++i) {
     values.Set(values.GetSize(),
-               new base::StringValue(base::Int64ToString((*i)->id())));
+               new base::Value(base::Int64ToString((*i)->id())));
   }
 
   pref_service_->Set(prefs::kBookmarkEditorExpandedNodes, values);
diff --git a/components/browsing_data_strings.grdp b/components/browsing_data_strings.grdp
index 9de1c82..744a4e6 100644
--- a/components/browsing_data_strings.grdp
+++ b/components/browsing_data_strings.grdp
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
 <grit-part>
-  
   <!-- Clear Browsing Data counters-->
   <message name="IDS_CLEAR_BROWSING_DATA_CALCULATING" desc="A text that is shown while the data volume is being counted.">
     Calculating...
@@ -66,6 +65,12 @@
   <message name="IDS_DEL_COOKIES_COUNTER" desc="A static message shown in the Clear Browsing Data dialog explaining to the user that deleting cookies and site data will result in the user being signed out of most websites.">
     This will sign you out of most websites.
   </message>
+  <message name="IDS_DEL_COOKIES_COUNTER_ADVANCED" desc="A counter showing the number of sites that use cookies.">
+    {COUNT, plural,
+      =0 {No cookies}
+      =1 {1 site uses cookies. }
+      other {# sites use cookies. }}
+  </message>
   <message name="IDS_DEL_DOWNLOADS_COUNTER" desc="A counter showing how many items of downloads history the user has.">
     {COUNT, plural,
      =0 {none}
@@ -90,4 +95,4 @@
   <message name="IDS_DEL_MEDIA_LICENSES_COUNTER_SITE_COMMENT" desc="A message shown in the Clear Browsing Data dialog explaining to the user that clearing media licenses will result in the user being unable to play some premium content from at least one specific web site">
      You may lose access to premium content from <ph name="SITE">$1<ex>youtube.com</ex></ph> and some other sites.
   </message>
-</grit-part>
\ No newline at end of file
+</grit-part>
diff --git a/components/cronet/android/BUILD.gn b/components/cronet/android/BUILD.gn
index a6b7b52..22f3648 100644
--- a/components/cronet/android/BUILD.gn
+++ b/components/cronet/android/BUILD.gn
@@ -1271,17 +1271,15 @@
 
 action("cronet_combine_proguard_flags") {
   script = "//components/cronet/tools/generate_proguard_file.py"
+  sources = [
+    "//base/android/proguard/chromium_code.flags",
+    "//components/cronet/android/cronet_impl_native_proguard.cfg",
+  ]
   outputs = [
     "$target_gen_dir/cronet_impl_native_proguard.cfg",
   ]
-  args = [
-    "--output-file",
-    rebase_path("$target_gen_dir/cronet_impl_native_proguard.cfg",
-                root_build_dir),
-    rebase_path("//components/cronet/android/cronet_impl_native_proguard.cfg",
-                root_build_dir),
-    rebase_path("//base/android/proguard/chromium_code.flags", root_build_dir),
-  ]
+  args = [ "--output-file" ] + rebase_path(outputs, root_build_dir) +
+         rebase_path(sources, root_build_dir)
 }
 
 copy("cronet_package_copy_native_lib") {
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc
index 5d4b87c9..4d765d8 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc
@@ -76,7 +76,7 @@
                         int64_t length,
                         base::ListValue* list_update) {
   int64_t value = GetInt64PrefValue(*list_update, index) + length;
-  list_update->Set(index, new base::StringValue(base::Int64ToString(value)));
+  list_update->Set(index, new base::Value(base::Int64ToString(value)));
 }
 
 // DailyContentLengthUpdate maintains a data saving pref. The pref is a list
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats_unittest.cc
index cadbcd3c..05ac2c9 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats_unittest.cc
@@ -163,13 +163,13 @@
 
     for (size_t i = 0; i < kNumDaysInHistory; ++i) {
       original_daily_content_length_list->Set(
-          i, new base::StringValue(base::SizeTToString(i)));
+          i, new base::Value(base::SizeTToString(i)));
     }
 
     received_daily_content_length_list->Clear();
     for (size_t i = 0; i < kNumDaysInHistory / 2; ++i) {
       received_daily_content_length_list->Set(
-          i, new base::StringValue(base::SizeTToString(i)));
+          i, new base::Value(base::SizeTToString(i)));
     }
   }
 
@@ -178,8 +178,7 @@
     base::ListValue* update = compression_stats_->GetList(pref);
     update->Clear();
     for (size_t i = 0; i < kNumDaysInHistory; ++i) {
-      update->Insert(
-          0, base::MakeUnique<base::StringValue>(base::Int64ToString(0)));
+      update->Insert(0, base::MakeUnique<base::Value>(base::Int64ToString(0)));
     }
   }
 
@@ -544,8 +543,8 @@
 
 TEST_F(DataReductionProxyCompressionStatsTest, StatsRestoredOnOnRestart) {
   base::ListValue list_value;
-  list_value.Insert(
-      0, base::MakeUnique<base::StringValue>(base::Int64ToString(1234)));
+  list_value.Insert(0,
+                    base::MakeUnique<base::Value>(base::Int64ToString(1234)));
   pref_service()->Set(prefs::kDailyHttpOriginalContentLength, list_value);
 
   ResetCompressionStatsWithDelay(
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc
index 8bae820..aaf790f 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc
@@ -19,12 +19,14 @@
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options.h"
 #include "components/data_reduction_proxy/core/browser/data_use_group.h"
 #include "components/data_reduction_proxy/core/browser/data_use_group_provider.h"
+#include "components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h"
 #include "components/data_reduction_proxy/core/common/data_reduction_proxy_util.h"
 #include "components/data_reduction_proxy/core/common/lofi_decider.h"
 #include "net/base/load_flags.h"
 #include "net/http/http_request_headers.h"
 #include "net/http/http_response_headers.h"
+#include "net/nqe/effective_connection_type.h"
 #include "net/nqe/network_quality_estimator.h"
 #include "net/proxy/proxy_info.h"
 #include "net/proxy/proxy_server.h"
@@ -194,6 +196,8 @@
         ->MaybeSetAcceptTransformHeader(
             *request, data_reduction_proxy_config_->lofi_off(), headers);
   }
+
+  MaybeAddChromeProxyECTHeader(headers, *request);
 }
 
 void DataReductionProxyNetworkDelegate::OnBeforeSendHeadersInternal(
@@ -241,6 +245,7 @@
       // Chrome-Proxy-Accept-Transform header.
       lofi_decider->RemoveAcceptTransformHeader(headers);
     }
+    RemoveChromeProxyECTHeader(headers);
     return;
   }
 
@@ -498,4 +503,47 @@
                              header_value);
 }
 
+void DataReductionProxyNetworkDelegate::MaybeAddChromeProxyECTHeader(
+    net::HttpRequestHeaders* request_headers,
+    const net::URLRequest& request) const {
+  DCHECK(thread_checker_.CalledOnValidThread());
+
+  // This method should be called only when the resolved proxy was a data
+  // saver proxy.
+  DCHECK(request.url().is_valid());
+  DCHECK(!request.url().SchemeIsCryptographic());
+  DCHECK(request.url().SchemeIsHTTPOrHTTPS());
+
+  if (!params::IsAddChromeProxyECTHeaderEnabled())
+    return;
+
+  DCHECK(!request_headers->HasHeader(chrome_proxy_ect_header()));
+
+  if (!request.context()->network_quality_estimator())
+    return;
+
+  net::EffectiveConnectionType ect = request.context()
+                                         ->network_quality_estimator()
+                                         ->GetEffectiveConnectionType();
+  if (ect <= net::EFFECTIVE_CONNECTION_TYPE_OFFLINE)
+    return;
+
+  static_assert(net::EFFECTIVE_CONNECTION_TYPE_OFFLINE + 1 ==
+                    net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G,
+                "ECT enum value is not handled.");
+  static_assert(net::EFFECTIVE_CONNECTION_TYPE_4G + 1 ==
+                    net::EFFECTIVE_CONNECTION_TYPE_LAST,
+                "ECT enum value is not handled.");
+
+  request_headers->SetHeader(chrome_proxy_ect_header(),
+                             net::GetNameForEffectiveConnectionType(ect));
+}
+
+void DataReductionProxyNetworkDelegate::RemoveChromeProxyECTHeader(
+    net::HttpRequestHeaders* request_headers) const {
+  DCHECK(thread_checker_.CalledOnValidThread());
+
+  request_headers->RemoveHeader(chrome_proxy_ect_header());
+}
+
 }  // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.h
index f36cea45..f32107b 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.h
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.h
@@ -157,6 +157,17 @@
       net::HttpRequestHeaders* request_headers,
       const net::URLRequest& request) const;
 
+  // May add chrome-proxy-ect header to |request_headers| if adding of
+  // chrome-proxy-ect is enabled via field trial and a valid estimate of
+  // network quality is available. This method should be called only when the
+  // resolved proxy for |request| is a data saver proxy.
+  void MaybeAddChromeProxyECTHeader(net::HttpRequestHeaders* request_headers,
+                                    const net::URLRequest& request) const;
+
+  // Removes the chrome-proxy-ect header from |request_headers|.
+  void RemoveChromeProxyECTHeader(
+      net::HttpRequestHeaders* request_headers) const;
+
   // All raw Data Reduction Proxy pointers must outlive |this|.
   DataReductionProxyConfig* data_reduction_proxy_config_;
 
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc
index 028c43e..0153127 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc
@@ -180,7 +180,13 @@
 class DataReductionProxyNetworkDelegateTest : public testing::Test {
  public:
   DataReductionProxyNetworkDelegateTest()
-      : context_(true), context_storage_(&context_) {}
+      : context_(true),
+        context_storage_(&context_),
+        ssl_socket_data_provider_(net::ASYNC, net::OK) {
+    ssl_socket_data_provider_.next_proto = net::kProtoHTTP11;
+    ssl_socket_data_provider_.cert = net::ImportCertFromFile(
+        net::GetTestCertsDirectory(), "unittest.selfsigned.der");
+  }
 
   void Init(bool use_secure_proxy, bool enable_brotli_globally) {
     net::ProxyServer proxy_server =
@@ -213,11 +219,85 @@
     test_context_->io_data()->set_lofi_ui_service(std::move(lofi_ui_service));
 
     context_.set_enable_brotli(enable_brotli_globally);
+    context_.set_network_quality_estimator(&test_network_quality_estimator_);
     context_.Init();
 
     test_context_->EnableDataReductionProxyWithSecureProxyCheckSuccess();
   }
 
+  // Build the sockets by adding appropriate mock data for
+  // |effective_connection_types.size()| number of requests. Data for
+  // chrome-Proxy-ect header is added to the mock data if |expect_ect_header|
+  // is true. |reads_list|, |mock_writes| and |writes_list| should be empty, and
+  // are owned by the caller.
+  void BuildSocket(const std::string& response_headers,
+                   const std::string& response_body,
+                   bool expect_ect_header,
+                   const std::vector<net::EffectiveConnectionType>&
+                       effective_connection_types,
+                   std::vector<net::MockRead>* reads_list,
+                   std::vector<std::string>* mock_writes,
+                   std::vector<net::MockWrite>* writes_list) {
+    EXPECT_LT(0u, effective_connection_types.size());
+    EXPECT_TRUE(reads_list->empty());
+    EXPECT_TRUE(mock_writes->empty());
+    EXPECT_TRUE(writes_list->empty());
+
+    for (size_t i = 0; i < effective_connection_types.size(); ++i) {
+      reads_list->push_back(net::MockRead(response_headers.c_str()));
+      reads_list->push_back(net::MockRead(response_body.c_str()));
+    }
+    reads_list->push_back(net::MockRead(net::SYNCHRONOUS, net::OK));
+
+    std::string prefix = std::string("GET ")
+                             .append(kTestURL)
+                             .append(" HTTP/1.1\r\n")
+                             .append("Host: ")
+                             .append(GURL(kTestURL).host())
+                             .append(
+                                 "\r\n"
+                                 "Proxy-Connection: keep-alive\r\n"
+                                 "User-Agent:\r\n"
+                                 "Accept-Encoding: gzip, deflate\r\n"
+                                 "Accept-Language: en-us,fr\r\n");
+
+    if (io_data()->test_request_options()->GetHeaderValueForTesting().empty()) {
+      // Force regeneration of Chrome-Proxy header.
+      io_data()->test_request_options()->SetSecureSession("123");
+    }
+
+    EXPECT_FALSE(
+        io_data()->test_request_options()->GetHeaderValueForTesting().empty());
+
+    std::string suffix =
+        std::string("Chrome-Proxy: ") +
+        io_data()->test_request_options()->GetHeaderValueForTesting() +
+        std::string("\r\n\r\n");
+
+    mock_socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data_provider_);
+
+    for (net::EffectiveConnectionType effective_connection_type :
+         effective_connection_types) {
+      std::string ect_header;
+      if (expect_ect_header) {
+        ect_header = "chrome-proxy-ect: " +
+                     std::string(net::GetNameForEffectiveConnectionType(
+                         effective_connection_type)) +
+                     "\r\n";
+      }
+
+      std::string mock_write = prefix + ect_header + suffix;
+      mock_writes->push_back(mock_write);
+      writes_list->push_back(net::MockWrite(mock_writes->back().c_str()));
+    }
+
+    EXPECT_FALSE(socket_);
+    socket_ = base::MakeUnique<net::StaticSocketDataProvider>(
+        reads_list->data(), reads_list->size(), writes_list->data(),
+        writes_list->size());
+    mock_socket_factory_.AddSocketDataProvider(socket_.get());
+  }
+
   static void VerifyHeaders(bool expected_data_reduction_proxy_used,
                             bool expected_lofi_used,
                             const net::HttpRequestHeaders& headers) {
@@ -285,16 +365,12 @@
                                       bool expect_cached,
                                       bool expect_brotli) {
     GURL url(kTestURL);
-    net::SSLSocketDataProvider ssl_socket_data_provider(net::ASYNC, net::OK);
 
     int response_body_size = 140;
     const std::string response_body(
         base::checked_cast<size_t>(response_body_size), ' ');
 
-    ssl_socket_data_provider.next_proto = net::kProtoHTTP11;
-    ssl_socket_data_provider.cert = net::ImportCertFromFile(
-        net::GetTestCertsDirectory(), "unittest.selfsigned.der");
-    mock_socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data_provider);
+    mock_socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data_provider_);
 
     net::MockRead reads[] = {net::MockRead(response_headers.c_str()),
                              net::MockRead(response_body.c_str()),
@@ -386,6 +462,53 @@
     }
   }
 
+  // Fetches a request while the effective connection type is set to
+  // |effective_connection_type|. Verifies that the request headers include the
+  // chrome-proxy-ect header only if |expect_ect_header| is true. The response
+  // must be served from the cache if |expect_cached| is true.
+  void FetchURLRequestAndVerifyECTHeader(
+      net::EffectiveConnectionType effective_connection_type,
+      bool expect_ect_header,
+      bool expect_cached) {
+    EXPECT_EQ(expect_ect_header, params::IsAddChromeProxyECTHeaderEnabled());
+
+    test_network_quality_estimator()->set_effective_connection_type(
+        effective_connection_type);
+
+    net::TestDelegate delegate;
+    std::unique_ptr<net::URLRequest> request =
+        context_.CreateRequest(GURL(kTestURL), net::IDLE, &delegate);
+
+    request->Start();
+    base::RunLoop().RunUntilIdle();
+
+    EXPECT_EQ(140, request->received_response_content_length());
+    EXPECT_EQ(expect_cached, request->was_cached());
+    EXPECT_EQ(expect_cached, request->GetTotalSentBytes() == 0);
+    EXPECT_EQ(expect_cached, request->GetTotalReceivedBytes() == 0);
+
+    net::HttpRequestHeaders sent_request_headers;
+    EXPECT_NE(expect_cached,
+              request->GetFullRequestHeaders(&sent_request_headers));
+
+    if (expect_cached) {
+      // Request headers are missing. Return since there is nothing left to
+      // check.
+      return;
+    }
+
+    // Verify that chrome-proxy-ect header is present in the request headers
+    // only if |expect_ect_header| is true.
+    std::string ect_value;
+    EXPECT_EQ(expect_ect_header, sent_request_headers.GetHeader(
+                                     chrome_proxy_ect_header(), &ect_value));
+
+    if (!expect_ect_header)
+      return;
+    EXPECT_EQ(net::GetNameForEffectiveConnectionType(effective_connection_type),
+              ect_value);
+  }
+
   void DelegateStageDone(int result) {}
 
   void NotifyNetworkDelegate(net::URLRequest* request,
@@ -430,6 +553,10 @@
 
   TestLoFiDecider* lofi_decider() const { return lofi_decider_; }
 
+  net::TestNetworkQualityEstimator* test_network_quality_estimator() {
+    return &test_network_quality_estimator_;
+  }
+
  private:
   base::MessageLoopForIO message_loop_;
   net::MockClientSocketFactory mock_socket_factory_;
@@ -440,6 +567,11 @@
   TestLoFiDecider* lofi_decider_;
   TestLoFiUIService* lofi_ui_service_;
   std::unique_ptr<DataReductionProxyTestContext> test_context_;
+  net::TestNetworkQualityEstimator test_network_quality_estimator_;
+
+  net::SSLSocketDataProvider ssl_socket_data_provider_;
+
+  std::unique_ptr<net::StaticSocketDataProvider> socket_;
 };
 
 TEST_F(DataReductionProxyNetworkDelegateTest, AuthenticationTest) {
@@ -655,10 +787,8 @@
     net::HttpRequestHeaders headers;
     net::ProxyRetryInfoMap proxy_retry_info;
 
-    net::TestNetworkQualityEstimator test_network_quality_estimator;
-    test_network_quality_estimator.set_effective_connection_type(
+    test_network_quality_estimator()->set_effective_connection_type(
         net::EFFECTIVE_CONNECTION_TYPE_OFFLINE);
-    context()->set_network_quality_estimator(&test_network_quality_estimator);
 
     std::unique_ptr<net::URLRequest> request = context()->CreateRequest(
         GURL(kTestURL), net::RequestPriority::IDLE, nullptr);
@@ -744,10 +874,8 @@
   net::HttpRequestHeaders headers;
   net::ProxyRetryInfoMap proxy_retry_info;
 
-  net::TestNetworkQualityEstimator test_network_quality_estimator;
-  test_network_quality_estimator.set_effective_connection_type(
+  test_network_quality_estimator()->set_effective_connection_type(
       net::EFFECTIVE_CONNECTION_TYPE_OFFLINE);
-  context()->set_network_quality_estimator(&test_network_quality_estimator);
 
   std::unique_ptr<net::URLRequest> request = context()->CreateRequest(
       GURL(kTestURL), net::RequestPriority::IDLE, nullptr);
@@ -1075,6 +1203,131 @@
   FetchURLRequestAndVerifyBrotli(nullptr, response_headers, true, true);
 }
 
+// Test that effective connection type is correctly added to the request
+// headers when it is enabled using field trial. The server is varying on the
+// effective connection type (ECT).
+TEST_F(DataReductionProxyNetworkDelegateTest, ECTHeaderEnabledWithVary) {
+  Init(true /* use_secure_proxy */, false /* enable_brotli_globally */);
+
+  base::FieldTrialList field_trial_list(nullptr);
+  base::FieldTrialList::CreateFieldTrial(
+      "DataReductionProxyAddChromeProxyECTHeader", "Enabled");
+
+  std::string response_headers =
+      "HTTP/1.1 200 OK\r\n"
+      "Content-Length: 140\r\n"
+      "Via: 1.1 Chrome-Compression-Proxy\r\n"
+      "Cache-Control: max-age=1200\r\n"
+      "Vary: chrome-proxy-ect\r\n"
+      "x-original-content-length: 200\r\n\r\n";
+
+  int response_body_size = 140;
+  std::string response_body(base::checked_cast<size_t>(response_body_size),
+                            ' ');
+
+  std::vector<net::MockRead> reads_list;
+  std::vector<std::string> mock_writes;
+  std::vector<net::MockWrite> writes_list;
+
+  std::vector<net::EffectiveConnectionType> effective_connection_types;
+  effective_connection_types.push_back(net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G);
+  effective_connection_types.push_back(net::EFFECTIVE_CONNECTION_TYPE_2G);
+
+  BuildSocket(response_headers, response_body, true, effective_connection_types,
+              &reads_list, &mock_writes, &writes_list);
+
+  // Add 2 socket providers since 2 requests in this test are fetched from the
+  // network.
+  FetchURLRequestAndVerifyECTHeader(effective_connection_types[0], true, false);
+
+  // When the ECT is set to the same value, fetching the same resource should
+  // result in a cache hit.
+  FetchURLRequestAndVerifyECTHeader(effective_connection_types[0], true, true);
+
+  // When the ECT is set to a different value, the response should not be
+  // served from the cache.
+  FetchURLRequestAndVerifyECTHeader(effective_connection_types[1], true, false);
+}
+
+// Test that effective connection type is correctly added to the request
+// headers when it is enabled using field trial. The server is not varying on
+// the effective connection type (ECT).
+TEST_F(DataReductionProxyNetworkDelegateTest, ECTHeaderEnabledWithoutVary) {
+  Init(true /* use_secure_proxy */, false /* enable_brotli_globally */);
+
+  base::FieldTrialList field_trial_list(nullptr);
+  base::FieldTrialList::CreateFieldTrial(
+      "DataReductionProxyAddChromeProxyECTHeader", "Enabled");
+
+  std::string response_headers =
+      "HTTP/1.1 200 OK\r\n"
+      "Content-Length: 140\r\n"
+      "Via: 1.1 Chrome-Compression-Proxy\r\n"
+      "Cache-Control: max-age=1200\r\n"
+      "x-original-content-length: 200\r\n\r\n";
+
+  int response_body_size = 140;
+  std::string response_body(base::checked_cast<size_t>(response_body_size),
+                            ' ');
+
+  std::vector<net::MockRead> reads_list;
+  std::vector<std::string> mock_writes;
+  std::vector<net::MockWrite> writes_list;
+
+  std::vector<net::EffectiveConnectionType> effective_connection_types;
+  effective_connection_types.push_back(net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G);
+  effective_connection_types.push_back(net::EFFECTIVE_CONNECTION_TYPE_2G);
+
+  BuildSocket(response_headers, response_body, true, effective_connection_types,
+              &reads_list, &mock_writes, &writes_list);
+
+  // Add 1 socket provider since 1 request in this test is fetched from the
+  // network.
+  FetchURLRequestAndVerifyECTHeader(effective_connection_types[0], true, false);
+
+  // When the ECT is set to the same value, fetching the same resource should
+  // result in a cache hit.
+  FetchURLRequestAndVerifyECTHeader(effective_connection_types[0], true, true);
+
+  // When the ECT is set to a different value, the response should still be
+  // served from the cache.
+  FetchURLRequestAndVerifyECTHeader(effective_connection_types[1], true, true);
+}
+
+// Test that effective connection type is not added to the request headers when
+// the field trial is not enabled.
+TEST_F(DataReductionProxyNetworkDelegateTest, ECTHeaderNotEnabled) {
+  Init(true /* use_secure_proxy */, false /* enable_brotli_globally */);
+
+  std::string response_headers =
+      "HTTP/1.1 200 OK\r\n"
+      "Content-Length: 140\r\n"
+      "Via: 1.1 Chrome-Compression-Proxy\r\n"
+      "Cache-Control: max-age=1200\r\n"
+      "Vary: chrome-proxy-ect\r\n"
+      "x-original-content-length: 200\r\n\r\n";
+
+  int response_body_size = 140;
+  std::string response_body(base::checked_cast<size_t>(response_body_size),
+                            ' ');
+
+  std::vector<net::MockRead> reads_list;
+  std::vector<std::string> mock_writes;
+  std::vector<net::MockWrite> writes_list;
+
+  std::vector<net::EffectiveConnectionType> effective_connection_types;
+  effective_connection_types.push_back(net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G);
+
+  BuildSocket(response_headers, response_body, false,
+              effective_connection_types, &reads_list, &mock_writes,
+              &writes_list);
+
+  // Add 1 socket provider since 1 request in this test is fetched from the
+  // network.
+  FetchURLRequestAndVerifyECTHeader(effective_connection_types[0], false,
+                                    false);
+}
+
 }  // namespace
 
 }  // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_prefs_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_prefs_unittest.cc
index beabdfb1..8567157 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_prefs_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_prefs_unittest.cc
@@ -39,8 +39,7 @@
                       PrefService* pref_service) {
     ListPrefUpdate list(local_state_prefs(), pref_name);
     for (int64_t i = 0; i < 10L; ++i) {
-      list->Set(i, new base::StringValue(
-          base::Int64ToString(i + starting_value)));
+      list->Set(i, new base::Value(base::Int64ToString(i + starting_value)));
     }
   }
 
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.cc
index 744a0f3b..0a54fbd 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_test_utils.cc
@@ -62,9 +62,9 @@
                                  prefs::kDailyHttpReceivedContentLength);
   for (int64_t i = 0; i < kNumDaysInHistory; i++) {
     original_update->Insert(
-        0, base::MakeUnique<base::StringValue>(base::Int64ToString(2 * i)));
+        0, base::MakeUnique<base::Value>(base::Int64ToString(2 * i)));
     received_update->Insert(
-        0, base::MakeUnique<base::StringValue>(base::Int64ToString(i)));
+        0, base::MakeUnique<base::Value>(base::Int64ToString(i)));
   }
   last_update_time_ = base::Time::Now().LocalMidnight();
   pref_service->SetInt64(prefs::kDailyHttpContentLengthLastUpdateDate,
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.cc b/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.cc
index 375416a0..a8dca30 100644
--- a/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.cc
+++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.cc
@@ -27,6 +27,7 @@
 namespace {
 
 const char kChromeProxyHeader[] = "chrome-proxy";
+const char kChromeProxyECTHeader[] = "chrome-proxy-ect";
 const char kChromeProxyAcceptTransformHeader[] =
     "chrome-proxy-accept-transform";
 const char kChromeProxyContentTransformHeader[] =
@@ -113,6 +114,10 @@
   return kChromeProxyHeader;
 }
 
+const char* chrome_proxy_ect_header() {
+  return kChromeProxyECTHeader;
+}
+
 const char* chrome_proxy_accept_transform_header() {
   return kChromeProxyAcceptTransformHeader;
 }
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h b/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h
index e86cb5a..3e613d8 100644
--- a/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h
+++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h
@@ -67,6 +67,10 @@
 // Gets the header used for data reduction proxy requests and responses.
 const char* chrome_proxy_header();
 
+// Gets the chrome-proxy-ect request header that includes the effective
+// connection type.
+const char* chrome_proxy_ect_header();
+
 // Gets the ChromeProxyAcceptTransform header name.
 const char* chrome_proxy_accept_transform_header();
 
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 ac08fb10..a1069e3c 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
@@ -260,6 +260,12 @@
                            kDisabled, base::CompareCase::SENSITIVE);
 }
 
+bool IsAddChromeProxyECTHeaderEnabled() {
+  return base::StartsWith(base::FieldTrialList::FindFullName(
+                              "DataReductionProxyAddChromeProxyECTHeader"),
+                          kEnabled, base::CompareCase::SENSITIVE);
+}
+
 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".
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 02b3d9c..401f78e7 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
@@ -130,6 +130,10 @@
 // Returns true if Brotli should be added to the accept-encoding header.
 bool IsBrotliAcceptEncodingEnabled();
 
+// Returns true if the effective connection type should be added to the data
+// saver requests using chrome-proxy-ect header.
+bool IsAddChromeProxyECTHeaderEnabled();
+
 // Returns true if the Data Reduction Proxy config client should be used.
 bool IsConfigClientEnabled();
 
diff --git a/components/data_use_measurement/core/data_use_user_data.h b/components/data_use_measurement/core/data_use_user_data.h
index 4f8b4b9..a3912d3 100644
--- a/components/data_use_measurement/core/data_use_user_data.h
+++ b/components/data_use_measurement/core/data_use_user_data.h
@@ -22,7 +22,8 @@
  public:
   // This enum should be synced with DataUseServices enum in histograms.xml.
   // Please keep them synced after any updates. Also add service name to
-  // GetServiceNameAsString function.
+  // GetServiceNameAsString function and the same service name to
+  // DataUse.Service.Types histogram suffixes in histograms.xml
   enum ServiceName {
     NOT_TAGGED,
     SUGGESTIONS,
diff --git a/components/dom_distiller/core/page_features_unittest.cc b/components/dom_distiller/core/page_features_unittest.cc
index 6d0bea3..0bfeb14 100644
--- a/components/dom_distiller/core/page_features_unittest.cc
+++ b/components/dom_distiller/core/page_features_unittest.cc
@@ -75,7 +75,7 @@
     std::string stringified_json;
     ASSERT_TRUE(base::JSONWriter::Write(*core_features, &stringified_json));
     std::unique_ptr<base::Value> stringified_value(
-        new base::StringValue(stringified_json));
+        new base::Value(stringified_json));
     std::vector<double> derived(
         CalculateDerivedFeaturesFromJSON(stringified_value.get()));
 
diff --git a/components/dom_distiller/core/viewer.cc b/components/dom_distiller/core/viewer.cc
index 524f50f..efc5c6a 100644
--- a/components/dom_distiller/core/viewer.cc
+++ b/components/dom_distiller/core/viewer.cc
@@ -150,11 +150,11 @@
 namespace viewer {
 
 const std::string GetShowFeedbackFormJs() {
-  base::StringValue question_val(
+  base::Value question_val(
       l10n_util::GetStringUTF8(IDS_DOM_DISTILLER_QUALITY_QUESTION));
-  base::StringValue no_val(
+  base::Value no_val(
       l10n_util::GetStringUTF8(IDS_DOM_DISTILLER_QUALITY_ANSWER_NO));
-  base::StringValue yes_val(
+  base::Value yes_val(
       l10n_util::GetStringUTF8(IDS_DOM_DISTILLER_QUALITY_ANSWER_YES));
 
   std::string question;
@@ -173,7 +173,7 @@
     const bool is_last_page) {
   std::string output(page_proto->html());
   EnsureNonEmptyContent(&output);
-  base::StringValue value(output);
+  base::Value value(output);
   base::JSONWriter::Write(value, &output);
   std::string page_update("addToPage(");
   page_update += output + ");";
@@ -187,7 +187,7 @@
       IDS_DOM_DISTILLER_VIEWER_FAILED_TO_FIND_ARTICLE_TITLE));
   std::string page_update(GetSetTitleJs(title));
 
-  base::StringValue value(l10n_util::GetStringUTF8(
+  base::Value value(l10n_util::GetStringUTF8(
       IDS_DOM_DISTILLER_VIEWER_FAILED_TO_FIND_ARTICLE_CONTENT));
   std::string output;
   base::JSONWriter::Write(value, &output);
@@ -201,14 +201,14 @@
 }
 
 const std::string GetSetTitleJs(std::string title) {
-  base::StringValue value(title);
+  base::Value value(title);
   std::string output;
   base::JSONWriter::Write(value, &output);
   return "setTitle(" + output + ");";
 }
 
 const std::string GetSetTextDirectionJs(const std::string& direction) {
-  base::StringValue value(direction);
+  base::Value value(direction);
   std::string output;
   base::JSONWriter::Write(value, &output);
   return "setTextDirection(" + output + ");";
@@ -240,7 +240,7 @@
 
   std::string output(unsafe_output_stream.str());
   EnsureNonEmptyContent(&output);
-  base::JSONWriter::Write(base::StringValue(output), &output);
+  base::JSONWriter::Write(base::Value(output), &output);
   std::string page_update("addToPage(");
   page_update += output + ");";
   return page_update + GetToggleLoadingIndicatorJs(true);
diff --git a/components/dom_distiller/ios/distiller_page_ios.mm b/components/dom_distiller/ios/distiller_page_ios.mm
index 4773be55..04bfd90 100644
--- a/components/dom_distiller/ios/distiller_page_ios.mm
+++ b/components/dom_distiller/ios/distiller_page_ios.mm
@@ -50,7 +50,7 @@
 
   CFTypeID result_type = CFGetTypeID(wk_result);
   if (result_type == CFStringGetTypeID()) {
-    result.reset(new base::StringValue(base::SysNSStringToUTF16(wk_result)));
+    result.reset(new base::Value(base::SysNSStringToUTF16(wk_result)));
     DCHECK(result->IsType(base::Value::Type::STRING));
   } else if (result_type == CFNumberGetTypeID()) {
     // Different implementation is here.
diff --git a/components/json_schema/json_schema_validator_unittest_base.cc b/components/json_schema/json_schema_validator_unittest_base.cc
index eb60ebb..1208c12 100644
--- a/components/json_schema/json_schema_validator_unittest_base.cc
+++ b/components/json_schema/json_schema_validator_unittest_base.cc
@@ -123,18 +123,16 @@
   schema->SetString(schema::kPattern, "foo+");
 
   ExpectValid(TEST_SOURCE,
-              std::unique_ptr<base::Value>(new base::StringValue("foo")).get(),
+              std::unique_ptr<base::Value>(new base::Value("foo")).get(),
               schema.get(), NULL);
-  ExpectValid(
-      TEST_SOURCE,
-      std::unique_ptr<base::Value>(new base::StringValue("foooooo")).get(),
-      schema.get(), NULL);
-  ExpectNotValid(
-      TEST_SOURCE,
-      std::unique_ptr<base::Value>(new base::StringValue("bar")).get(),
-      schema.get(), NULL, std::string(),
-      JSONSchemaValidator::FormatErrorMessage(
-          JSONSchemaValidator::kStringPattern, "foo+"));
+  ExpectValid(TEST_SOURCE,
+              std::unique_ptr<base::Value>(new base::Value("foooooo")).get(),
+              schema.get(), NULL);
+  ExpectNotValid(TEST_SOURCE,
+                 std::unique_ptr<base::Value>(new base::Value("bar")).get(),
+                 schema.get(), NULL, std::string(),
+                 JSONSchemaValidator::FormatErrorMessage(
+                     JSONSchemaValidator::kStringPattern, "foo+"));
 }
 
 void JSONSchemaValidatorTestBase::TestEnum() {
@@ -142,7 +140,7 @@
       LoadDictionary("enum_schema.json"));
 
   ExpectValid(TEST_SOURCE,
-              std::unique_ptr<base::Value>(new base::StringValue("foo")).get(),
+              std::unique_ptr<base::Value>(new base::Value("foo")).get(),
               schema.get(), NULL);
   ExpectValid(TEST_SOURCE,
               std::unique_ptr<base::Value>(new base::Value(42)).get(),
@@ -152,8 +150,7 @@
               schema.get(), NULL);
 
   ExpectNotValid(
-      TEST_SOURCE,
-      std::unique_ptr<base::Value>(new base::StringValue("42")).get(),
+      TEST_SOURCE, std::unique_ptr<base::Value>(new base::Value("42")).get(),
       schema.get(), NULL, std::string(), JSONSchemaValidator::kInvalidEnum);
   ExpectNotValid(TEST_SOURCE, base::Value::CreateNullValue().get(),
                  schema.get(), NULL, std::string(),
@@ -175,8 +172,7 @@
   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
 
   ExpectNotValid(
-      TEST_SOURCE,
-      std::unique_ptr<base::Value>(new base::StringValue("foo")).get(),
+      TEST_SOURCE, std::unique_ptr<base::Value>(new base::Value("foo")).get(),
       schema.get(), NULL, std::string(), JSONSchemaValidator::kInvalidChoice);
   ExpectNotValid(
       TEST_SOURCE, std::unique_ptr<base::Value>(new base::ListValue()).get(),
@@ -413,7 +409,7 @@
   base::DictionaryValue* additional_properties = new base::DictionaryValue();
   additional_properties->SetString(schema::kType, schema::kAny);
   schema->Set(schema::kAdditionalProperties, additional_properties);
-  instance->Set(0, new base::StringValue("42"));
+  instance->Set(0, new base::Value("42"));
   instance->AppendString("anything");
   ExpectValid(TEST_SOURCE, instance.get(), schema.get(), NULL);
   instance->Set(2, new base::ListValue());
@@ -497,22 +493,21 @@
   schema->SetInteger(schema::kMaxLength, 10);
 
   ExpectValid(TEST_SOURCE,
-              std::unique_ptr<base::Value>(new base::StringValue("x")).get(),
+              std::unique_ptr<base::Value>(new base::Value("x")).get(),
               schema.get(), NULL);
-  ExpectValid(
-      TEST_SOURCE,
-      std::unique_ptr<base::Value>(new base::StringValue("xxxxxxxxxx")).get(),
-      schema.get(), NULL);
+  ExpectValid(TEST_SOURCE,
+              std::unique_ptr<base::Value>(new base::Value("xxxxxxxxxx")).get(),
+              schema.get(), NULL);
 
   ExpectNotValid(
       TEST_SOURCE,
-      std::unique_ptr<base::Value>(new base::StringValue(std::string())).get(),
+      std::unique_ptr<base::Value>(new base::Value(std::string())).get(),
       schema.get(), NULL, std::string(),
       JSONSchemaValidator::FormatErrorMessage(
           JSONSchemaValidator::kStringMinLength, "1"));
   ExpectNotValid(
       TEST_SOURCE,
-      std::unique_ptr<base::Value>(new base::StringValue("xxxxxxxxxxx")).get(),
+      std::unique_ptr<base::Value>(new base::Value("xxxxxxxxxxx")).get(),
       schema.get(), NULL, std::string(),
       JSONSchemaValidator::FormatErrorMessage(
           JSONSchemaValidator::kStringMaxLength, "10"));
@@ -597,10 +592,9 @@
                     new base::Value(pow(-2.0, DBL_MANT_DIG) * 2))
                     .get()));
 
-  EXPECT_EQ(
-      std::string(schema::kString),
-      JSONSchemaValidator::GetJSONSchemaType(
-          std::unique_ptr<base::Value>(new base::StringValue("foo")).get()));
+  EXPECT_EQ(std::string(schema::kString),
+            JSONSchemaValidator::GetJSONSchemaType(
+                std::unique_ptr<base::Value>(new base::Value("foo")).get()));
   EXPECT_EQ(std::string(schema::kArray),
             JSONSchemaValidator::GetJSONSchemaType(
                 std::unique_ptr<base::Value>(new base::ListValue()).get()));
@@ -628,10 +622,9 @@
               schema.get(), NULL);
 
   schema->SetString(schema::kType, schema::kString);
-  ExpectValid(
-      TEST_SOURCE,
-      std::unique_ptr<base::Value>(new base::StringValue("foobar")).get(),
-      schema.get(), NULL);
+  ExpectValid(TEST_SOURCE,
+              std::unique_ptr<base::Value>(new base::Value("foobar")).get(),
+              schema.get(), NULL);
 
   schema->SetString(schema::kType, schema::kNumber);
   ExpectValid(TEST_SOURCE,
@@ -712,8 +705,7 @@
 
   schema->SetString(schema::kType, schema::kNumber);
   ExpectNotValid(
-      TEST_SOURCE,
-      std::unique_ptr<base::Value>(new base::StringValue("42")).get(),
+      TEST_SOURCE, std::unique_ptr<base::Value>(new base::Value("42")).get(),
       schema.get(), NULL, std::string(),
       JSONSchemaValidator::FormatErrorMessage(
           JSONSchemaValidator::kInvalidType, schema::kNumber, schema::kString));
diff --git a/components/login/base_screen_handler_utils.cc b/components/login/base_screen_handler_utils.cc
index 89c2cf40..fe1851b 100644
--- a/components/login/base_screen_handler_utils.cc
+++ b/components/login/base_screen_handler_utils.cc
@@ -84,16 +84,16 @@
   return base::Value(v);
 }
 
-base::StringValue MakeValue(const std::string& v) {
-  return base::StringValue(v);
+base::Value MakeValue(const std::string& v) {
+  return base::Value(v);
 }
 
-base::StringValue MakeValue(const base::string16& v) {
-  return base::StringValue(v);
+base::Value MakeValue(const base::string16& v) {
+  return base::Value(v);
 }
 
-base::StringValue MakeValue(const AccountId& v) {
-  return base::StringValue(v.Serialize());
+base::Value MakeValue(const AccountId& v) {
+  return base::Value(v.Serialize());
 }
 
 ParsedValueContainer<AccountId>::ParsedValueContainer() {
diff --git a/components/login/base_screen_handler_utils.h b/components/login/base_screen_handler_utils.h
index e6a6e64..fbb74d35 100644
--- a/components/login/base_screen_handler_utils.h
+++ b/components/login/base_screen_handler_utils.h
@@ -56,9 +56,9 @@
 base::Value LOGIN_EXPORT MakeValue(bool v);
 base::Value LOGIN_EXPORT MakeValue(int v);
 base::Value LOGIN_EXPORT MakeValue(double v);
-base::StringValue LOGIN_EXPORT MakeValue(const std::string& v);
-base::StringValue LOGIN_EXPORT MakeValue(const base::string16& v);
-base::StringValue LOGIN_EXPORT MakeValue(const AccountId& v);
+base::Value LOGIN_EXPORT MakeValue(const std::string& v);
+base::Value LOGIN_EXPORT MakeValue(const base::string16& v);
+base::Value LOGIN_EXPORT MakeValue(const AccountId& v);
 
 template <typename T>
 inline const T& MakeValue(const T& v) {
diff --git a/components/login/screens/screen_context.cc b/components/login/screens/screen_context.cc
index 4021855..5e170b6 100644
--- a/components/login/screens/screen_context.cc
+++ b/components/login/screens/screen_context.cc
@@ -44,11 +44,11 @@
 }
 
 bool ScreenContext::SetString(const KeyType& key, const std::string& value) {
-  return Set(key, new base::StringValue(value));
+  return Set(key, new base::Value(value));
 }
 
 bool ScreenContext::SetString(const KeyType& key, const base::string16& value) {
-  return Set(key, new base::StringValue(value));
+  return Set(key, new base::Value(value));
 }
 
 bool ScreenContext::SetStringList(const KeyType& key, const StringList& value) {
diff --git a/components/ntp_tiles/webui/popular_sites_internals_message_handler.cc b/components/ntp_tiles/webui/popular_sites_internals_message_handler.cc
index 29e69b93..7163b59 100644
--- a/components/ntp_tiles/webui/popular_sites_internals_message_handler.cc
+++ b/components/ntp_tiles/webui/popular_sites_internals_message_handler.cc
@@ -114,12 +114,12 @@
   std::string version =
       prefs->GetString(ntp_tiles::prefs::kPopularSitesOverrideVersion);
   web_ui_->CallJavascriptFunction(
-      "chrome.popular_sites_internals.receiveOverrides", base::StringValue(url),
-      base::StringValue(country), base::StringValue(version));
+      "chrome.popular_sites_internals.receiveOverrides", base::Value(url),
+      base::Value(country), base::Value(version));
 }
 
 void PopularSitesInternalsMessageHandler::SendDownloadResult(bool success) {
-  base::StringValue result(success ? "Success" : "Fail");
+  base::Value result(success ? "Success" : "Fail");
   web_ui_->CallJavascriptFunction(
       "chrome.popular_sites_internals.receiveDownloadResult", result);
 }
@@ -142,7 +142,7 @@
 
 void PopularSitesInternalsMessageHandler::SendJson(const std::string& json) {
   web_ui_->CallJavascriptFunction("chrome.popular_sites_internals.receiveJson",
-                                  base::StringValue(json));
+                                  base::Value(json));
 }
 
 void PopularSitesInternalsMessageHandler::OnPopularSitesAvailable(
diff --git a/components/offline_pages/core/background/offliner.h b/components/offline_pages/core/background/offliner.h
index 2c36452..c50df35 100644
--- a/components/offline_pages/core/background/offliner.h
+++ b/components/offline_pages/core/background/offliner.h
@@ -63,6 +63,9 @@
   // TODO(dougarnett): consider passing back a request id instead of request.
   typedef base::Callback<void(const SavePageRequest&, RequestStatus)>
       CompletionCallback;
+  // Reports that the cancel operation has completed.
+  // TODO(chili): make save operation cancellable.
+  typedef base::Callback<void(int64_t request_id)> CancelCallback;
 
   Offliner() {}
   virtual ~Offliner() {}
@@ -75,7 +78,7 @@
 
   // Clears the currently processing request, if any, and skips running its
   // CompletionCallback.
-  virtual void Cancel() = 0;
+  virtual void Cancel(const CancelCallback& callback) = 0;
 
   // Handles timeout scenario. Returns true if lowbar is met and try to do a
   // snapshot of the current webcontents.
diff --git a/components/offline_pages/core/background/offliner_stub.cc b/components/offline_pages/core/background/offliner_stub.cc
index 3b3c1f56..c007ae0a 100644
--- a/components/offline_pages/core/background/offliner_stub.cc
+++ b/components/offline_pages/core/background/offliner_stub.cc
@@ -34,8 +34,9 @@
   return true;
 }
 
-void OfflinerStub::Cancel() {
+void OfflinerStub::Cancel(const CancelCallback& callback) {
   cancel_called_ = true;
+  callback.Run(0LL);
 }
 
 bool OfflinerStub::HandleTimeout(const SavePageRequest& request) {
diff --git a/components/offline_pages/core/background/offliner_stub.h b/components/offline_pages/core/background/offliner_stub.h
index 821f5ea9..16abb8f7 100644
--- a/components/offline_pages/core/background/offliner_stub.h
+++ b/components/offline_pages/core/background/offliner_stub.h
@@ -19,7 +19,7 @@
   bool LoadAndSave(const SavePageRequest& request,
                    const CompletionCallback& callback) override;
 
-  void Cancel() override;
+  void Cancel(const CancelCallback& callback) override;
 
   void disable_loading() { disable_loading_ = true; }
 
diff --git a/components/offline_pages/core/background/request_coordinator.cc b/components/offline_pages/core/background/request_coordinator.cc
index 5a363c0a..f729bc51 100644
--- a/components/offline_pages/core/background/request_coordinator.cc
+++ b/components/offline_pages/core/background/request_coordinator.cc
@@ -263,35 +263,21 @@
   callback.Run(std::move(requests));
 }
 
-void RequestCoordinator::StopPrerendering(Offliner::RequestStatus stop_status) {
+void RequestCoordinator::StopPrerendering(
+    const Offliner::CancelCallback& final_callback,
+    Offliner::RequestStatus stop_status) {
   if (offliner_ && is_busy_) {
     DCHECK(active_request_.get());
-    offliner_->Cancel();
-
-    if (stop_status == Offliner::RequestStatus::REQUEST_COORDINATOR_TIMED_OUT ||
-        stop_status == Offliner::RequestStatus::BACKGROUND_SCHEDULER_CANCELED) {
-      // Consider watchdog timeout a completed attempt.
-      SavePageRequest request(*active_request_.get());
-      UpdateRequestForCompletedAttempt(request, stop_status);
-    } else {
-      // Otherwise consider this stop an aborted attempt.
-      UpdateRequestForAbortedAttempt(*active_request_.get());
-    }
+    offliner_->Cancel(base::Bind(
+        &RequestCoordinator::HandleCancelUpdateStatusCallback,
+        weak_ptr_factory_.GetWeakPtr(), final_callback, stop_status));
+    return;
   }
 
-  // Stopping offliner means it will not call callback so set last status.
-  last_offlining_status_ = stop_status;
-
-  if (active_request_) {
-    event_logger_.RecordOfflinerResult(active_request_->client_id().name_space,
-                                       last_offlining_status_,
-                                       active_request_->request_id());
-    RecordOfflinerResultUMA(active_request_->client_id(),
-                            active_request_->creation_time(),
-                            last_offlining_status_);
-    is_busy_ = false;
-    active_request_.reset();
-  }
+  UpdateStatusForCancel(stop_status);
+  int64_t request_id =
+      active_request_.get() ? active_request_->request_id() : 0LL;
+  final_callback.Run(request_id);
 }
 
 void RequestCoordinator::GetRequestsForSchedulingCallback(
@@ -322,8 +308,10 @@
   if (active_request_ != nullptr) {
     if (request_ids.end() != std::find(request_ids.begin(), request_ids.end(),
                                        active_request_->request_id())) {
-      StopPrerendering(Offliner::RequestStatus::REQUEST_COORDINATOR_CANCELED);
-      active_request_.reset(nullptr);
+      StopPrerendering(
+          base::Bind(&RequestCoordinator::ResetActiveRequestCallback,
+                     weak_ptr_factory_.GetWeakPtr()),
+          Offliner::RequestStatus::REQUEST_COORDINATOR_CANCELED);
       return true;
     }
   }
@@ -505,6 +493,53 @@
     NotifyCompleted(request, status);
 }
 
+void RequestCoordinator::HandleCancelUpdateStatusCallback(
+    const Offliner::CancelCallback& final_callback,
+    Offliner::RequestStatus stop_status,
+    int64_t offline_id) {
+  if (stop_status == Offliner::RequestStatus::REQUEST_COORDINATOR_TIMED_OUT ||
+      stop_status == Offliner::RequestStatus::BACKGROUND_SCHEDULER_CANCELED) {
+    // Consider watchdog timeout a completed attempt.
+    SavePageRequest request(*active_request_.get());
+    UpdateRequestForCompletedAttempt(request, stop_status);
+  } else {
+    // Otherwise consider this stop an aborted attempt.
+    UpdateRequestForAbortedAttempt(*active_request_.get());
+  }
+
+  UpdateStatusForCancel(stop_status);
+  final_callback.Run(offline_id);
+}
+
+void RequestCoordinator::UpdateStatusForCancel(
+    Offliner::RequestStatus stop_status) {
+  // Stopping offliner means it will not call callback so set last status.
+  last_offlining_status_ = stop_status;
+
+  if (active_request_) {
+    event_logger_.RecordOfflinerResult(active_request_->client_id().name_space,
+                                       last_offlining_status_,
+                                       active_request_->request_id());
+    RecordOfflinerResultUMA(active_request_->client_id(),
+                            active_request_->creation_time(),
+                            last_offlining_status_);
+    is_busy_ = false;
+    active_request_.reset();
+  }
+}
+
+void RequestCoordinator::ResetActiveRequestCallback(int64_t offline_id) {
+  active_request_.reset();
+}
+
+void RequestCoordinator::StartSchedulerCallback(int64_t offline_id) {
+  scheduler_callback_.Run(true);
+}
+
+void RequestCoordinator::TryNextRequestCallback(int64_t offline_id) {
+  TryNextRequest(!kStartOfProcessing);
+}
+
 void RequestCoordinator::ScheduleAsNeeded() {
   // Get all requests from queue (there is no filtering mechanism).
   queue_->GetRequests(
@@ -514,10 +549,9 @@
 
 void RequestCoordinator::StopProcessing(Offliner::RequestStatus stop_status) {
   processing_state_ = ProcessingWindowState::STOPPED;
-  StopPrerendering(stop_status);
-
-  // Let the scheduler know we are done processing.
-  scheduler_callback_.Run(true);
+  StopPrerendering(base::Bind(&RequestCoordinator::StartSchedulerCallback,
+                              weak_ptr_factory_.GetWeakPtr()),
+                   stop_status);
 }
 
 void RequestCoordinator::HandleWatchdogTimeout() {
@@ -525,8 +559,9 @@
       Offliner::REQUEST_COORDINATOR_TIMED_OUT;
   if (offliner_->HandleTimeout(*active_request_.get()))
     return;
-  StopPrerendering(watchdog_status);
-  TryNextRequest(!kStartOfProcessing);
+  StopPrerendering(base::Bind(&RequestCoordinator::TryNextRequestCallback,
+                              weak_ptr_factory_.GetWeakPtr()),
+                   watchdog_status);
 }
 
 // Returns true if the caller should expect a callback, false otherwise. For
diff --git a/components/offline_pages/core/background/request_coordinator.h b/components/offline_pages/core/background/request_coordinator.h
index b9d3fae9..770cae3 100644
--- a/components/offline_pages/core/background/request_coordinator.h
+++ b/components/offline_pages/core/background/request_coordinator.h
@@ -274,6 +274,17 @@
   void HandleRemovedRequests(RequestNotifier::BackgroundSavePageResult status,
                              std::unique_ptr<UpdateRequestsResult> result);
 
+  // Handle updating of request status after cancel is called. Will call
+  // HandleCancelRecordResultCallback for UMA handling
+  void HandleCancelUpdateStatusCallback(
+      const Offliner::CancelCallback& next_callback,
+      Offliner::RequestStatus stop_status,
+      int64_t offline_id);
+  void UpdateStatusForCancel(Offliner::RequestStatus stop_status);
+  void ResetActiveRequestCallback(int64_t offline_id);
+  void StartSchedulerCallback(int64_t offline_id);
+  void TryNextRequestCallback(int64_t offline_id);
+
   bool StartProcessingInternal(const ProcessingWindowState processing_state,
                                const base::Callback<void(bool)>& callback);
 
@@ -318,7 +329,8 @@
   void HandleWatchdogTimeout();
 
   // Cancels an in progress pre-rendering, and updates state appropriately.
-  void StopPrerendering(Offliner::RequestStatus stop_status);
+  void StopPrerendering(const Offliner::CancelCallback& callback,
+                        Offliner::RequestStatus stop_status);
 
   // Marks attempt on the request and sends it to offliner in continuation.
   void SendRequestToOffliner(const SavePageRequest& request);
diff --git a/components/omnibox/browser/BUILD.gn b/components/omnibox/browser/BUILD.gn
index d4bc859..926825f 100644
--- a/components/omnibox/browser/BUILD.gn
+++ b/components/omnibox/browser/BUILD.gn
@@ -70,6 +70,7 @@
     "keyword_provider.cc",
     "keyword_provider.h",
     "match_compare.h",
+    "omnibox_client.cc",
     "omnibox_client.h",
     "omnibox_controller.cc",
     "omnibox_controller.h",
diff --git a/components/omnibox/browser/base_search_provider.cc b/components/omnibox/browser/base_search_provider.cc
index 014ed75..7b3a8a6 100644
--- a/components/omnibox/browser/base_search_provider.cc
+++ b/components/omnibox/browser/base_search_provider.cc
@@ -7,6 +7,7 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include "base/feature_list.h"
 #include "base/i18n/case_conversion.h"
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
@@ -337,13 +338,18 @@
   if (!current_page_url.is_valid())
     return false;
 
-  // Only allow HTTP URLs or HTTPS URLs for the same domain as the search
-  // provider.
-  if ((current_page_url.scheme() != url::kHttpScheme) &&
-      ((current_page_url.scheme() != url::kHttpsScheme) ||
-       !net::registry_controlled_domains::SameDomainOrHost(
-           current_page_url, suggest_url,
-           net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES)))
+  // Only allow HTTP URLs or HTTPS URLs.  For HTTPS URLs, require that either
+  // the appropriate feature flag is enabled or the URL is the same domain as
+  // the search provider.
+  const bool scheme_allowed =
+      (current_page_url.scheme() == url::kHttpScheme) ||
+      ((current_page_url.scheme() == url::kHttpsScheme) &&
+       (base::FeatureList::IsEnabled(
+            omnibox::kSearchProviderContextAllowHttpsUrls) ||
+        net::registry_controlled_domains::SameDomainOrHost(
+            current_page_url, suggest_url,
+            net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES)));
+  if (!scheme_allowed)
     return false;
 
   if (!client->TabSyncEnabledAndUnencrypted())
diff --git a/components/omnibox/browser/omnibox_client.cc b/components/omnibox/browser/omnibox_client.cc
new file mode 100644
index 0000000..7f85f44
--- /dev/null
+++ b/components/omnibox/browser/omnibox_client.cc
@@ -0,0 +1,81 @@
+// Copyright 2017 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 "components/omnibox/browser/omnibox_client.h"
+
+#include "base/strings/string_util.h"
+#include "ui/gfx/image/image.h"
+
+std::unique_ptr<OmniboxNavigationObserver>
+OmniboxClient::CreateOmniboxNavigationObserver(
+    const base::string16& text,
+    const AutocompleteMatch& match,
+    const AutocompleteMatch& alternate_nav_match) {
+  return nullptr;
+}
+
+bool OmniboxClient::CurrentPageExists() const {
+  return true;
+}
+
+const GURL& OmniboxClient::GetURL() const {
+  return GURL::EmptyGURL();
+}
+
+const base::string16& OmniboxClient::GetTitle() const {
+  return base::EmptyString16();
+}
+
+gfx::Image OmniboxClient::GetFavicon() const {
+  return gfx::Image();
+}
+
+bool OmniboxClient::IsInstantNTP() const {
+  return false;
+}
+
+bool OmniboxClient::IsSearchResultsPage() const {
+  return false;
+}
+
+bool OmniboxClient::IsLoading() const {
+  return false;
+}
+
+bool OmniboxClient::IsPasteAndGoEnabled() const {
+  return false;
+}
+
+bool OmniboxClient::IsNewTabPage(const std::string& url) const {
+  return false;
+}
+
+bool OmniboxClient::IsHomePage(const std::string& url) const {
+  return false;
+}
+
+bookmarks::BookmarkModel* OmniboxClient::GetBookmarkModel() {
+  return nullptr;
+}
+
+TemplateURLService* OmniboxClient::GetTemplateURLService() {
+  return nullptr;
+}
+
+AutocompleteClassifier* OmniboxClient::GetAutocompleteClassifier() {
+  return nullptr;
+}
+
+gfx::Image OmniboxClient::GetIconIfExtensionMatch(
+    const AutocompleteMatch& match) const {
+  return gfx::Image();
+}
+
+bool OmniboxClient::ProcessExtensionKeyword(
+    TemplateURL* template_url,
+    const AutocompleteMatch& match,
+    WindowOpenDisposition disposition,
+    OmniboxNavigationObserver* observer) {
+  return false;
+}
diff --git a/components/omnibox/browser/omnibox_client.h b/components/omnibox/browser/omnibox_client.h
index 10a177f..4d8cf2b 100644
--- a/components/omnibox/browser/omnibox_client.h
+++ b/components/omnibox/browser/omnibox_client.h
@@ -43,54 +43,53 @@
   // Returns an OmniboxNavigationObserver specific to the embedder context. May
   // return null if the embedder has no need to observe omnibox navigations.
   virtual std::unique_ptr<OmniboxNavigationObserver>
-  CreateOmniboxNavigationObserver(
-      const base::string16& text,
-      const AutocompleteMatch& match,
-      const AutocompleteMatch& alternate_nav_match) = 0;
+  CreateOmniboxNavigationObserver(const base::string16& text,
+                                  const AutocompleteMatch& match,
+                                  const AutocompleteMatch& alternate_nav_match);
 
   // Returns whether there is any associated current page.  For example, during
   // startup or shutdown, the omnibox may exist but have no attached page.
-  virtual bool CurrentPageExists() const = 0;
+  virtual bool CurrentPageExists() const;
 
   // Returns the URL of the current page.
-  virtual const GURL& GetURL() const = 0;
+  virtual const GURL& GetURL() const;
 
   // Returns the title of the current page.
-  virtual const base::string16& GetTitle() const = 0;
+  virtual const base::string16& GetTitle() const;
 
   // Returns the favicon of the current page.
-  virtual gfx::Image GetFavicon() const = 0;
+  virtual gfx::Image GetFavicon() const;
 
   // Returns true if the visible entry is a New Tab Page rendered by Instant.
-  virtual bool IsInstantNTP() const = 0;
+  virtual bool IsInstantNTP() const;
 
   // Returns true if the committed entry is a search results page.
-  virtual bool IsSearchResultsPage() const = 0;
+  virtual bool IsSearchResultsPage() const;
 
   // Returns whether the current page is loading.
-  virtual bool IsLoading() const = 0;
+  virtual bool IsLoading() const;
 
   // Returns whether paste-and-go functionality is enabled.
-  virtual bool IsPasteAndGoEnabled() const = 0;
+  virtual bool IsPasteAndGoEnabled() const;
 
   // Returns whether |url| corresponds to the new tab page.
-  virtual bool IsNewTabPage(const std::string& url) const = 0;
+  virtual bool IsNewTabPage(const std::string& url) const;
 
   // Returns whether |url| corresponds to the user's home page.
-  virtual bool IsHomePage(const std::string& url) const = 0;
+  virtual bool IsHomePage(const std::string& url) const;
 
   // Returns the session ID of the current page.
   virtual const SessionID& GetSessionID() const = 0;
 
-  virtual bookmarks::BookmarkModel* GetBookmarkModel() = 0;
-  virtual TemplateURLService* GetTemplateURLService() = 0;
+  virtual bookmarks::BookmarkModel* GetBookmarkModel();
+  virtual TemplateURLService* GetTemplateURLService();
   virtual const AutocompleteSchemeClassifier& GetSchemeClassifier() const = 0;
-  virtual AutocompleteClassifier* GetAutocompleteClassifier() = 0;
+  virtual AutocompleteClassifier* GetAutocompleteClassifier();
 
   // Returns the icon corresponding to |match| if match is an extension match
   // and an empty icon otherwise.
   virtual gfx::Image GetIconIfExtensionMatch(
-      const AutocompleteMatch& match) const = 0;
+      const AutocompleteMatch& match) const;
 
   // Checks whether |template_url| is an extension keyword; if so, asks the
   // ExtensionOmniboxEventRouter to process |match| for it and returns true.
@@ -101,25 +100,25 @@
   virtual bool ProcessExtensionKeyword(TemplateURL* template_url,
                                        const AutocompleteMatch& match,
                                        WindowOpenDisposition disposition,
-                                       OmniboxNavigationObserver* observer) = 0;
+                                       OmniboxNavigationObserver* observer);
 
   // Called to notify clients that the omnibox input state has changed.
-  virtual void OnInputStateChanged() = 0;
+  virtual void OnInputStateChanged() {}
 
   // Called to notify clients that the omnibox focus state has changed.
   virtual void OnFocusChanged(OmniboxFocusState state,
-                              OmniboxFocusChangeReason reason) = 0;
+                              OmniboxFocusChangeReason reason) {}
 
   // Called when the autocomplete result has changed. If the embedder supports
   // fetching of bitmaps for URLs (not all embedders do), |on_bitmap_fetched|
   // will be called when the bitmap has been fetched.
-  virtual void OnResultChanged(
-      const AutocompleteResult& result,
-      bool default_match_changed,
-      const BitmapFetchedCallback& on_bitmap_fetched) = 0;
+  virtual void OnResultChanged(const AutocompleteResult& result,
+                               bool default_match_changed,
+                               const BitmapFetchedCallback& on_bitmap_fetched) {
+  }
 
   // Called when the current autocomplete match has changed.
-  virtual void OnCurrentMatchChanged(const AutocompleteMatch& match) = 0;
+  virtual void OnCurrentMatchChanged(const AutocompleteMatch& match) {}
 
   // Called when the text may have changed in the edit.
   virtual void OnTextChanged(const AutocompleteMatch& current_match,
@@ -127,22 +126,22 @@
                              base::string16& user_text,
                              const AutocompleteResult& result,
                              bool is_popup_open,
-                             bool has_focus) = 0;
+                             bool has_focus) {}
 
   // Called when input has been accepted.
-  virtual void OnInputAccepted(const AutocompleteMatch& match) = 0;
+  virtual void OnInputAccepted(const AutocompleteMatch& match) {}
 
   // Called when the edit model is being reverted back to its unedited state.
-  virtual void OnRevert() = 0;
+  virtual void OnRevert() {}
 
   // Called to notify clients that a URL was opened from the omnibox.
-  virtual void OnURLOpenedFromOmnibox(OmniboxLog* log) = 0;
+  virtual void OnURLOpenedFromOmnibox(OmniboxLog* log) {}
 
   // Called when a bookmark is launched from the omnibox.
-  virtual void OnBookmarkLaunched() = 0;
+  virtual void OnBookmarkLaunched() {}
 
   // Discards the state for all pending and transient navigations.
-  virtual void DiscardNonCommittedNavigations() = 0;
+  virtual void DiscardNonCommittedNavigations() {}
 };
 
 #endif  // COMPONENTS_OMNIBOX_BROWSER_OMNIBOX_CLIENT_H_
diff --git a/components/omnibox/browser/omnibox_edit_unittest.cc b/components/omnibox/browser/omnibox_edit_unittest.cc
index a04b15e..b216370 100644
--- a/components/omnibox/browser/omnibox_edit_unittest.cc
+++ b/components/omnibox/browser/omnibox_edit_unittest.cc
@@ -152,56 +152,13 @@
     alternate_nav_match_ = alternate_nav_match;
     return nullptr;
   }
-  bool CurrentPageExists() const override { return true; }
-  const GURL& GetURL() const override { return GURL::EmptyGURL(); }
-  const base::string16& GetTitle() const override {
-    return base::EmptyString16();
-  }
-  gfx::Image GetFavicon() const override { return gfx::Image(); }
-  bool IsInstantNTP() const override { return false; }
-  bool IsSearchResultsPage() const override { return false; }
-  bool IsLoading() const override { return false; }
-  bool IsPasteAndGoEnabled() const override { return false; }
-  bool IsNewTabPage(const std::string& url) const override { return false; }
-  bool IsHomePage(const std::string& url) const override { return false; }
   const SessionID& GetSessionID() const override { return session_id_; }
-  bookmarks::BookmarkModel* GetBookmarkModel() override { return nullptr; }
-  TemplateURLService* GetTemplateURLService() override { return nullptr; }
   const AutocompleteSchemeClassifier& GetSchemeClassifier() const override {
     return scheme_classifier_;
   }
   AutocompleteClassifier* GetAutocompleteClassifier() override {
     return &autocomplete_classifier_;
   }
-  gfx::Image GetIconIfExtensionMatch(
-      const AutocompleteMatch& match) const override {
-    return gfx::Image();
-  }
-  bool ProcessExtensionKeyword(TemplateURL* template_url,
-                               const AutocompleteMatch& match,
-                               WindowOpenDisposition disposition,
-                               OmniboxNavigationObserver* observer) override {
-    return false;
-  }
-  void OnInputStateChanged() override {}
-  void OnFocusChanged(OmniboxFocusState state,
-                      OmniboxFocusChangeReason reason) override {}
-  void OnResultChanged(const AutocompleteResult& result,
-                       bool default_match_changed,
-                       const base::Callback<void(const SkBitmap& bitmap)>&
-                           on_bitmap_fetched) override {}
-  void OnCurrentMatchChanged(const AutocompleteMatch& match) override {}
-  void OnTextChanged(const AutocompleteMatch& current_match,
-                     bool user_input_in_progress,
-                     base::string16& user_text,
-                     const AutocompleteResult& result,
-                     bool is_popup_open,
-                     bool has_focus) override {}
-  void OnInputAccepted(const AutocompleteMatch& match) override {}
-  void OnRevert() override {}
-  void OnURLOpenedFromOmnibox(OmniboxLog* log) override {}
-  void OnBookmarkLaunched() override {}
-  void DiscardNonCommittedNavigations() override {}
 
  private:
   SessionID session_id_;
diff --git a/components/omnibox/browser/omnibox_field_trial.cc b/components/omnibox/browser/omnibox_field_trial.cc
index 24fbd8da..0ca581ed 100644
--- a/components/omnibox/browser/omnibox_field_trial.cc
+++ b/components/omnibox/browser/omnibox_field_trial.cc
@@ -61,6 +61,13 @@
 const base::Feature kSearchProviderWarmUpOnFocus{
     "OmniboxWarmUpSearchProviderOnFocus", base::FEATURE_DISABLED_BY_DEFAULT};
 
+// Feature used to enable the transmission of HTTPS URLs as part of the
+// context to the suggest server (assuming SearchProvider is permitted to
+// transmit URLs for context in the first place).
+const base::Feature kSearchProviderContextAllowHttpsUrls{
+    "OmniboixSearchProviderContextAllowHttpsUrls",
+    base::FEATURE_DISABLED_BY_DEFAULT};
+
 }  // namespace omnibox
 
 namespace {
diff --git a/components/omnibox/browser/omnibox_field_trial.h b/components/omnibox/browser/omnibox_field_trial.h
index 3bd0df05..525e9c8 100644
--- a/components/omnibox/browser/omnibox_field_trial.h
+++ b/components/omnibox/browser/omnibox_field_trial.h
@@ -28,6 +28,7 @@
 extern const base::Feature kOmniboxEntitySuggestions;
 extern const base::Feature kEnableClipboardProvider;
 extern const base::Feature kSearchProviderWarmUpOnFocus;
+extern const base::Feature kSearchProviderContextAllowHttpsUrls;
 }
 
 // The set of parameters customizing the HUP scoring.
diff --git a/components/omnibox/browser/search_provider.cc b/components/omnibox/browser/search_provider.cc
index 830f160..79ba8ae 100644
--- a/components/omnibox/browser/search_provider.cc
+++ b/components/omnibox/browser/search_provider.cc
@@ -271,12 +271,8 @@
   providers_.set(default_provider_keyword, keyword_provider_keyword);
 
   if (input.from_omnibox_focus()) {
-    // Don't display any suggestions for on-focus requests.  Stop any pending
-    // requests here (there likely aren't yet, though it doesn't hurt to be safe
-    // so that we can create a new request later in this flow (to warm-up the
-    // suggest server by alerting it that the user is likely about to start
-    // typing).
-    StopSuggest();
+    // Don't display any suggestions for on-focus requests.
+    DCHECK(done_);
     ClearAllResults();
   } else if (input.text().empty()) {
     // User typed "?" alone.  Give them a placeholder result indicating what
diff --git a/components/omnibox/browser/search_provider.h b/components/omnibox/browser/search_provider.h
index f59b9d4..34060dc 100644
--- a/components/omnibox/browser/search_provider.h
+++ b/components/omnibox/browser/search_provider.h
@@ -196,11 +196,12 @@
   // if suggested relevances cause undesirable behavior. Updates |done_|.
   void UpdateMatches();
 
-  // Check constraints that may be violated by suggested relevances and revises/
-  // rolls back the suggested relevance scores to make all constraints old.
+  // Checks constraints that may be violated by suggested relevances and
+  // revises/rolls back the suggested relevance scores to make all constraints
+  // hold.
   void EnforceConstraints();
 
-  // Record the top suggestion (if any) for future use.  SearchProvider tries
+  // Records the top suggestion (if any) for future use.  SearchProvider tries
   // to ensure that an inline autocomplete suggestion does not change
   // asynchronously.
   void RecordTopSuggestion();
diff --git a/components/omnibox/browser/zero_suggest_provider.cc b/components/omnibox/browser/zero_suggest_provider.cc
index f6e3863..3ab642a 100644
--- a/components/omnibox/browser/zero_suggest_provider.cc
+++ b/components/omnibox/browser/zero_suggest_provider.cc
@@ -81,7 +81,7 @@
 const int kDefaultZeroSuggestRelevance = 100;
 
 // Used for testing whether zero suggest is ever available.
-const char kArbitraryInsecureUrlString[] = "http://www.google.com/";
+constexpr char kArbitraryInsecureUrlString[] = "http://www.google.com/";
 
 }  // namespace
 
diff --git a/components/ownership/owner_settings_service.cc b/components/ownership/owner_settings_service.cc
index 6fbd902..ca969d2 100644
--- a/components/ownership/owner_settings_service.cc
+++ b/components/ownership/owner_settings_service.cc
@@ -137,7 +137,7 @@
 bool OwnerSettingsService::SetString(const std::string& setting,
                                      const std::string& value) {
   DCHECK(thread_checker_.CalledOnValidThread());
-  base::StringValue in_value(value);
+  base::Value in_value(value);
   return Set(setting, in_value);
 }
 
diff --git a/components/password_manager/core/browser/browser_save_password_progress_logger.cc b/components/password_manager/core/browser/browser_save_password_progress_logger.cc
index db8803d..e2523ec7 100644
--- a/components/password_manager/core/browser/browser_save_password_progress_logger.cc
+++ b/components/password_manager/core/browser/browser_save_password_progress_logger.cc
@@ -161,7 +161,7 @@
 
 void BrowserSavePasswordProgressLogger::LogString(StringID label,
                                                   const std::string& s) {
-  LogValue(label, base::StringValue(s));
+  LogValue(label, base::Value(s));
 }
 
 void BrowserSavePasswordProgressLogger::SendLog(const std::string& log) {
diff --git a/components/payments/content/payment_request_web_contents_manager.h b/components/payments/content/payment_request_web_contents_manager.h
index 5232314..2c94216 100644
--- a/components/payments/content/payment_request_web_contents_manager.h
+++ b/components/payments/content/payment_request_web_contents_manager.h
@@ -52,7 +52,7 @@
  private:
   explicit PaymentRequestWebContentsManager(content::WebContents* web_contents);
   friend class content::WebContentsUserData<PaymentRequestWebContentsManager>;
-  friend class PaymentRequestInteractiveTestBase;
+  friend class PaymentRequestBrowserTestBase;
 
   // Owns all the PaymentRequest for this WebContents. Since the
   // PaymentRequestWebContentsManager's lifetime is tied to the WebContents,
diff --git a/components/plugins/renderer/loadable_plugin_placeholder.cc b/components/plugins/renderer/loadable_plugin_placeholder.cc
index 8bffae8..355dc7d 100644
--- a/components/plugins/renderer/loadable_plugin_placeholder.cc
+++ b/components/plugins/renderer/loadable_plugin_placeholder.cc
@@ -338,7 +338,7 @@
 
   std::unique_ptr<content::V8ValueConverter> converter(
       content::V8ValueConverter::create());
-  base::StringValue value("placeholderReady");
+  base::Value value("placeholderReady");
   blink::WebSerializedScriptValue message_data =
       blink::WebSerializedScriptValue::serialize(converter->ToV8Value(
           &value, element.document().frame()->mainWorldScriptContext()));
diff --git a/components/policy/core/browser/android/policy_converter.cc b/components/policy/core/browser/android/policy_converter.cc
index ef46e598..9460fa2 100644
--- a/components/policy/core/browser/android/policy_converter.cc
+++ b/components/policy/core/browser/android/policy_converter.cc
@@ -74,7 +74,7 @@
                                       const JavaRef<jstring>& value) {
   SetPolicyValue(
       ConvertJavaStringToUTF8(env, policyKey),
-      base::MakeUnique<base::StringValue>(ConvertJavaStringToUTF8(env, value)));
+      base::MakeUnique<base::Value>(ConvertJavaStringToUTF8(env, value)));
 }
 
 void PolicyConverter::SetPolicyStringArray(JNIEnv* env,
diff --git a/components/policy/core/browser/android/policy_converter_unittest.cc b/components/policy/core/browser/android/policy_converter_unittest.cc
index 3f522420..01fb7df 100644
--- a/components/policy/core/browser/android/policy_converter_unittest.cc
+++ b/components/policy/core/browser/android/policy_converter_unittest.cc
@@ -15,7 +15,6 @@
 
 using base::DictionaryValue;
 using base::ListValue;
-using base::StringValue;
 using base::Value;
 using base::android::JavaRef;
 using base::android::ScopedJavaLocalRef;
@@ -99,7 +98,7 @@
   Schema null_schema = schema_.GetKnownProperty("null");
   ASSERT_TRUE(null_schema.valid());
 
-  EXPECT_EQ("null", Convert(new StringValue("foo"), null_schema));
+  EXPECT_EQ("null", Convert(new Value("foo"), null_schema));
 }
 
 TEST_F(PolicyConverterTest, ConvertToBoolValue) {
@@ -108,14 +107,14 @@
 
   EXPECT_EQ("true", Convert(new Value(true), bool_schema));
   EXPECT_EQ("false", Convert(new Value(false), bool_schema));
-  EXPECT_EQ("true", Convert(new StringValue("true"), bool_schema));
-  EXPECT_EQ("false", Convert(new StringValue("false"), bool_schema));
-  EXPECT_EQ("\"narf\"", Convert(new StringValue("narf"), bool_schema));
+  EXPECT_EQ("true", Convert(new Value("true"), bool_schema));
+  EXPECT_EQ("false", Convert(new Value("false"), bool_schema));
+  EXPECT_EQ("\"narf\"", Convert(new Value("narf"), bool_schema));
   EXPECT_EQ("false", Convert(new Value(0), bool_schema));
   EXPECT_EQ("true", Convert(new Value(1), bool_schema));
   EXPECT_EQ("true", Convert(new Value(42), bool_schema));
   EXPECT_EQ("true", Convert(new Value(-1), bool_schema));
-  EXPECT_EQ("\"1\"", Convert(new StringValue("1"), bool_schema));
+  EXPECT_EQ("\"1\"", Convert(new Value("1"), bool_schema));
   EXPECT_EQ("{}", Convert(new DictionaryValue(), bool_schema));
 }
 
@@ -124,9 +123,9 @@
   ASSERT_TRUE(int_schema.valid());
 
   EXPECT_EQ("23", Convert(new Value(23), int_schema));
-  EXPECT_EQ("42", Convert(new StringValue("42"), int_schema));
-  EXPECT_EQ("-1", Convert(new StringValue("-1"), int_schema));
-  EXPECT_EQ("\"poit\"", Convert(new StringValue("poit"), int_schema));
+  EXPECT_EQ("42", Convert(new Value("42"), int_schema));
+  EXPECT_EQ("-1", Convert(new Value("-1"), int_schema));
+  EXPECT_EQ("\"poit\"", Convert(new Value("poit"), int_schema));
   EXPECT_EQ("false", Convert(new Value(false), int_schema));
 }
 
@@ -136,8 +135,8 @@
 
   EXPECT_EQ("3", Convert(new Value(3), double_schema));
   EXPECT_EQ("3.14", Convert(new Value(3.14), double_schema));
-  EXPECT_EQ("2.71", Convert(new StringValue("2.71"), double_schema));
-  EXPECT_EQ("\"zort\"", Convert(new StringValue("zort"), double_schema));
+  EXPECT_EQ("2.71", Convert(new Value("2.71"), double_schema));
+  EXPECT_EQ("\"zort\"", Convert(new Value("zort"), double_schema));
   EXPECT_EQ("true", Convert(new Value(true), double_schema));
 }
 
@@ -145,7 +144,7 @@
   Schema string_schema = schema_.GetKnownProperty("string");
   ASSERT_TRUE(string_schema.valid());
 
-  EXPECT_EQ("\"troz\"", Convert(new StringValue("troz"), string_schema));
+  EXPECT_EQ("\"troz\"", Convert(new Value("troz"), string_schema));
   EXPECT_EQ("4711", Convert(new Value(4711), string_schema));
 }
 
@@ -158,8 +157,8 @@
   list->AppendString("bar");
   EXPECT_EQ("[\"foo\",\"bar\"]", Convert(list, list_schema));
   EXPECT_EQ("[\"baz\",\"blurp\"]",
-            Convert(new StringValue("[\"baz\", \"blurp\"]"), list_schema));
-  EXPECT_EQ("\"hurz\"", Convert(new StringValue("hurz"), list_schema));
+            Convert(new Value("[\"baz\", \"blurp\"]"), list_schema));
+  EXPECT_EQ("\"hurz\"", Convert(new Value("hurz"), list_schema));
   EXPECT_EQ("19", Convert(new Value(19), list_schema));
 }
 
@@ -180,8 +179,8 @@
   dict->SetInteger("thx", 1138);
   EXPECT_EQ("{\"thx\":1138}", Convert(dict, dict_schema));
   EXPECT_EQ("{\"moose\":true}",
-            Convert(new StringValue("{\"moose\": true}"), dict_schema));
-  EXPECT_EQ("\"fnord\"", Convert(new StringValue("fnord"), dict_schema));
+            Convert(new Value("{\"moose\": true}"), dict_schema));
+  EXPECT_EQ("\"fnord\"", Convert(new Value("fnord"), dict_schema));
   EXPECT_EQ("1729", Convert(new Value(1729), dict_schema));
 }
 
diff --git a/components/policy/core/browser/configuration_policy_handler_unittest.cc b/components/policy/core/browser/configuration_policy_handler_unittest.cc
index 629a5c24..5a07756 100644
--- a/components/policy/core/browser/configuration_policy_handler_unittest.cc
+++ b/components/policy/core/browser/configuration_policy_handler_unittest.cc
@@ -85,8 +85,8 @@
   EXPECT_FALSE(errors.GetErrors(kTestPolicy).empty());
 
   policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-                 POLICY_SOURCE_CLOUD,
-                 base::MakeUnique<base::StringValue>("no list"), NULL);
+                 POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>("no list"),
+                 NULL);
   errors.Clear();
   EXPECT_FALSE(handler.CheckPolicySettings(policy_map, &errors));
   EXPECT_FALSE(errors.empty());
@@ -175,8 +175,8 @@
   // Check that an entirely invalid value is rejected and yields an error
   // message.
   policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-                 POLICY_SOURCE_CLOUD,
-                 base::MakeUnique<base::StringValue>("invalid"), nullptr);
+                 POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>("invalid"),
+                 nullptr);
   errors.Clear();
   EXPECT_FALSE(handler.CheckPolicySettings(policy_map, &errors));
   EXPECT_FALSE(errors.empty());
@@ -231,8 +231,8 @@
   // Check that an entirely invalid value is rejected and yields an error
   // message.
   policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-                 POLICY_SOURCE_CLOUD,
-                 base::MakeUnique<base::StringValue>("invalid"), nullptr);
+                 POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>("invalid"),
+                 nullptr);
   errors.Clear();
   EXPECT_FALSE(handler.CheckPolicySettings(policy_map, &errors));
   EXPECT_FALSE(errors.empty());
@@ -386,8 +386,8 @@
   // Check that an entirely invalid value is rejected and yields an error
   // message.
   policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-                 POLICY_SOURCE_CLOUD,
-                 base::MakeUnique<base::StringValue>("invalid"), nullptr);
+                 POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>("invalid"),
+                 nullptr);
   errors.Clear();
   EXPECT_FALSE(handler.CheckPolicySettings(policy_map, &errors));
   EXPECT_FALSE(errors.empty());
@@ -443,8 +443,8 @@
   // Check that an entirely invalid value is rejected and yields an error
   // message.
   policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-                 POLICY_SOURCE_CLOUD,
-                 base::MakeUnique<base::StringValue>("invalid"), nullptr);
+                 POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>("invalid"),
+                 nullptr);
   errors.Clear();
   EXPECT_FALSE(handler.CheckPolicySettings(policy_map, &errors));
   EXPECT_FALSE(errors.empty());
diff --git a/components/policy/core/browser/configuration_policy_pref_store_unittest.cc b/components/policy/core/browser/configuration_policy_pref_store_unittest.cc
index 13513e5..7092fa27 100644
--- a/components/policy/core/browser/configuration_policy_pref_store_unittest.cc
+++ b/components/policy/core/browser/configuration_policy_pref_store_unittest.cc
@@ -87,13 +87,12 @@
   PolicyMap policy;
   policy.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
              POLICY_SOURCE_CLOUD,
-             base::MakeUnique<base::StringValue>("http://chromium.org"),
-             nullptr);
+             base::MakeUnique<base::Value>("http://chromium.org"), nullptr);
   UpdateProviderPolicy(policy);
   const base::Value* value = NULL;
   EXPECT_TRUE(store_->GetValue(kTestPref, &value));
   ASSERT_TRUE(value);
-  EXPECT_TRUE(base::StringValue("http://chromium.org").Equals(value));
+  EXPECT_TRUE(base::Value("http://chromium.org").Equals(value));
 }
 
 // Test cases for boolean-valued policy settings.
@@ -186,12 +185,11 @@
   PolicyMap policy;
   policy.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
              POLICY_SOURCE_CLOUD,
-             base::MakeUnique<base::StringValue>("http://www.chromium.org"),
-             nullptr);
+             base::MakeUnique<base::Value>("http://www.chromium.org"), nullptr);
   UpdateProviderPolicy(policy);
   observer_.VerifyAndResetChangedKey(kTestPref);
   EXPECT_TRUE(store_->GetValue(kTestPref, &value));
-  EXPECT_TRUE(base::StringValue("http://www.chromium.org").Equals(value));
+  EXPECT_TRUE(base::Value("http://www.chromium.org").Equals(value));
 
   UpdateProviderPolicy(policy);
   EXPECT_TRUE(observer_.changed_keys.empty());
diff --git a/components/policy/core/browser/proxy_policy_handler_unittest.cc b/components/policy/core/browser/proxy_policy_handler_unittest.cc
index 9f261da..6a70b7f 100644
--- a/components/policy/core/browser/proxy_policy_handler_unittest.cc
+++ b/components/policy/core/browser/proxy_policy_handler_unittest.cc
@@ -77,12 +77,12 @@
 TEST_F(ProxyPolicyHandlerTest, ManualOptions) {
   PolicyMap policy;
   policy.Set(key::kProxyBypassList, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             POLICY_SOURCE_CLOUD, base::MakeUnique<base::StringValue>(
-                                      "http://chromium.org/override"),
+             POLICY_SOURCE_CLOUD,
+             base::MakeUnique<base::Value>("http://chromium.org/override"),
              nullptr);
   policy.Set(key::kProxyServer, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             POLICY_SOURCE_CLOUD,
-             base::MakeUnique<base::StringValue>("chromium.org"), nullptr);
+             POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>("chromium.org"),
+             nullptr);
   policy.Set(
       key::kProxyServerMode, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
       POLICY_SOURCE_CLOUD,
@@ -106,12 +106,12 @@
           ProxyPolicyHandler::PROXY_MANUALLY_CONFIGURED_PROXY_SERVER_MODE),
       nullptr);
   policy.Set(key::kProxyBypassList, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             POLICY_SOURCE_CLOUD, base::MakeUnique<base::StringValue>(
-                                      "http://chromium.org/override"),
+             POLICY_SOURCE_CLOUD,
+             base::MakeUnique<base::Value>("http://chromium.org/override"),
              nullptr);
   policy.Set(key::kProxyServer, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             POLICY_SOURCE_CLOUD,
-             base::MakeUnique<base::StringValue>("chromium.org"), nullptr);
+             POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>("chromium.org"),
+             nullptr);
   UpdateProviderPolicy(policy);
 
   VerifyProxyPrefs("chromium.org",
@@ -149,8 +149,8 @@
 TEST_F(ProxyPolicyHandlerTest, NoProxyModeName) {
   PolicyMap policy;
   policy.Set(key::kProxyMode, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             POLICY_SOURCE_CLOUD, base::MakeUnique<base::StringValue>(
-                                      ProxyPrefs::kDirectProxyModeName),
+             POLICY_SOURCE_CLOUD,
+             base::MakeUnique<base::Value>(ProxyPrefs::kDirectProxyModeName),
              nullptr);
   UpdateProviderPolicy(policy);
   VerifyProxyPrefs(
@@ -173,10 +173,11 @@
 
 TEST_F(ProxyPolicyHandlerTest, AutoDetectProxyModeName) {
   PolicyMap policy;
-  policy.Set(key::kProxyMode, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             POLICY_SOURCE_CLOUD, base::MakeUnique<base::StringValue>(
-                                      ProxyPrefs::kAutoDetectProxyModeName),
-             nullptr);
+  policy.Set(
+      key::kProxyMode, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+      POLICY_SOURCE_CLOUD,
+      base::MakeUnique<base::Value>(ProxyPrefs::kAutoDetectProxyModeName),
+      nullptr);
   UpdateProviderPolicy(policy);
   VerifyProxyPrefs(std::string(),
                    std::string(),
@@ -188,11 +189,11 @@
   PolicyMap policy;
   policy.Set(key::kProxyPacUrl, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
              POLICY_SOURCE_CLOUD,
-             base::MakeUnique<base::StringValue>("http://short.org/proxy.pac"),
+             base::MakeUnique<base::Value>("http://short.org/proxy.pac"),
              nullptr);
   policy.Set(key::kProxyMode, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             POLICY_SOURCE_CLOUD, base::MakeUnique<base::StringValue>(
-                                      ProxyPrefs::kPacScriptProxyModeName),
+             POLICY_SOURCE_CLOUD,
+             base::MakeUnique<base::Value>(ProxyPrefs::kPacScriptProxyModeName),
              nullptr);
   UpdateProviderPolicy(policy);
   VerifyProxyPrefs(std::string(),
@@ -204,8 +205,8 @@
 TEST_F(ProxyPolicyHandlerTest, PacScriptProxyModeInvalid) {
   PolicyMap policy;
   policy.Set(key::kProxyMode, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             POLICY_SOURCE_CLOUD, base::MakeUnique<base::StringValue>(
-                                      ProxyPrefs::kPacScriptProxyModeName),
+             POLICY_SOURCE_CLOUD,
+             base::MakeUnique<base::Value>(ProxyPrefs::kPacScriptProxyModeName),
              NULL);
   UpdateProviderPolicy(policy);
   const base::Value* value = NULL;
@@ -218,16 +219,16 @@
   PolicyMap policy;
   policy.Set(key::kProxyServer, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
              POLICY_SOURCE_CLOUD,
-             base::WrapUnique(new base::StringValue(std::string())), nullptr);
-  policy.Set(
-      key::kProxyPacUrl, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-      POLICY_SOURCE_CLOUD,
-      base::WrapUnique(new base::StringValue("http://short.org/proxy.pac")),
-      nullptr);
-  policy.Set(key::kProxyMode, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             POLICY_SOURCE_CLOUD, base::WrapUnique(new base::StringValue(
-                                      ProxyPrefs::kPacScriptProxyModeName)),
+             base::WrapUnique(new base::Value(std::string())), nullptr);
+  policy.Set(key::kProxyPacUrl, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+             POLICY_SOURCE_CLOUD,
+             base::WrapUnique(new base::Value("http://short.org/proxy.pac")),
              nullptr);
+  policy.Set(
+      key::kProxyMode, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+      POLICY_SOURCE_CLOUD,
+      base::WrapUnique(new base::Value(ProxyPrefs::kPacScriptProxyModeName)),
+      nullptr);
   UpdateProviderPolicy(policy);
   VerifyProxyPrefs(std::string(),
                    "http://short.org/proxy.pac",
@@ -250,8 +251,8 @@
 TEST_F(ProxyPolicyHandlerTest, UseSystemProxyMode) {
   PolicyMap policy;
   policy.Set(key::kProxyMode, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             POLICY_SOURCE_CLOUD, base::MakeUnique<base::StringValue>(
-                                      ProxyPrefs::kSystemProxyModeName),
+             POLICY_SOURCE_CLOUD,
+             base::MakeUnique<base::Value>(ProxyPrefs::kSystemProxyModeName),
              nullptr);
   UpdateProviderPolicy(policy);
   VerifyProxyPrefs(
@@ -266,10 +267,11 @@
       POLICY_SOURCE_CLOUD,
       base::MakeUnique<base::Value>(ProxyPolicyHandler::PROXY_SERVER_MODE),
       nullptr);
-  policy.Set(key::kProxyMode, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             POLICY_SOURCE_CLOUD, base::MakeUnique<base::StringValue>(
-                                      ProxyPrefs::kAutoDetectProxyModeName),
-             nullptr);
+  policy.Set(
+      key::kProxyMode, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+      POLICY_SOURCE_CLOUD,
+      base::MakeUnique<base::Value>(ProxyPrefs::kAutoDetectProxyModeName),
+      nullptr);
   UpdateProviderPolicy(policy);
   VerifyProxyPrefs(std::string(),
                    std::string(),
@@ -282,15 +284,15 @@
   PolicyMap policy;
   policy.Set(key::kProxyPacUrl, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
              POLICY_SOURCE_CLOUD,
-             base::MakeUnique<base::StringValue>("http://short.org/proxy.pac"),
+             base::MakeUnique<base::Value>("http://short.org/proxy.pac"),
              nullptr);
   policy.Set(key::kProxyBypassList, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             POLICY_SOURCE_CLOUD, base::MakeUnique<base::StringValue>(
-                                      "http://chromium.org/override"),
+             POLICY_SOURCE_CLOUD,
+             base::MakeUnique<base::Value>("http://chromium.org/override"),
              nullptr);
   policy.Set(key::kProxyServer, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             POLICY_SOURCE_CLOUD,
-             base::MakeUnique<base::StringValue>("chromium.org"), nullptr);
+             POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>("chromium.org"),
+             nullptr);
   for (int i = 0; i < ProxyPolicyHandler::MODE_COUNT; ++i) {
     policy.Set(key::kProxyServerMode, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
                POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>(i), nullptr);
diff --git a/components/policy/core/common/async_policy_provider_unittest.cc b/components/policy/core/common/async_policy_provider_unittest.cc
index 3972542..5365465 100644
--- a/components/policy/core/common/async_policy_provider_unittest.cc
+++ b/components/policy/core/common/async_policy_provider_unittest.cc
@@ -34,7 +34,7 @@
                const std::string& value) {
   bundle->Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
       .Set(name, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-           POLICY_SOURCE_PLATFORM, base::MakeUnique<base::StringValue>(value),
+           POLICY_SOURCE_PLATFORM, base::MakeUnique<base::Value>(value),
            nullptr);
 }
 
diff --git a/components/policy/core/common/cloud/cloud_policy_manager_unittest.cc b/components/policy/core/common/cloud/cloud_policy_manager_unittest.cc
index 836b15c..ad47f9a 100644
--- a/components/policy/core/common/cloud/cloud_policy_manager_unittest.cc
+++ b/components/policy/core/common/cloud/cloud_policy_manager_unittest.cc
@@ -88,9 +88,9 @@
 
 void TestHarness::InstallStringPolicy(const std::string& policy_name,
                                       const std::string& policy_value) {
-  store_.policy_map_.Set(
-      policy_name, policy_level(), policy_scope(), POLICY_SOURCE_CLOUD,
-      base::MakeUnique<base::StringValue>(policy_value), nullptr);
+  store_.policy_map_.Set(policy_name, policy_level(), policy_scope(),
+                         POLICY_SOURCE_CLOUD,
+                         base::MakeUnique<base::Value>(policy_value), nullptr);
 }
 
 void TestHarness::InstallIntegerPolicy(const std::string& policy_name,
@@ -174,8 +174,8 @@
   void SetUp() override {
     // Set up a policy map for testing.
     policy_map_.Set("key", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-                    POLICY_SOURCE_CLOUD,
-                    base::MakeUnique<base::StringValue>("value"), nullptr);
+                    POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>("value"),
+                    nullptr);
     expected_bundle_.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
         .CopyFrom(policy_map_);
 
diff --git a/components/policy/core/common/cloud/component_cloud_policy_service_unittest.cc b/components/policy/core/common/cloud/component_cloud_policy_service_unittest.cc
index 987dae0..423d401 100644
--- a/components/policy/core/common/cloud/component_cloud_policy_service_unittest.cc
+++ b/components/policy/core/common/cloud/component_cloud_policy_service_unittest.cc
@@ -128,12 +128,12 @@
 
     public_key_ = builder_.GetPublicSigningKeyAsString();
 
-    expected_policy_.Set(
-        "Name", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-        base::MakeUnique<base::StringValue>("disabled"), nullptr);
+    expected_policy_.Set("Name", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+                         POLICY_SOURCE_CLOUD,
+                         base::MakeUnique<base::Value>("disabled"), nullptr);
     expected_policy_.Set("Second", POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER,
                          POLICY_SOURCE_CLOUD,
-                         base::MakeUnique<base::StringValue>("maybe"), nullptr);
+                         base::MakeUnique<base::Value>("maybe"), nullptr);
   }
 
   void SetUp() override {
@@ -596,8 +596,8 @@
   PolicyBundle expected_bundle;
   expected_bundle.Get(kTestExtensionNS)
       .Set("Name", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-           POLICY_SOURCE_CLOUD,
-           base::MakeUnique<base::StringValue>("published"), nullptr);
+           POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>("published"),
+           nullptr);
   EXPECT_TRUE(service_->policy().Equals(expected_bundle));
 }
 
diff --git a/components/policy/core/common/cloud/component_cloud_policy_store_unittest.cc b/components/policy/core/common/cloud/component_cloud_policy_store_unittest.cc
index 21ecc43..e891c3f 100644
--- a/components/policy/core/common/cloud/component_cloud_policy_store_unittest.cc
+++ b/components/policy/core/common/cloud/component_cloud_policy_store_unittest.cc
@@ -88,11 +88,11 @@
 
     PolicyMap& policy = expected_bundle_.Get(kTestPolicyNS);
     policy.Set("Name", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-               POLICY_SOURCE_CLOUD,
-               base::MakeUnique<base::StringValue>("disabled"), nullptr);
+               POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>("disabled"),
+               nullptr);
     policy.Set("Second", POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER,
-               POLICY_SOURCE_CLOUD,
-               base::MakeUnique<base::StringValue>("maybe"), nullptr);
+               POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>("maybe"),
+               nullptr);
   }
 
   void SetUp() override {
diff --git a/components/policy/core/common/cloud/component_cloud_policy_updater_unittest.cc b/components/policy/core/common/cloud/component_cloud_policy_updater_unittest.cc
index e7a28e0..28fad2f 100644
--- a/components/policy/core/common/cloud/component_cloud_policy_updater_unittest.cc
+++ b/components/policy/core/common/cloud/component_cloud_policy_updater_unittest.cc
@@ -106,10 +106,10 @@
 
   PolicyMap& policy = expected_bundle_.Get(kTestPolicyNS);
   policy.Set("Name", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-             POLICY_SOURCE_CLOUD,
-             base::MakeUnique<base::StringValue>("disabled"), nullptr);
+             POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>("disabled"),
+             nullptr);
   policy.Set("Second", POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER,
-             POLICY_SOURCE_CLOUD, base::MakeUnique<base::StringValue>("maybe"),
+             POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>("maybe"),
              nullptr);
 }
 
diff --git a/components/policy/core/common/cloud/user_cloud_policy_manager_unittest.cc b/components/policy/core/common/cloud/user_cloud_policy_manager_unittest.cc
index aea3c44..b6964f2 100644
--- a/components/policy/core/common/cloud/user_cloud_policy_manager_unittest.cc
+++ b/components/policy/core/common/cloud/user_cloud_policy_manager_unittest.cc
@@ -36,8 +36,8 @@
   void SetUp() override {
     // Set up a policy map for testing.
     policy_map_.Set("key", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-                    POLICY_SOURCE_CLOUD,
-                    base::MakeUnique<base::StringValue>("value"), nullptr);
+                    POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>("value"),
+                    nullptr);
     expected_bundle_.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
         .CopyFrom(policy_map_);
   }
diff --git a/components/policy/core/common/configuration_policy_provider_test.cc b/components/policy/core/common/configuration_policy_provider_test.cc
index 93254d6..ad5c264 100644
--- a/components/policy/core/common/configuration_policy_provider_test.cc
+++ b/components/policy/core/common/configuration_policy_provider_test.cc
@@ -253,7 +253,7 @@
 
 TEST_P(ConfigurationPolicyProviderTest, StringValue) {
   const char kTestString[] = "string_value";
-  base::StringValue expected_value(kTestString);
+  base::Value expected_value(kTestString);
   CheckValue(test_keys::kKeyString,
              expected_value,
              base::Bind(&PolicyProviderTestHarness::InstallStringPolicy,
@@ -284,8 +284,8 @@
 
 TEST_P(ConfigurationPolicyProviderTest, StringListValue) {
   base::ListValue expected_value;
-  expected_value.Set(0U, new base::StringValue("first"));
-  expected_value.Set(1U, new base::StringValue("second"));
+  expected_value.Set(0U, new base::Value("first"));
+  expected_value.Set(1U, new base::Value("second"));
   CheckValue(test_keys::kKeyStringList,
              expected_value,
              base::Bind(&PolicyProviderTestHarness::InstallStringListPolicy,
@@ -302,8 +302,8 @@
   expected_value.SetString("string", "omg");
 
   base::ListValue* list = new base::ListValue();
-  list->Set(0U, new base::StringValue("first"));
-  list->Set(1U, new base::StringValue("second"));
+  list->Set(0U, new base::Value("first"));
+  list->Set(1U, new base::Value("second"));
   expected_value.Set("array", list);
 
   base::DictionaryValue* dict = new base::DictionaryValue();
@@ -352,7 +352,7 @@
   bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
       .Set(test_keys::kKeyString, test_harness_->policy_level(),
            test_harness_->policy_scope(), test_harness_->policy_source(),
-           base::MakeUnique<base::StringValue>("value"), nullptr);
+           base::MakeUnique<base::Value>("value"), nullptr);
   EXPECT_TRUE(provider_->policies().Equals(bundle));
   provider_->RemoveObserver(&observer);
 }
@@ -393,7 +393,7 @@
   // help detecting memory leaks in the code paths that detect invalid input.
   policy_3rdparty.Set("invalid-domain.component", policy_dict.DeepCopy());
   policy_3rdparty.Set("extensions.cccccccccccccccccccccccccccccccc",
-                      new base::StringValue("invalid-value"));
+                      new base::Value("invalid-value"));
   test_harness_->Install3rdPartyPolicy(&policy_3rdparty);
 
   provider_->RefreshPolicies();
diff --git a/components/policy/core/common/generate_policy_source_unittest.cc b/components/policy/core/common/generate_policy_source_unittest.cc
index 2e2a91f..8ea85fd 100644
--- a/components/policy/core/common/generate_policy_source_unittest.cc
+++ b/components/policy/core/common/generate_policy_source_unittest.cc
@@ -214,17 +214,17 @@
 
   const base::Value* multiprof_behavior =
       policy_map.GetValue(key::kChromeOsMultiProfileUserBehavior);
-  base::StringValue expected("primary-only");
+  base::Value expected("primary-only");
   EXPECT_TRUE(expected.Equals(multiprof_behavior));
 
   // If policy already configured, it's not changed to enterprise defaults.
   policy_map.Set(key::kChromeOsMultiProfileUserBehavior, POLICY_LEVEL_MANDATORY,
                  POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-                 base::MakeUnique<base::StringValue>("test_value"), nullptr);
+                 base::MakeUnique<base::Value>("test_value"), nullptr);
   SetEnterpriseUsersDefaults(&policy_map);
   multiprof_behavior =
       policy_map.GetValue(key::kChromeOsMultiProfileUserBehavior);
-  expected = base::StringValue("test_value");
+  expected = base::Value("test_value");
   EXPECT_TRUE(expected.Equals(multiprof_behavior));
 }
 #endif
diff --git a/components/policy/core/common/mac_util.cc b/components/policy/core/common/mac_util.cc
index dd06e1e..04167e00 100644
--- a/components/policy/core/common/mac_util.cc
+++ b/components/policy/core/common/mac_util.cc
@@ -71,7 +71,7 @@
 
   if (CFStringRef string = CFCast<CFStringRef>(property)) {
     return std::unique_ptr<base::Value>(
-        new base::StringValue(base::SysCFStringRefToUTF8(string)));
+        new base::Value(base::SysCFStringRefToUTF8(string)));
   }
 
   if (CFDictionaryRef dict = CFCast<CFDictionaryRef>(property)) {
diff --git a/components/policy/core/common/policy_bundle_unittest.cc b/components/policy/core/common/policy_bundle_unittest.cc
index e15abc3..91938437 100644
--- a/components/policy/core/common/policy_bundle_unittest.cc
+++ b/components/policy/core/common/policy_bundle_unittest.cc
@@ -34,7 +34,7 @@
   policy->Set("mandatory-user", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
               POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>(123), nullptr);
   policy->Set("mandatory-machine", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
-              POLICY_SOURCE_CLOUD, base::MakeUnique<base::StringValue>("omg"),
+              POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>("omg"),
               nullptr);
   policy->Set("recommended-user", POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER,
               POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>(true),
diff --git a/components/policy/core/common/policy_loader_ios_unittest.mm b/components/policy/core/common/policy_loader_ios_unittest.mm
index ef52acc..3f599f2 100644
--- a/components/policy/core/common/policy_loader_ios_unittest.mm
+++ b/components/policy/core/common/policy_loader_ios_unittest.mm
@@ -256,11 +256,9 @@
   PolicyMap& expectedMap =
       expected.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, ""));
   expectedMap.Set("shared", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
-                  POLICY_SOURCE_PLATFORM, new base::StringValue("right"),
-                  nullptr);
+                  POLICY_SOURCE_PLATFORM, new base::Value("right"), nullptr);
   expectedMap.Set("key2", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
-                  POLICY_SOURCE_PLATFORM, new base::StringValue("value2"),
-                  nullptr);
+                  POLICY_SOURCE_PLATFORM, new base::Value("value2"), nullptr);
 
   scoped_refptr<base::TestSimpleTaskRunner> taskRunner =
       new base::TestSimpleTaskRunner();
diff --git a/components/policy/core/common/policy_loader_mac_unittest.cc b/components/policy/core/common/policy_loader_mac_unittest.cc
index 7f3c14f..a9d636f 100644
--- a/components/policy/core/common/policy_loader_mac_unittest.cc
+++ b/components/policy/core/common/policy_loader_mac_unittest.cc
@@ -199,7 +199,7 @@
   expected_bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
       .Set(test_keys::kKeyString, POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER,
            POLICY_SOURCE_PLATFORM,
-           base::MakeUnique<base::StringValue>("string value"), nullptr);
+           base::MakeUnique<base::Value>("string value"), nullptr);
   EXPECT_TRUE(provider_->policies().Equals(expected_bundle));
 }
 
diff --git a/components/policy/core/common/policy_loader_win_unittest.cc b/components/policy/core/common/policy_loader_win_unittest.cc
index 1e06bd8..df67893 100644
--- a/components/policy/core/common/policy_loader_win_unittest.cc
+++ b/components/policy/core/common/policy_loader_win_unittest.cc
@@ -812,7 +812,7 @@
   PolicyBundle expected;
   expected.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
       .Set(test_keys::kKeyString, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
-           POLICY_SOURCE_PLATFORM, base::MakeUnique<base::StringValue>("hklm"),
+           POLICY_SOURCE_PLATFORM, base::MakeUnique<base::Value>("hklm"),
            nullptr);
   EXPECT_TRUE(Matches(expected));
 }
@@ -865,17 +865,17 @@
   PolicyMap& expected_policy = expected.Get(ns);
   expected_policy.Set(
       "a", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, POLICY_SOURCE_PLATFORM,
-      base::MakeUnique<base::StringValue>(kMachineMandatory), nullptr);
-  expected_policy.Set(
-      "b", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, POLICY_SOURCE_PLATFORM,
-      base::MakeUnique<base::StringValue>(kUserMandatory), nullptr);
+      base::MakeUnique<base::Value>(kMachineMandatory), nullptr);
+  expected_policy.Set("b", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+                      POLICY_SOURCE_PLATFORM,
+                      base::MakeUnique<base::Value>(kUserMandatory), nullptr);
   expected_policy.Set("c", POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_MACHINE,
                       POLICY_SOURCE_PLATFORM,
-                      base::MakeUnique<base::StringValue>(kMachineRecommended),
+                      base::MakeUnique<base::Value>(kMachineRecommended),
                       nullptr);
-  expected_policy.Set(
-      "d", POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER, POLICY_SOURCE_PLATFORM,
-      base::MakeUnique<base::StringValue>(kUserRecommended), nullptr);
+  expected_policy.Set("d", POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER,
+                      POLICY_SOURCE_PLATFORM,
+                      base::MakeUnique<base::Value>(kUserRecommended), nullptr);
   EXPECT_TRUE(Matches(expected));
 }
 
diff --git a/components/policy/core/common/policy_map_unittest.cc b/components/policy/core/common/policy_map_unittest.cc
index 638fa4e..5c49dfdc 100644
--- a/components/policy/core/common/policy_map_unittest.cc
+++ b/components/policy/core/common/policy_map_unittest.cc
@@ -59,11 +59,11 @@
 
 TEST_F(PolicyMapTest, SetAndGet) {
   PolicyMap map;
-  SetPolicy(&map, kTestPolicyName1, base::MakeUnique<base::StringValue>("aaa"));
-  base::StringValue expected("aaa");
+  SetPolicy(&map, kTestPolicyName1, base::MakeUnique<base::Value>("aaa"));
+  base::Value expected("aaa");
   EXPECT_TRUE(expected.Equals(map.GetValue(kTestPolicyName1)));
-  SetPolicy(&map, kTestPolicyName1, base::MakeUnique<base::StringValue>("bbb"));
-  base::StringValue expected_b("bbb");
+  SetPolicy(&map, kTestPolicyName1, base::MakeUnique<base::Value>("bbb"));
+  base::Value expected_b("bbb");
   EXPECT_TRUE(expected_b.Equals(map.GetValue(kTestPolicyName1)));
   SetPolicy(&map, kTestPolicyName1, CreateExternalDataFetcher("dummy"));
   EXPECT_FALSE(map.GetValue(kTestPolicyName1));
@@ -88,13 +88,13 @@
 
 TEST_F(PolicyMapTest, Equals) {
   PolicyMap a;
-  SetPolicy(&a, kTestPolicyName1, base::MakeUnique<base::StringValue>("aaa"));
+  SetPolicy(&a, kTestPolicyName1, base::MakeUnique<base::Value>("aaa"));
   PolicyMap a2;
-  SetPolicy(&a2, kTestPolicyName1, base::MakeUnique<base::StringValue>("aaa"));
+  SetPolicy(&a2, kTestPolicyName1, base::MakeUnique<base::Value>("aaa"));
   PolicyMap b;
-  SetPolicy(&b, kTestPolicyName1, base::MakeUnique<base::StringValue>("bbb"));
+  SetPolicy(&b, kTestPolicyName1, base::MakeUnique<base::Value>("bbb"));
   PolicyMap c;
-  SetPolicy(&c, kTestPolicyName1, base::MakeUnique<base::StringValue>("aaa"));
+  SetPolicy(&c, kTestPolicyName1, base::MakeUnique<base::Value>("aaa"));
   SetPolicy(&c, kTestPolicyName2, base::MakeUnique<base::Value>(true));
   PolicyMap d;
   SetPolicy(&d, kTestPolicyName1, CreateExternalDataFetcher("ddd"));
@@ -136,20 +136,20 @@
 
 TEST_F(PolicyMapTest, Swap) {
   PolicyMap a;
-  SetPolicy(&a, kTestPolicyName1, base::MakeUnique<base::StringValue>("aaa"));
+  SetPolicy(&a, kTestPolicyName1, base::MakeUnique<base::Value>("aaa"));
   SetPolicy(&a, kTestPolicyName2, CreateExternalDataFetcher("dummy"));
   PolicyMap b;
-  SetPolicy(&b, kTestPolicyName1, base::MakeUnique<base::StringValue>("bbb"));
+  SetPolicy(&b, kTestPolicyName1, base::MakeUnique<base::Value>("bbb"));
   SetPolicy(&b, kTestPolicyName3, base::MakeUnique<base::Value>(true));
 
   a.Swap(&b);
-  base::StringValue expected("bbb");
+  base::Value expected("bbb");
   EXPECT_TRUE(expected.Equals(a.GetValue(kTestPolicyName1)));
   base::Value expected_bool(true);
   EXPECT_TRUE(expected_bool.Equals(a.GetValue(kTestPolicyName3)));
   EXPECT_FALSE(a.GetValue(kTestPolicyName2));
   EXPECT_FALSE(a.Get(kTestPolicyName2));
-  base::StringValue expected_a("aaa");
+  base::Value expected_a("aaa");
   EXPECT_TRUE(expected_a.Equals(b.GetValue(kTestPolicyName1)));
   EXPECT_FALSE(b.GetValue(kTestPolicyName3));
   EXPECT_FALSE(a.GetValue(kTestPolicyName2));
@@ -169,7 +169,7 @@
 TEST_F(PolicyMapTest, MergeFrom) {
   PolicyMap a;
   a.Set(kTestPolicyName1, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-        POLICY_SOURCE_CLOUD, base::MakeUnique<base::StringValue>("google.com"),
+        POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>("google.com"),
         nullptr);
   a.Set(kTestPolicyName2, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
         POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>(true), nullptr);
@@ -179,16 +179,16 @@
   a.Set(kTestPolicyName4, POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER,
         POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>(false), nullptr);
   a.Set(kTestPolicyName5, POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_MACHINE,
-        POLICY_SOURCE_CLOUD,
-        base::MakeUnique<base::StringValue>("google.com/q={x}"), nullptr);
+        POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>("google.com/q={x}"),
+        nullptr);
   a.Set(kTestPolicyName7, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
         POLICY_SOURCE_ENTERPRISE_DEFAULT, base::MakeUnique<base::Value>(false),
         nullptr);
 
   PolicyMap b;
   b.Set(kTestPolicyName1, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
-        POLICY_SOURCE_CLOUD,
-        base::MakeUnique<base::StringValue>("chromium.org"), nullptr);
+        POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>("chromium.org"),
+        nullptr);
   b.Set(kTestPolicyName2, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
         POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>(false), nullptr);
   b.Set(kTestPolicyName3, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
@@ -198,8 +198,8 @@
         POLICY_SOURCE_PUBLIC_SESSION_OVERRIDE,
         base::MakeUnique<base::Value>(true), nullptr);
   b.Set(kTestPolicyName5, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
-        POLICY_SOURCE_PLATFORM,
-        base::MakeUnique<base::StringValue>(std::string()), nullptr);
+        POLICY_SOURCE_PLATFORM, base::MakeUnique<base::Value>(std::string()),
+        nullptr);
   b.Set(kTestPolicyName6, POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER,
         POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>(true), nullptr);
   b.Set(kTestPolicyName7, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
@@ -211,8 +211,8 @@
   PolicyMap c;
   // POLICY_SCOPE_MACHINE over POLICY_SCOPE_USER.
   c.Set(kTestPolicyName1, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
-        POLICY_SOURCE_CLOUD,
-        base::MakeUnique<base::StringValue>("chromium.org"), nullptr);
+        POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>("chromium.org"),
+        nullptr);
   // |a| has precedence over |b|.
   c.Set(kTestPolicyName2, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
         POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>(true), nullptr);
@@ -225,8 +225,8 @@
         base::MakeUnique<base::Value>(true), nullptr);
   // POLICY_LEVEL_MANDATORY over POLICY_LEVEL_RECOMMENDED.
   c.Set(kTestPolicyName5, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
-        POLICY_SOURCE_PLATFORM,
-        base::MakeUnique<base::StringValue>(std::string()), nullptr);
+        POLICY_SOURCE_PLATFORM, base::MakeUnique<base::Value>(std::string()),
+        nullptr);
   // Merge new ones.
   c.Set(kTestPolicyName6, POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER,
         POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>(true), nullptr);
@@ -241,7 +241,7 @@
 TEST_F(PolicyMapTest, GetDifferingKeys) {
   PolicyMap a;
   a.Set(kTestPolicyName1, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-        POLICY_SOURCE_CLOUD, base::MakeUnique<base::StringValue>("google.com"),
+        POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>("google.com"),
         nullptr);
   a.Set(kTestPolicyName2, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
         POLICY_SOURCE_CLOUD, nullptr, CreateExternalDataFetcher("dummy"));
@@ -252,14 +252,14 @@
   a.Set(kTestPolicyName5, POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER,
         POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>(false), nullptr);
   a.Set(kTestPolicyName6, POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_MACHINE,
-        POLICY_SOURCE_CLOUD,
-        base::MakeUnique<base::StringValue>("google.com/q={x}"), nullptr);
+        POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>("google.com/q={x}"),
+        nullptr);
   a.Set(kTestPolicyName7, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
         POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>(true), nullptr);
 
   PolicyMap b;
   b.Set(kTestPolicyName1, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-        POLICY_SOURCE_CLOUD, base::MakeUnique<base::StringValue>("google.com"),
+        POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>("google.com"),
         nullptr);
   b.Set(kTestPolicyName2, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
         POLICY_SOURCE_CLOUD, nullptr, CreateExternalDataFetcher("dummy"));
@@ -270,8 +270,8 @@
   b.Set(kTestPolicyName5, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
         POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>(false), nullptr);
   b.Set(kTestPolicyName6, POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER,
-        POLICY_SOURCE_CLOUD,
-        base::MakeUnique<base::StringValue>("google.com/q={x}"), nullptr);
+        POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>("google.com/q={x}"),
+        nullptr);
   b.Set(kTestPolicyName8, POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER,
         POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>(true), nullptr);
 
@@ -315,7 +315,7 @@
   PolicyMap expected;
   expected.Set("TestPolicy1", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
                POLICY_SOURCE_PLATFORM,
-               base::MakeUnique<base::StringValue>("google.com"), nullptr);
+               base::MakeUnique<base::Value>("google.com"), nullptr);
   expected.Set("TestPolicy2", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
                POLICY_SOURCE_PLATFORM, base::MakeUnique<base::Value>(true),
                nullptr);
@@ -332,7 +332,7 @@
 TEST_F(PolicyMapTest, EraseNonmatching) {
   PolicyMap a;
   a.Set(kTestPolicyName1, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-        POLICY_SOURCE_CLOUD, base::MakeUnique<base::StringValue>("google.com"),
+        POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>("google.com"),
         nullptr);
   a.Set(kTestPolicyName2, POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_MACHINE,
         POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>(true), nullptr);
@@ -341,7 +341,7 @@
 
   PolicyMap b;
   b.Set(kTestPolicyName1, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-        POLICY_SOURCE_CLOUD, base::MakeUnique<base::StringValue>("google.com"),
+        POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>("google.com"),
         nullptr);
   EXPECT_TRUE(a.Equals(b));
 }
diff --git a/components/policy/core/common/policy_service_impl_unittest.cc b/components/policy/core/common/policy_service_impl_unittest.cc
index a6b0e978..db9e321 100644
--- a/components/policy/core/common/policy_service_impl_unittest.cc
+++ b/components/policy/core/common/policy_service_impl_unittest.cc
@@ -56,16 +56,16 @@
       &bundle->Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()));
   policy_map->Set(kSameLevelPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
                   POLICY_SOURCE_ENTERPRISE_DEFAULT,
-                  base::MakeUnique<base::StringValue>(value), nullptr);
+                  base::MakeUnique<base::Value>(value), nullptr);
   policy_map->Set(kDiffLevelPolicy, level, scope, POLICY_SOURCE_PLATFORM,
-                  base::MakeUnique<base::StringValue>(value), nullptr);
+                  base::MakeUnique<base::Value>(value), nullptr);
   policy_map =
       &bundle->Get(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, kExtension));
   policy_map->Set(kSameLevelPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
                   POLICY_SOURCE_ENTERPRISE_DEFAULT,
-                  base::MakeUnique<base::StringValue>(value), nullptr);
+                  base::MakeUnique<base::Value>(value), nullptr);
   policy_map->Set(kDiffLevelPolicy, level, scope, POLICY_SOURCE_PLATFORM,
-                  base::MakeUnique<base::StringValue>(value), nullptr);
+                  base::MakeUnique<base::Value>(value), nullptr);
 }
 
 // Observer class that changes the policy in the passed provider when the
@@ -267,8 +267,8 @@
   PolicyMap policy_map;
   policy_map.CopyFrom(previous_policy_map);
   policy_map.Set("policy", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-                 POLICY_SOURCE_CLOUD,
-                 base::MakeUnique<base::StringValue>("value"), nullptr);
+                 POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>("value"),
+                 nullptr);
 
   std::unique_ptr<PolicyBundle> bundle(new PolicyBundle());
   // The initial setup includes a policy for chrome that is now changing.
@@ -308,7 +308,7 @@
       .CopyFrom(policy_map);
   policy_map.Set("policy", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
                  POLICY_SOURCE_CLOUD,
-                 base::MakeUnique<base::StringValue>("another value"), nullptr);
+                 base::MakeUnique<base::Value>("another value"), nullptr);
   bundle->Get(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, kExtension1))
       .CopyFrom(policy_map);
   bundle->Get(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, kExtension2))
@@ -536,12 +536,12 @@
   // precedence, on every namespace.
   expected.Set(kSameLevelPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
                POLICY_SOURCE_ENTERPRISE_DEFAULT,
-               base::MakeUnique<base::StringValue>("bundle0"), nullptr);
+               base::MakeUnique<base::Value>("bundle0"), nullptr);
   // For policies with different levels and scopes, the highest priority
   // level/scope combination takes precedence, on every namespace.
   expected.Set(kDiffLevelPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
-               POLICY_SOURCE_PLATFORM,
-               base::MakeUnique<base::StringValue>("bundle2"), nullptr);
+               POLICY_SOURCE_PLATFORM, base::MakeUnique<base::Value>("bundle2"),
+               nullptr);
   EXPECT_TRUE(policy_service_->GetPolicies(
       PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())).Equals(expected));
   EXPECT_TRUE(policy_service_->GetPolicies(
@@ -670,10 +670,10 @@
   // policy available.
   policy_map.Set(key::kProxyMode, POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER,
                  POLICY_SOURCE_CLOUD,
-                 base::MakeUnique<base::StringValue>("pac_script"), nullptr);
+                 base::MakeUnique<base::Value>("pac_script"), nullptr);
   policy_map.Set(key::kProxyPacUrl, POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER,
-                 POLICY_SOURCE_CLOUD, base::MakeUnique<base::StringValue>(
-                                          "http://example.com/wpad.dat"),
+                 POLICY_SOURCE_CLOUD,
+                 base::MakeUnique<base::Value>("http://example.com/wpad.dat"),
                  nullptr);
 
   // Add a value to a non-Chrome namespace.
diff --git a/components/policy/core/common/preg_parser.cc b/components/policy/core/common/preg_parser.cc
index 0d78b70..8126199 100644
--- a/components/policy/core/common/preg_parser.cc
+++ b/components/policy/core/common/preg_parser.cc
@@ -148,7 +148,7 @@
   switch (type) {
     case REG_SZ:
     case REG_EXPAND_SZ:
-      value->reset(new base::StringValue(DecodePRegStringValue(data)));
+      value->reset(new base::Value(DecodePRegStringValue(data)));
       return true;
     case REG_DWORD_LITTLE_ENDIAN:
     case REG_DWORD_BIG_ENDIAN:
diff --git a/components/policy/core/common/preg_parser_unittest.cc b/components/policy/core/common/preg_parser_unittest.cc
index e29c9c4..757ac70e 100644
--- a/components/policy/core/common/preg_parser_unittest.cc
+++ b/components/policy/core/common/preg_parser_unittest.cc
@@ -66,8 +66,7 @@
 void SetString(RegistryDict* dict,
                const std::string& name,
                const std::string&  value) {
-  dict->SetValue(name,
-                 base::WrapUnique<base::Value>(new base::StringValue(value)));
+  dict->SetValue(name, base::WrapUnique<base::Value>(new base::Value(value)));
 }
 
 TEST(PRegParserTest, TestParseFile) {
diff --git a/components/policy/core/common/proxy_policy_provider_unittest.cc b/components/policy/core/common/proxy_policy_provider_unittest.cc
index 254074d..1b57eb5 100644
--- a/components/policy/core/common/proxy_policy_provider_unittest.cc
+++ b/components/policy/core/common/proxy_policy_provider_unittest.cc
@@ -55,7 +55,7 @@
   PolicyBundle bundle;
   bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
       .Set("policy", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-           POLICY_SOURCE_CLOUD, base::MakeUnique<base::StringValue>("value"),
+           POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>("value"),
            nullptr);
   mock_provider_.UpdatePolicy(CopyBundle(bundle));
 
@@ -67,8 +67,8 @@
   EXPECT_CALL(observer_, OnUpdatePolicy(&proxy_provider_));
   bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
       .Set("policy", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-           POLICY_SOURCE_CLOUD,
-           base::MakeUnique<base::StringValue>("new value"), nullptr);
+           POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>("new value"),
+           nullptr);
   mock_provider_.UpdatePolicy(CopyBundle(bundle));
   Mock::VerifyAndClearExpectations(&observer_);
   EXPECT_TRUE(bundle.Equals(proxy_provider_.policies()));
diff --git a/components/policy/core/common/registry_dict.cc b/components/policy/core/common/registry_dict.cc
index 86e6824..29c9df7 100644
--- a/components/policy/core/common/registry_dict.cc
+++ b/components/policy/core/common/registry_dict.cc
@@ -260,8 +260,8 @@
     switch (it.Type()) {
       case REG_SZ:
       case REG_EXPAND_SZ:
-        SetValue(name, std::unique_ptr<base::Value>(new base::StringValue(
-                           base::UTF16ToUTF8(it.Value()))));
+        SetValue(name, std::unique_ptr<base::Value>(
+                           new base::Value(base::UTF16ToUTF8(it.Value()))));
         continue;
       case REG_DWORD_LITTLE_ENDIAN:
       case REG_DWORD_BIG_ENDIAN:
diff --git a/components/policy/core/common/registry_dict_unittest.cc b/components/policy/core/common/registry_dict_unittest.cc
index b26349db..e415d55 100644
--- a/components/policy/core/common/registry_dict_unittest.cc
+++ b/components/policy/core/common/registry_dict_unittest.cc
@@ -19,7 +19,7 @@
   RegistryDict test_dict;
 
   base::Value int_value(42);
-  base::StringValue string_value("fortytwo");
+  base::Value string_value("fortytwo");
 
   test_dict.SetValue("one", int_value.CreateDeepCopy());
   EXPECT_EQ(1u, test_dict.values().size());
@@ -47,7 +47,7 @@
   RegistryDict test_dict;
 
   base::Value int_value(42);
-  base::StringValue string_value("fortytwo");
+  base::Value string_value("fortytwo");
 
   test_dict.SetValue("One", int_value.CreateDeepCopy());
   EXPECT_EQ(1u, test_dict.values().size());
@@ -70,7 +70,7 @@
   RegistryDict test_dict;
 
   base::Value int_value(42);
-  base::StringValue string_value("fortytwo");
+  base::Value string_value("fortytwo");
 
   std::unique_ptr<RegistryDict> subdict(new RegistryDict());
   subdict->SetValue("one", int_value.CreateDeepCopy());
@@ -134,7 +134,7 @@
   RegistryDict dict_b;
 
   base::Value int_value(42);
-  base::StringValue string_value("fortytwo");
+  base::Value string_value("fortytwo");
 
   dict_a.SetValue("one", int_value.CreateDeepCopy());
   std::unique_ptr<RegistryDict> subdict(new RegistryDict());
@@ -167,7 +167,7 @@
   RegistryDict dict_b;
 
   base::Value int_value(42);
-  base::StringValue string_value("fortytwo");
+  base::Value string_value("fortytwo");
 
   dict_a.SetValue("one", int_value.CreateDeepCopy());
   dict_a.SetKey("two", base::MakeUnique<RegistryDict>());
@@ -189,9 +189,9 @@
   RegistryDict test_dict;
 
   base::Value int_value(42);
-  base::StringValue string_value("fortytwo");
-  base::StringValue string_zero("0");
-  base::StringValue string_dict("{ \"key\": [ \"value\" ] }");
+  base::Value string_value("fortytwo");
+  base::Value string_zero("0");
+  base::Value string_dict("{ \"key\": [ \"value\" ] }");
 
   test_dict.SetValue("one", int_value.CreateDeepCopy());
   std::unique_ptr<RegistryDict> subdict(new RegistryDict());
@@ -244,7 +244,7 @@
   expected.Set("string-to-double", new base::Value(0.0));
   expected.Set("string-to-int", new base::Value(static_cast<int>(0)));
   expected_list.reset(new base::ListValue());
-  expected_list->Append(base::MakeUnique<base::StringValue>("value"));
+  expected_list->Append(base::MakeUnique<base::Value>("value"));
   expected_subdict.reset(new base::DictionaryValue());
   expected_subdict->Set("key", std::move(expected_list));
   expected.Set("string-to-dict", std::move(expected_subdict));
@@ -256,10 +256,10 @@
   RegistryDict test_dict;
 
   std::unique_ptr<RegistryDict> list(new RegistryDict());
-  list->SetValue("1", base::StringValue("1").CreateDeepCopy());
-  list->SetValue("2", base::StringValue("2").CreateDeepCopy());
-  list->SetValue("THREE", base::StringValue("3").CreateDeepCopy());
-  list->SetValue("4", base::StringValue("4").CreateDeepCopy());
+  list->SetValue("1", base::Value("1").CreateDeepCopy());
+  list->SetValue("2", base::Value("2").CreateDeepCopy());
+  list->SetValue("THREE", base::Value("3").CreateDeepCopy());
+  list->SetValue("4", base::Value("4").CreateDeepCopy());
   test_dict.SetKey("dict-to-list", std::move(list));
 
   std::string error;
@@ -280,9 +280,9 @@
 
   base::DictionaryValue expected;
   std::unique_ptr<base::ListValue> expected_list(new base::ListValue());
-  expected_list->Append(base::StringValue("1").CreateDeepCopy());
-  expected_list->Append(base::StringValue("2").CreateDeepCopy());
-  expected_list->Append(base::StringValue("4").CreateDeepCopy());
+  expected_list->Append(base::Value("1").CreateDeepCopy());
+  expected_list->Append(base::Value("2").CreateDeepCopy());
+  expected_list->Append(base::Value("4").CreateDeepCopy());
   expected.Set("dict-to-list", std::move(expected_list));
 
   EXPECT_TRUE(base::Value::Equals(actual.get(), &expected));
@@ -293,7 +293,7 @@
   RegistryDict test_dict;
 
   base::Value int_value(42);
-  base::StringValue string_value("fortytwo");
+  base::Value string_value("fortytwo");
 
   test_dict.SetValue("one", int_value.CreateDeepCopy());
   std::unique_ptr<RegistryDict> subdict(new RegistryDict());
diff --git a/components/policy/core/common/schema_map_unittest.cc b/components/policy/core/common/schema_map_unittest.cc
index 2d44a482..5913ee1 100644
--- a/components/policy/core/common/schema_map_unittest.cc
+++ b/components/policy/core/common/schema_map_unittest.cc
@@ -142,15 +142,14 @@
   PolicyNamespace chrome_ns(POLICY_DOMAIN_CHROME, "");
   expected_bundle.Get(chrome_ns).Set(
       "ChromePolicy", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-      POLICY_SOURCE_CLOUD, base::MakeUnique<base::StringValue>("value"),
-      nullptr);
+      POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>("value"), nullptr);
   bundle.CopyFrom(expected_bundle);
 
   // Unknown components are filtered out.
   PolicyNamespace another_extension_ns(POLICY_DOMAIN_EXTENSIONS, "xyz");
   bundle.Get(another_extension_ns)
       .Set("AnotherExtensionPolicy", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-           POLICY_SOURCE_CLOUD, base::MakeUnique<base::StringValue>("value"),
+           POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>("value"),
            nullptr);
   schema_map->FilterBundle(&bundle);
   EXPECT_TRUE(bundle.Equals(expected_bundle));
@@ -176,14 +175,13 @@
   map.Set("object", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
           POLICY_SOURCE_CLOUD, dict.CreateDeepCopy(), nullptr);
   map.Set("string", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-          POLICY_SOURCE_CLOUD, base::MakeUnique<base::StringValue>("value"),
-          nullptr);
+          POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>("value"), nullptr);
 
   bundle.MergeFrom(expected_bundle);
   bundle.Get(extension_ns)
       .Set("Unexpected", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-           POLICY_SOURCE_CLOUD,
-           base::MakeUnique<base::StringValue>("to-be-removed"), nullptr);
+           POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>("to-be-removed"),
+           nullptr);
 
   schema_map->FilterBundle(&bundle);
   EXPECT_TRUE(bundle.Equals(expected_bundle));
@@ -239,15 +237,14 @@
   PolicyNamespace extension_ns(POLICY_DOMAIN_EXTENSIONS, "with-schema");
   bundle.Get(extension_ns)
       .Set("String", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-           POLICY_SOURCE_CLOUD, base::MakeUnique<base::StringValue>("value 1"),
+           POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>("value 1"),
            nullptr);
 
   // The Chrome namespace isn't filtered.
   PolicyNamespace chrome_ns(POLICY_DOMAIN_CHROME, "");
   bundle.Get(chrome_ns).Set("ChromePolicy", POLICY_LEVEL_MANDATORY,
                             POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-                            base::MakeUnique<base::StringValue>("value 3"),
-                            nullptr);
+                            base::MakeUnique<base::Value>("value 3"), nullptr);
 
   PolicyBundle expected_bundle;
   expected_bundle.MergeFrom(bundle);
@@ -256,20 +253,20 @@
   PolicyNamespace without_schema_ns(POLICY_DOMAIN_EXTENSIONS, "without-schema");
   bundle.Get(without_schema_ns)
       .Set("Schemaless", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-           POLICY_SOURCE_CLOUD, base::MakeUnique<base::StringValue>("value 2"),
+           POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>("value 2"),
            nullptr);
 
   // Unknown policies of known components with a schema are removed.
   bundle.Get(extension_ns)
       .Set("Surprise", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-           POLICY_SOURCE_CLOUD, base::MakeUnique<base::StringValue>("value 4"),
+           POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>("value 4"),
            nullptr);
 
   // Unknown components are removed.
   PolicyNamespace unknown_ns(POLICY_DOMAIN_EXTENSIONS, "unknown");
   bundle.Get(unknown_ns)
       .Set("Surprise", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-           POLICY_SOURCE_CLOUD, base::MakeUnique<base::StringValue>("value 5"),
+           POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>("value 5"),
            nullptr);
 
   schema_map->FilterBundle(&bundle);
diff --git a/components/policy/core/common/schema_registry_tracking_policy_provider_unittest.cc b/components/policy/core/common/schema_registry_tracking_policy_provider_unittest.cc
index 5513e8a..fd6668d 100644
--- a/components/policy/core/common/schema_registry_tracking_policy_provider_unittest.cc
+++ b/components/policy/core/common/schema_registry_tracking_policy_provider_unittest.cc
@@ -85,17 +85,17 @@
 TEST_F(SchemaRegistryTrackingPolicyProviderTest, PassOnChromePolicy) {
   PolicyBundle bundle;
   const PolicyNamespace chrome_ns(POLICY_DOMAIN_CHROME, "");
-  bundle.Get(chrome_ns).Set(
-      "policy", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-      base::MakeUnique<base::StringValue>("visible"), nullptr);
+  bundle.Get(chrome_ns).Set("policy", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+                            POLICY_SOURCE_CLOUD,
+                            base::MakeUnique<base::Value>("visible"), nullptr);
 
   EXPECT_CALL(observer_, OnUpdatePolicy(&schema_registry_tracking_provider_));
   std::unique_ptr<PolicyBundle> delegate_bundle(new PolicyBundle);
   delegate_bundle->CopyFrom(bundle);
   delegate_bundle->Get(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "xyz"))
       .Set("foo", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-           POLICY_SOURCE_CLOUD,
-           base::MakeUnique<base::StringValue>("not visible"), nullptr);
+           POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>("not visible"),
+           nullptr);
   mock_provider_.UpdatePolicy(std::move(delegate_bundle));
   Mock::VerifyAndClearExpectations(&observer_);
 
@@ -122,8 +122,8 @@
 TEST_F(SchemaRegistryTrackingPolicyProviderTest, SchemaReadyWithComponents) {
   PolicyMap policy_map;
   policy_map.Set("foo", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-                 POLICY_SOURCE_CLOUD,
-                 base::MakeUnique<base::StringValue>("omg"), nullptr);
+                 POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>("omg"),
+                 nullptr);
   std::unique_ptr<PolicyBundle> bundle(new PolicyBundle);
   bundle->Get(PolicyNamespace(POLICY_DOMAIN_CHROME, "")).CopyFrom(policy_map);
   bundle->Get(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "xyz"))
@@ -171,8 +171,8 @@
 
   PolicyMap policy_map;
   policy_map.Set("foo", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
-                 POLICY_SOURCE_CLOUD,
-                 base::MakeUnique<base::StringValue>("omg"), nullptr);
+                 POLICY_SOURCE_CLOUD, base::MakeUnique<base::Value>("omg"),
+                 nullptr);
   // Chrome policy updates are visible even if the components aren't ready.
   EXPECT_CALL(observer_, OnUpdatePolicy(&schema_registry_tracking_provider_));
   mock_provider_.UpdateChromePolicy(policy_map);
@@ -209,9 +209,9 @@
 
   // Serve policy for |ns|.
   PolicyBundle platform_policy;
-  platform_policy.Get(ns).Set(
-      "foo", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-      base::MakeUnique<base::StringValue>("omg"), nullptr);
+  platform_policy.Get(ns).Set("foo", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+                              POLICY_SOURCE_CLOUD,
+                              base::MakeUnique<base::Value>("omg"), nullptr);
   std::unique_ptr<PolicyBundle> copy(new PolicyBundle);
   copy->CopyFrom(platform_policy);
   EXPECT_CALL(observer_, OnUpdatePolicy(_));
diff --git a/components/policy/core/common/schema_unittest.cc b/components/policy/core/common/schema_unittest.cc
index d63c12dc..dd8c0caf 100644
--- a/components/policy/core/common/schema_unittest.cc
+++ b/components/policy/core/common/schema_unittest.cc
@@ -858,16 +858,13 @@
     Schema subschema = schema.GetProperty("StringWithPattern");
     ASSERT_TRUE(subschema.valid());
 
-    TestSchemaValidation(
-        subschema, base::StringValue("foobar"), SCHEMA_STRICT, false);
-    TestSchemaValidation(
-        subschema, base::StringValue("foo"), SCHEMA_STRICT, true);
-    TestSchemaValidation(
-        subschema, base::StringValue("fo"), SCHEMA_STRICT, false);
-    TestSchemaValidation(
-        subschema, base::StringValue("fooo"), SCHEMA_STRICT, true);
-    TestSchemaValidation(
-        subschema, base::StringValue("^foo+$"), SCHEMA_STRICT, false);
+    TestSchemaValidation(subschema, base::Value("foobar"), SCHEMA_STRICT,
+                         false);
+    TestSchemaValidation(subschema, base::Value("foo"), SCHEMA_STRICT, true);
+    TestSchemaValidation(subschema, base::Value("fo"), SCHEMA_STRICT, false);
+    TestSchemaValidation(subschema, base::Value("fooo"), SCHEMA_STRICT, true);
+    TestSchemaValidation(subschema, base::Value("^foo+$"), SCHEMA_STRICT,
+                         false);
   }
 
   // Tests on ObjectWithPatternProperties.
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json
index 84c9694..9160b019 100644
--- a/components/policy/resources/policy_templates.json
+++ b/components/policy/resources/policy_templates.json
@@ -139,7 +139,7 @@
 #   persistent IDs for all fields (but not for groups!) are needed. These are
 #   specified by the 'id' keys of each policy. NEVER CHANGE EXISTING IDs,
 #   because doing so would break the deployed wire format!
-#   For your editing convenience: highest ID currently used: 365
+#   For your editing convenience: highest ID currently used: 366
 #   And don't forget to also update the EnterprisePolicies enum of
 #   histograms.xml (run tools/metrics/histograms/update_policies.py).
 #
@@ -4850,6 +4850,25 @@
       If this policy is not set, or it is set to false, then <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> follows the publicly announced SHA-1 deprecation schedule.''',
     },
     {
+      'name': 'EnableCommonNameFallbackForLocalAnchors',
+      'type': 'main',
+      'schema': { 'type': 'boolean' },
+      'supported_on': ['chrome.*:58-65', 'chrome_os:58-65', 'android:58-65'],
+      'features': {
+        'dynamic_refresh': True,
+        'per_profile': False,
+      },
+      'example_value': False,
+      'id': 366,
+      'caption': '''Whether to allow certificates issued by local trust anchors that are missing the subjectAlternativeName extension''',
+      'tags': ['system-security'],
+      'desc': '''When this setting is enabled, <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> will use the commonName of a server certificate to match a hostname if the certificate is missing a subjectAlternativeName extension, as long as it successfully validates and chains to a locally-installed CA certificates.
+
+      Note that this is not recommended, as this may allow bypassing the nameConstraints extension that restricts the hostnames that a given certificate can be authorized for.
+
+      If this policy is not set, or is set to false, server certificates that lack a subjectAlternativeName extension containing either a DNS name or IP address will not be trusted.''',
+    },
+    {
       'name': 'ForceEphemeralProfiles',
       'type': 'main',
       'schema': { 'type': 'boolean' },
diff --git a/components/policy/tools/generate_policy_source.py b/components/policy/tools/generate_policy_source.py
index 62ed74b..88cf22a 100755
--- a/components/policy/tools/generate_policy_source.py
+++ b/components/policy/tools/generate_policy_source.py
@@ -687,7 +687,7 @@
     return [], 'base::MakeUnique<base::Value>(%s)' %\
                     json.dumps(value)
   elif type(value) == str:
-    return [], 'base::MakeUnique<base::StringValue>("%s")' % value
+    return [], 'base::MakeUnique<base::Value>("%s")' % value
   elif type(value) == list:
     setup = ['auto default_value = base::MakeUnique<base::ListValue>();']
     for entry in value:
@@ -1174,7 +1174,7 @@
   elif type == 'Type::INTEGER':
     return 'DecodeIntegerValue(%s)' % arg
   elif type == 'Type::STRING':
-    return 'new base::StringValue(%s)' % arg
+    return 'new base::Value(%s)' % arg
   elif type == 'Type::LIST':
     return 'DecodeStringList(%s)' % arg
   elif type == 'Type::DICTIONARY' or type == 'TYPE_EXTERNAL':
diff --git a/components/policy/tools/generate_policy_source_test.py b/components/policy/tools/generate_policy_source_test.py
index 9de1bbb..0a42616 100755
--- a/components/policy/tools/generate_policy_source_test.py
+++ b/components/policy/tools/generate_policy_source_test.py
@@ -26,7 +26,7 @@
     # Strings
     stmts, expr = generate_policy_source._GenerateDefaultValue('foo')
     self.assertListEqual([], stmts)
-    self.assertEqual('base::MakeUnique<base::StringValue>("foo")', expr)
+    self.assertEqual('base::MakeUnique<base::Value>("foo")', expr)
 
     # Empty list
     stmts, expr = generate_policy_source._GenerateDefaultValue([])
@@ -39,7 +39,7 @@
     self.assertListEqual([
         'auto default_value = base::MakeUnique<base::ListValue>();',
         'default_value->Append(base::MakeUnique<base::Value>(1));',
-        'default_value->Append(base::MakeUnique<base::StringValue>("2"));'
+        'default_value->Append(base::MakeUnique<base::Value>("2"));'
       ], stmts)
     self.assertEqual('std::move(default_value)', expr)
 
diff --git a/components/prefs/command_line_pref_store.cc b/components/prefs/command_line_pref_store.cc
index 49278c1..ddaac31e 100644
--- a/components/prefs/command_line_pref_store.cc
+++ b/components/prefs/command_line_pref_store.cc
@@ -22,9 +22,8 @@
   for (size_t i = 0; i < size; ++i) {
     if (command_line_->HasSwitch(string_switch[i].switch_name)) {
       SetValue(string_switch[i].preference_path,
-               base::MakeUnique<base::StringValue>(
-                   command_line_->GetSwitchValueASCII(
-                       string_switch[i].switch_name)),
+               base::MakeUnique<base::Value>(command_line_->GetSwitchValueASCII(
+                   string_switch[i].switch_name)),
                WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
     }
   }
@@ -35,12 +34,11 @@
     size_t size) {
   for (size_t i = 0; i < size; ++i) {
     if (command_line_->HasSwitch(path_switch[i].switch_name)) {
-      SetValue(
-          path_switch[i].preference_path,
-          base::MakeUnique<base::StringValue>(
-              command_line_->GetSwitchValuePath(path_switch[i].switch_name)
-                  .value()),
-          WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
+      SetValue(path_switch[i].preference_path,
+               base::MakeUnique<base::Value>(
+                   command_line_->GetSwitchValuePath(path_switch[i].switch_name)
+                       .value()),
+               WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
     }
   }
 }
diff --git a/components/prefs/default_pref_store_unittest.cc b/components/prefs/default_pref_store_unittest.cc
index af6a074..20bbba3 100644
--- a/components/prefs/default_pref_store_unittest.cc
+++ b/components/prefs/default_pref_store_unittest.cc
@@ -6,7 +6,6 @@
 #include "components/prefs/default_pref_store.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-using base::StringValue;
 using base::Value;
 
 namespace {
@@ -54,17 +53,17 @@
 
   // Setting a default value shouldn't send a change notification.
   pref_store->SetDefaultValue(kPrefKey,
-                              std::unique_ptr<Value>(new StringValue("foo")));
+                              std::unique_ptr<Value>(new Value("foo")));
   EXPECT_EQ(0, observer.change_count());
 
   // Replacing the default value should send a change notification...
-  pref_store->ReplaceDefaultValue(
-      kPrefKey, std::unique_ptr<Value>(new StringValue("bar")));
+  pref_store->ReplaceDefaultValue(kPrefKey,
+                                  std::unique_ptr<Value>(new Value("bar")));
   EXPECT_EQ(1, observer.change_count());
 
   // But only if the value actually changed.
-  pref_store->ReplaceDefaultValue(
-      kPrefKey, std::unique_ptr<Value>(new StringValue("bar")));
+  pref_store->ReplaceDefaultValue(kPrefKey,
+                                  std::unique_ptr<Value>(new Value("bar")));
   EXPECT_EQ(1, observer.change_count());
 }
 
diff --git a/components/prefs/json_pref_store_unittest.cc b/components/prefs/json_pref_store_unittest.cc
index f404d2a..0164ad6 100644
--- a/components/prefs/json_pref_store_unittest.cc
+++ b/components/prefs/json_pref_store_unittest.cc
@@ -229,7 +229,7 @@
   base::FilePath some_path(FILE_PATH_LITERAL("/usr/sbin/"));
 
   pref_store->SetValue(kSomeDirectory,
-                       base::MakeUnique<StringValue>(some_path.value()),
+                       base::MakeUnique<Value>(some_path.value()),
                        WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
   EXPECT_TRUE(pref_store->GetValue(kSomeDirectory, &actual));
   EXPECT_TRUE(actual->GetAsString(&path));
@@ -257,9 +257,10 @@
   EXPECT_TRUE(actual->GetAsInteger(&integer));
   EXPECT_EQ(10, integer);
 
-  pref_store->SetValue(kLongIntPref, base::MakeUnique<StringValue>(
-                                         base::Int64ToString(214748364842LL)),
-                       WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
+  pref_store->SetValue(
+      kLongIntPref,
+      base::MakeUnique<Value>(base::Int64ToString(214748364842LL)),
+      WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
   EXPECT_TRUE(pref_store->GetValue(kLongIntPref, &actual));
   EXPECT_TRUE(actual->GetAsString(&string_value));
   int64_t value;
@@ -872,7 +873,7 @@
 
   // Set a normal pref and check that it gets scheduled to be written.
   ASSERT_FALSE(file_writer->HasPendingWrite());
-  pref_store->SetValue("normal", base::MakeUnique<base::StringValue>("normal"),
+  pref_store->SetValue("normal", base::MakeUnique<base::Value>("normal"),
                        WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
   ASSERT_TRUE(file_writer->HasPendingWrite());
   file_writer->DoScheduledWrite();
@@ -881,15 +882,14 @@
 
   // Set a lossy pref and check that it is not scheduled to be written.
   // SetValue/RemoveValue.
-  pref_store->SetValue("lossy", base::MakeUnique<base::StringValue>("lossy"),
+  pref_store->SetValue("lossy", base::MakeUnique<base::Value>("lossy"),
                        WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
   ASSERT_FALSE(file_writer->HasPendingWrite());
   pref_store->RemoveValue("lossy", WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
   ASSERT_FALSE(file_writer->HasPendingWrite());
 
   // SetValueSilently/RemoveValueSilently.
-  pref_store->SetValueSilently("lossy",
-                               base::MakeUnique<base::StringValue>("lossy"),
+  pref_store->SetValueSilently("lossy", base::MakeUnique<base::Value>("lossy"),
                                WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
   ASSERT_FALSE(file_writer->HasPendingWrite());
   pref_store->RemoveValueSilently("lossy",
@@ -897,7 +897,7 @@
   ASSERT_FALSE(file_writer->HasPendingWrite());
 
   // ReportValueChanged.
-  pref_store->SetValue("lossy", base::MakeUnique<base::StringValue>("lossy"),
+  pref_store->SetValue("lossy", base::MakeUnique<base::Value>("lossy"),
                        WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
   ASSERT_FALSE(file_writer->HasPendingWrite());
   pref_store->ReportValueChanged("lossy",
@@ -918,12 +918,12 @@
 
   // Set a lossy pref and check that it is not scheduled to be written.
   ASSERT_FALSE(file_writer->HasPendingWrite());
-  pref_store->SetValue("lossy", base::MakeUnique<base::StringValue>("lossy"),
+  pref_store->SetValue("lossy", base::MakeUnique<base::Value>("lossy"),
                        WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
   ASSERT_FALSE(file_writer->HasPendingWrite());
 
   // Set a normal pref and check that it is scheduled to be written.
-  pref_store->SetValue("normal", base::MakeUnique<base::StringValue>("normal"),
+  pref_store->SetValue("normal", base::MakeUnique<base::Value>("normal"),
                        WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
   ASSERT_TRUE(file_writer->HasPendingWrite());
 
@@ -940,12 +940,12 @@
 
   // Set a normal pref and check that it is scheduled to be written.
   ASSERT_FALSE(file_writer->HasPendingWrite());
-  pref_store->SetValue("normal", base::MakeUnique<base::StringValue>("normal"),
+  pref_store->SetValue("normal", base::MakeUnique<base::Value>("normal"),
                        WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
   ASSERT_TRUE(file_writer->HasPendingWrite());
 
   // Set a lossy pref and check that the write is still scheduled.
-  pref_store->SetValue("lossy", base::MakeUnique<base::StringValue>("lossy"),
+  pref_store->SetValue("lossy", base::MakeUnique<base::Value>("lossy"),
                        WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
   ASSERT_TRUE(file_writer->HasPendingWrite());
 
@@ -961,7 +961,7 @@
   ImportantFileWriter* file_writer = GetImportantFileWriter(pref_store.get());
 
   // Set a lossy pref and check that it is not scheduled to be written.
-  pref_store->SetValue("lossy", base::MakeUnique<base::StringValue>("lossy"),
+  pref_store->SetValue("lossy", base::MakeUnique<base::Value>("lossy"),
                        WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
   ASSERT_FALSE(file_writer->HasPendingWrite());
 
@@ -1125,7 +1125,7 @@
 
   EXPECT_EQ(NOT_CALLED,
             write_callback_observer_.GetAndResetPostWriteObservationState());
-  pref_store->SetValue("normal", base::MakeUnique<base::StringValue>("normal"),
+  pref_store->SetValue("normal", base::MakeUnique<base::Value>("normal"),
                        WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
   file_writer->DoScheduledWrite();
 
diff --git a/components/prefs/pref_change_registrar_unittest.cc b/components/prefs/pref_change_registrar_unittest.cc
index 68b62cd..cecaca8 100644
--- a/components/prefs/pref_change_registrar_unittest.cc
+++ b/components/prefs/pref_change_registrar_unittest.cc
@@ -157,8 +157,7 @@
 TEST_F(ObserveSetOfPreferencesTest, IsManaged) {
   std::unique_ptr<PrefChangeRegistrar> pref_set(CreatePrefChangeRegistrar());
   EXPECT_FALSE(pref_set->IsManaged());
-  pref_service_->SetManagedPref(kHomePage,
-                                new StringValue("http://crbug.com"));
+  pref_service_->SetManagedPref(kHomePage, new Value("http://crbug.com"));
   EXPECT_TRUE(pref_set->IsManaged());
   pref_service_->SetManagedPref(kHomePageIsNewTabPage, new Value(true));
   EXPECT_TRUE(pref_set->IsManaged());
@@ -181,7 +180,7 @@
   pref_set.Add(kHomePageIsNewTabPage, callback);
 
   EXPECT_CALL(*this, OnPreferenceChanged(kHomePage));
-  pref_service_->SetUserPref(kHomePage, new StringValue("http://crbug.com"));
+  pref_service_->SetUserPref(kHomePage, new Value("http://crbug.com"));
   Mock::VerifyAndClearExpectations(this);
 
   EXPECT_CALL(*this, OnPreferenceChanged(kHomePageIsNewTabPage));
@@ -189,7 +188,7 @@
   Mock::VerifyAndClearExpectations(this);
 
   EXPECT_CALL(*this, OnPreferenceChanged(_)).Times(0);
-  pref_service_->SetUserPref(kApplicationLocale, new StringValue("en_US.utf8"));
+  pref_service_->SetUserPref(kApplicationLocale, new Value("en_US.utf8"));
   Mock::VerifyAndClearExpectations(this);
 }
 
diff --git a/components/prefs/pref_registry_simple.cc b/components/prefs/pref_registry_simple.cc
index ef15ce01..efd8cf2f 100644
--- a/components/prefs/pref_registry_simple.cc
+++ b/components/prefs/pref_registry_simple.cc
@@ -34,14 +34,14 @@
 
 void PrefRegistrySimple::RegisterStringPref(const std::string& path,
                                             const std::string& default_value) {
-  RegisterPrefAndNotify(path, new base::StringValue(default_value),
+  RegisterPrefAndNotify(path, new base::Value(default_value),
                         NO_REGISTRATION_FLAGS);
 }
 
 void PrefRegistrySimple::RegisterFilePathPref(
     const std::string& path,
     const base::FilePath& default_value) {
-  RegisterPrefAndNotify(path, new base::StringValue(default_value.value()),
+  RegisterPrefAndNotify(path, new base::Value(default_value.value()),
                         NO_REGISTRATION_FLAGS);
 }
 
@@ -67,16 +67,16 @@
 
 void PrefRegistrySimple::RegisterInt64Pref(const std::string& path,
                                            int64_t default_value) {
-  RegisterPrefAndNotify(
-      path, new base::StringValue(base::Int64ToString(default_value)),
-      NO_REGISTRATION_FLAGS);
+  RegisterPrefAndNotify(path,
+                        new base::Value(base::Int64ToString(default_value)),
+                        NO_REGISTRATION_FLAGS);
 }
 
 void PrefRegistrySimple::RegisterUint64Pref(const std::string& path,
                                             uint64_t default_value) {
-  RegisterPrefAndNotify(
-      path, new base::StringValue(base::Uint64ToString(default_value)),
-      NO_REGISTRATION_FLAGS);
+  RegisterPrefAndNotify(path,
+                        new base::Value(base::Uint64ToString(default_value)),
+                        NO_REGISTRATION_FLAGS);
 }
 
 void PrefRegistrySimple::RegisterBooleanPref(const std::string& path,
@@ -100,15 +100,14 @@
 void PrefRegistrySimple::RegisterStringPref(const std::string& path,
                                             const std::string& default_value,
                                             uint32_t flags) {
-  RegisterPrefAndNotify(path, new base::StringValue(default_value), flags);
+  RegisterPrefAndNotify(path, new base::Value(default_value), flags);
 }
 
 void PrefRegistrySimple::RegisterFilePathPref(
     const std::string& path,
     const base::FilePath& default_value,
     uint32_t flags) {
-  RegisterPrefAndNotify(path, new base::StringValue(default_value.value()),
-                        flags);
+  RegisterPrefAndNotify(path, new base::Value(default_value.value()), flags);
 }
 
 void PrefRegistrySimple::RegisterListPref(const std::string& path,
@@ -138,14 +137,14 @@
                                            int64_t default_value,
                                            uint32_t flags) {
   RegisterPrefAndNotify(
-      path, new base::StringValue(base::Int64ToString(default_value)), flags);
+      path, new base::Value(base::Int64ToString(default_value)), flags);
 }
 
 void PrefRegistrySimple::RegisterUint64Pref(const std::string& path,
                                             uint64_t default_value,
                                             uint32_t flags) {
   RegisterPrefAndNotify(
-      path, new base::StringValue(base::Uint64ToString(default_value)), flags);
+      path, new base::Value(base::Uint64ToString(default_value)), flags);
 }
 
 void PrefRegistrySimple::OnPrefRegistered(const std::string& path,
diff --git a/components/prefs/pref_service.cc b/components/prefs/pref_service.cc
index b42529b..89033a2 100644
--- a/components/prefs/pref_service.cc
+++ b/components/prefs/pref_service.cc
@@ -401,7 +401,7 @@
 }
 
 void PrefService::SetString(const std::string& path, const std::string& value) {
-  SetUserPrefValue(path, new base::StringValue(value));
+  SetUserPrefValue(path, new base::Value(value));
 }
 
 void PrefService::SetFilePath(const std::string& path,
@@ -410,7 +410,7 @@
 }
 
 void PrefService::SetInt64(const std::string& path, int64_t value) {
-  SetUserPrefValue(path, new base::StringValue(base::Int64ToString(value)));
+  SetUserPrefValue(path, new base::Value(base::Int64ToString(value)));
 }
 
 int64_t PrefService::GetInt64(const std::string& path) const {
@@ -431,7 +431,7 @@
 }
 
 void PrefService::SetUint64(const std::string& path, uint64_t value) {
-  SetUserPrefValue(path, new base::StringValue(base::Uint64ToString(value)));
+  SetUserPrefValue(path, new base::Value(base::Uint64ToString(value)));
 }
 
 uint64_t PrefService::GetUint64(const std::string& path) const {
diff --git a/components/prefs/pref_service_unittest.cc b/components/prefs/pref_service_unittest.cc
index 8c97e5e..55d3ccc 100644
--- a/components/prefs/pref_service_unittest.cc
+++ b/components/prefs/pref_service_unittest.cc
@@ -38,7 +38,7 @@
   registrar.Add(pref_name, obs.GetCallback());
 
   // This should fire the checks in MockPrefChangeCallback::OnPreferenceChanged.
-  const base::StringValue expected_value(new_pref_value);
+  const base::Value expected_value(new_pref_value);
   obs.Expect(pref_name, &expected_value);
   prefs.SetString(pref_name, new_pref_value);
   Mock::VerifyAndClearExpectations(&obs);
@@ -50,7 +50,7 @@
   Mock::VerifyAndClearExpectations(&obs);
 
   // Clearing the pref should cause the pref to fire.
-  const base::StringValue expected_default_value((std::string()));
+  const base::Value expected_default_value((std::string()));
   obs.Expect(pref_name, &expected_default_value);
   prefs.ClearPref(pref_name);
   Mock::VerifyAndClearExpectations(&obs);
@@ -83,12 +83,11 @@
   const char pref_name[] = "homepage";
 
   TestingPrefServiceSimple prefs;
-  prefs.SetUserPref(pref_name,
-                    new base::StringValue("http://www.cnn.com"));
+  prefs.SetUserPref(pref_name, new base::Value("http://www.cnn.com"));
   prefs.registry()->RegisterStringPref(pref_name, std::string());
 
   const char new_pref_value[] = "http://www.google.com/";
-  const base::StringValue expected_new_pref_value(new_pref_value);
+  const base::Value expected_new_pref_value(new_pref_value);
   MockPrefChangeCallback obs(&prefs);
   PrefChangeRegistrar registrar;
   registrar.Init(&prefs);
@@ -104,7 +103,7 @@
 
   // Now try adding a second pref observer.
   const char new_pref_value2[] = "http://www.youtube.com/";
-  const base::StringValue expected_new_pref_value2(new_pref_value2);
+  const base::Value expected_new_pref_value2(new_pref_value2);
   MockPrefChangeCallback obs2(&prefs);
   obs.Expect(pref_name, &expected_new_pref_value2);
   obs2.Expect(pref_name, &expected_new_pref_value2);
@@ -115,7 +114,7 @@
   Mock::VerifyAndClearExpectations(&obs2);
 
   // Set a recommended value.
-  const base::StringValue recommended_pref_value("http://www.gmail.com/");
+  const base::Value recommended_pref_value("http://www.gmail.com/");
   obs.Expect(pref_name, &expected_new_pref_value2);
   obs2.Expect(pref_name, &expected_new_pref_value2);
   // This should fire the checks in obs and obs2 but with an unchanged value
@@ -142,8 +141,7 @@
   prefs.registry()->RegisterIntegerPref(kPrefName, kTestValue);
 
   // Check falling back to a recommended value.
-  prefs.SetUserPref(kPrefName,
-                    new base::StringValue("not an integer"));
+  prefs.SetUserPref(kPrefName, new base::Value("not an integer"));
   const PrefService::Preference* pref = prefs.FindPreference(kPrefName);
   ASSERT_TRUE(pref);
   const base::Value* value = pref->GetValue();
@@ -354,7 +352,7 @@
 
 TEST_F(PrefServiceSetValueTest, SetStringValue) {
   const char default_string[] = "default";
-  const base::StringValue default_value(default_string);
+  const base::Value default_value(default_string);
   prefs_.registry()->RegisterStringPref(kName, default_string);
 
   PrefChangeRegistrar registrar;
@@ -370,7 +368,7 @@
   prefs_.Set(kName, default_value);
   Mock::VerifyAndClearExpectations(&observer_);
 
-  base::StringValue new_value(kValue);
+  base::Value new_value(kValue);
   observer_.Expect(kName, &new_value);
   prefs_.Set(kName, new_value);
   Mock::VerifyAndClearExpectations(&observer_);
diff --git a/components/prefs/pref_value_map.cc b/components/prefs/pref_value_map.cc
index a0352670..1d120a8 100644
--- a/components/prefs/pref_value_map.cc
+++ b/components/prefs/pref_value_map.cc
@@ -103,7 +103,7 @@
 
 void PrefValueMap::SetString(const std::string& key,
                              const std::string& value) {
-  SetValue(key, base::MakeUnique<base::StringValue>(value));
+  SetValue(key, base::MakeUnique<base::Value>(value));
 }
 
 bool PrefValueMap::GetInteger(const std::string& key, int* value) const {
diff --git a/components/prefs/pref_value_map_unittest.cc b/components/prefs/pref_value_map_unittest.cc
index f6912da..0ad8cd1 100644
--- a/components/prefs/pref_value_map_unittest.cc
+++ b/components/prefs/pref_value_map_unittest.cc
@@ -17,12 +17,12 @@
   EXPECT_FALSE(map.GetValue("key", &result));
   EXPECT_FALSE(result);
 
-  EXPECT_TRUE(map.SetValue("key", base::MakeUnique<StringValue>("test")));
-  EXPECT_FALSE(map.SetValue("key", base::MakeUnique<StringValue>("test")));
-  EXPECT_TRUE(map.SetValue("key", base::MakeUnique<StringValue>("hi mom!")));
+  EXPECT_TRUE(map.SetValue("key", base::MakeUnique<Value>("test")));
+  EXPECT_FALSE(map.SetValue("key", base::MakeUnique<Value>("test")));
+  EXPECT_TRUE(map.SetValue("key", base::MakeUnique<Value>("hi mom!")));
 
   EXPECT_TRUE(map.GetValue("key", &result));
-  EXPECT_TRUE(StringValue("hi mom!").Equals(result));
+  EXPECT_TRUE(Value("hi mom!").Equals(result));
 }
 
 TEST(PrefValueMapTest, GetAndSetIntegerValue) {
@@ -53,7 +53,7 @@
   PrefValueMap map;
   EXPECT_FALSE(map.RemoveValue("key"));
 
-  EXPECT_TRUE(map.SetValue("key", base::MakeUnique<StringValue>("test")));
+  EXPECT_TRUE(map.SetValue("key", base::MakeUnique<Value>("test")));
   EXPECT_TRUE(map.GetValue("key", NULL));
 
   EXPECT_TRUE(map.RemoveValue("key"));
@@ -64,7 +64,7 @@
 
 TEST(PrefValueMapTest, Clear) {
   PrefValueMap map;
-  EXPECT_TRUE(map.SetValue("key", base::MakeUnique<StringValue>("test")));
+  EXPECT_TRUE(map.SetValue("key", base::MakeUnique<Value>("test")));
   EXPECT_TRUE(map.GetValue("key", NULL));
 
   map.Clear();
@@ -74,9 +74,9 @@
 
 TEST(PrefValueMapTest, GetDifferingKeys) {
   PrefValueMap reference;
-  EXPECT_TRUE(reference.SetValue("b", base::MakeUnique<StringValue>("test")));
-  EXPECT_TRUE(reference.SetValue("c", base::MakeUnique<StringValue>("test")));
-  EXPECT_TRUE(reference.SetValue("e", base::MakeUnique<StringValue>("test")));
+  EXPECT_TRUE(reference.SetValue("b", base::MakeUnique<Value>("test")));
+  EXPECT_TRUE(reference.SetValue("c", base::MakeUnique<Value>("test")));
+  EXPECT_TRUE(reference.SetValue("e", base::MakeUnique<Value>("test")));
 
   PrefValueMap check;
   std::vector<std::string> differing_paths;
@@ -88,9 +88,9 @@
   expected_differing_paths.push_back("e");
   EXPECT_EQ(expected_differing_paths, differing_paths);
 
-  EXPECT_TRUE(check.SetValue("a", base::MakeUnique<StringValue>("test")));
-  EXPECT_TRUE(check.SetValue("c", base::MakeUnique<StringValue>("test")));
-  EXPECT_TRUE(check.SetValue("d", base::MakeUnique<StringValue>("test")));
+  EXPECT_TRUE(check.SetValue("a", base::MakeUnique<Value>("test")));
+  EXPECT_TRUE(check.SetValue("c", base::MakeUnique<Value>("test")));
+  EXPECT_TRUE(check.SetValue("d", base::MakeUnique<Value>("test")));
 
   reference.GetDifferingKeys(&check, &differing_paths);
   expected_differing_paths.clear();
@@ -103,14 +103,14 @@
 
 TEST(PrefValueMapTest, SwapTwoMaps) {
   PrefValueMap first_map;
-  EXPECT_TRUE(first_map.SetValue("a", base::MakeUnique<StringValue>("test")));
-  EXPECT_TRUE(first_map.SetValue("b", base::MakeUnique<StringValue>("test")));
-  EXPECT_TRUE(first_map.SetValue("c", base::MakeUnique<StringValue>("test")));
+  EXPECT_TRUE(first_map.SetValue("a", base::MakeUnique<Value>("test")));
+  EXPECT_TRUE(first_map.SetValue("b", base::MakeUnique<Value>("test")));
+  EXPECT_TRUE(first_map.SetValue("c", base::MakeUnique<Value>("test")));
 
   PrefValueMap second_map;
-  EXPECT_TRUE(second_map.SetValue("d", base::MakeUnique<StringValue>("test")));
-  EXPECT_TRUE(second_map.SetValue("e", base::MakeUnique<StringValue>("test")));
-  EXPECT_TRUE(second_map.SetValue("f", base::MakeUnique<StringValue>("test")));
+  EXPECT_TRUE(second_map.SetValue("d", base::MakeUnique<Value>("test")));
+  EXPECT_TRUE(second_map.SetValue("e", base::MakeUnique<Value>("test")));
+  EXPECT_TRUE(second_map.SetValue("f", base::MakeUnique<Value>("test")));
 
   first_map.Swap(&second_map);
 
diff --git a/components/prefs/testing_pref_store.cc b/components/prefs/testing_pref_store.cc
index 8f6f209..e9b04c8 100644
--- a/components/prefs/testing_pref_store.cc
+++ b/components/prefs/testing_pref_store.cc
@@ -124,8 +124,7 @@
 
 void TestingPrefStore::SetString(const std::string& key,
                                  const std::string& value) {
-  SetValue(key, base::MakeUnique<base::StringValue>(value),
-           DEFAULT_PREF_WRITE_FLAGS);
+  SetValue(key, base::MakeUnique<base::Value>(value), DEFAULT_PREF_WRITE_FLAGS);
 }
 
 void TestingPrefStore::SetInteger(const std::string& key, int value) {
diff --git a/components/printing/renderer/print_web_view_helper.cc b/components/printing/renderer/print_web_view_helper.cc
index eaa294d9..f31074f2 100644
--- a/components/printing/renderer/print_web_view_helper.cc
+++ b/components/printing/renderer/print_web_view_helper.cc
@@ -591,7 +591,7 @@
   web_view->setMainFrame(frame);
   blink::WebFrameWidget::create(nullptr, web_view, frame);
 
-  base::StringValue html(ResourceBundle::GetSharedInstance().GetLocalizedString(
+  base::Value html(ResourceBundle::GetSharedInstance().GetLocalizedString(
       IDR_PRINT_PREVIEW_PAGE));
   // Load page with script to avoid async operations.
   ExecuteScript(frame, kPageLoadScriptFormat, html);
diff --git a/components/proximity_auth/webui/proximity_auth_webui_handler.cc b/components/proximity_auth/webui/proximity_auth_webui_handler.cc
index 834d8af..943a485d 100644
--- a/components/proximity_auth/webui/proximity_auth_webui_handler.cc
+++ b/components/proximity_auth/webui/proximity_auth_webui_handler.cc
@@ -368,7 +368,7 @@
 void ProximityAuthWebUIHandler::OnCryptAuthClientError(
     const std::string& error_message) {
   PA_LOG(WARNING) << "CryptAuth request failed: " << error_message;
-  base::StringValue error_string(error_message);
+  base::Value error_string(error_message);
   web_ui()->CallJavascriptFunctionUnsafe("CryptAuthInterface.onError",
                                          error_string);
 }
diff --git a/components/search_engines/default_search_policy_handler_unittest.cc b/components/search_engines/default_search_policy_handler_unittest.cc
index 02b9dcd..a8c86e13 100644
--- a/components/search_engines/default_search_policy_handler_unittest.cc
+++ b/components/search_engines/default_search_policy_handler_unittest.cc
@@ -84,19 +84,19 @@
               base::MakeUnique<base::Value>(true), nullptr);
   policy->Set(key::kDefaultSearchProviderSearchURL, POLICY_LEVEL_MANDATORY,
               POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-              base::MakeUnique<base::StringValue>(kSearchURL), nullptr);
+              base::MakeUnique<base::Value>(kSearchURL), nullptr);
   policy->Set(key::kDefaultSearchProviderName, POLICY_LEVEL_MANDATORY,
               POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-              base::MakeUnique<base::StringValue>(kName), nullptr);
+              base::MakeUnique<base::Value>(kName), nullptr);
   policy->Set(key::kDefaultSearchProviderKeyword, POLICY_LEVEL_MANDATORY,
               POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-              base::MakeUnique<base::StringValue>(kKeyword), nullptr);
+              base::MakeUnique<base::Value>(kKeyword), nullptr);
   policy->Set(key::kDefaultSearchProviderSuggestURL, POLICY_LEVEL_MANDATORY,
               POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-              base::MakeUnique<base::StringValue>(kSuggestURL), nullptr);
+              base::MakeUnique<base::Value>(kSuggestURL), nullptr);
   policy->Set(key::kDefaultSearchProviderIconURL, POLICY_LEVEL_MANDATORY,
               POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-              base::MakeUnique<base::StringValue>(kIconURL), nullptr);
+              base::MakeUnique<base::Value>(kIconURL), nullptr);
   policy->Set(key::kDefaultSearchProviderEncodings, POLICY_LEVEL_MANDATORY,
               POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
               base::WrapUnique(encodings), nullptr);
@@ -105,16 +105,16 @@
               default_alternate_urls_.CreateDeepCopy(), nullptr);
   policy->Set(key::kDefaultSearchProviderSearchTermsReplacementKey,
               POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-              base::MakeUnique<base::StringValue>(kReplacementKey), nullptr);
+              base::MakeUnique<base::Value>(kReplacementKey), nullptr);
   policy->Set(key::kDefaultSearchProviderImageURL, POLICY_LEVEL_MANDATORY,
               POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-              base::MakeUnique<base::StringValue>(kImageURL), nullptr);
+              base::MakeUnique<base::Value>(kImageURL), nullptr);
   policy->Set(key::kDefaultSearchProviderImageURLPostParams,
               POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-              base::MakeUnique<base::StringValue>(kImageParams), nullptr);
+              base::MakeUnique<base::Value>(kImageParams), nullptr);
   policy->Set(key::kDefaultSearchProviderNewTabURL, POLICY_LEVEL_MANDATORY,
               POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-              base::MakeUnique<base::StringValue>(kNewTabURL), nullptr);
+              base::MakeUnique<base::Value>(kNewTabURL), nullptr);
 }
 
 // Checks that if the default search policy is missing, that no elements of the
@@ -138,7 +138,7 @@
   const char bad_search_url[] = "http://test.com/noSearchTerms";
   policy.Set(key::kDefaultSearchProviderSearchURL, POLICY_LEVEL_MANDATORY,
              POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-             base::WrapUnique(new base::StringValue(bad_search_url)), nullptr);
+             base::WrapUnique(new base::Value(bad_search_url)), nullptr);
   UpdateProviderPolicy(policy);
 
   const base::Value* temp = nullptr;
@@ -285,7 +285,7 @@
              base::WrapUnique(new base::Value(true)), nullptr);
   policy.Set(key::kDefaultSearchProviderSearchURL, POLICY_LEVEL_MANDATORY,
              POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-             base::WrapUnique(new base::StringValue(kSearchURL)), nullptr);
+             base::WrapUnique(new base::Value(kSearchURL)), nullptr);
   UpdateProviderPolicy(policy);
 
   const base::Value* temp = NULL;
@@ -344,7 +344,7 @@
              base::WrapUnique(new base::Value(true)), nullptr);
   policy.Set(key::kDefaultSearchProviderSearchURL, POLICY_LEVEL_MANDATORY,
              POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
-             base::WrapUnique(new base::StringValue(kFileSearchURL)), nullptr);
+             base::WrapUnique(new base::Value(kFileSearchURL)), nullptr);
   UpdateProviderPolicy(policy);
 
   const base::Value* temp = NULL;
diff --git a/components/signin/core/browser/android/BUILD.gn b/components/signin/core/browser/android/BUILD.gn
index 400ccab..62cc07ab 100644
--- a/components/signin/core/browser/android/BUILD.gn
+++ b/components/signin/core/browser/android/BUILD.gn
@@ -15,6 +15,7 @@
   deps = [
     "//base:base_java",
     "//net/android:net_java",
+    "//third_party/android_tools:android_support_annotations_java",
     google_play_services_library,
   ]
 
diff --git a/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerDelegate.java b/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerDelegate.java
index 3c41ad0..436e0d1 100644
--- a/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerDelegate.java
+++ b/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerDelegate.java
@@ -7,27 +7,32 @@
 import android.accounts.Account;
 import android.accounts.AuthenticatorDescription;
 import android.app.Activity;
+import android.support.annotation.AnyThread;
+import android.support.annotation.WorkerThread;
 
 import org.chromium.base.Callback;
 
 /**
- * Wrapper around the Android account manager, to facilitate dependency injection during testing.
+ * Abstraction of account management implementation.
+ * Provides methods for getting accounts and managing auth tokens.
  */
 public interface AccountManagerDelegate {
     /**
-     * This method is deprecated; please use the asynchronous version below instead.
-     *
-     * See http://crbug.com/517697 for details.
+     * Get all the accounts for a given {@code type}.
+     * This method shouldn't be called on the UI thread (violated due to crbug.com/517697).
      */
+    @WorkerThread
     Account[] getAccountsByType(String type);
 
     /**
-     * Get all the accounts for a given {@code type}.
+     * Async version of {@link #getAccountsByType}
+     * This method is deprecated and will be removed soon.
      */
+    @AnyThread
     void getAccountsByType(String type, Callback<Account[]> callback);
 
     /**
-     * Get an auth token. This should only be called on a background thread.
+     * Get an auth token.
      *
      * @param account The {@link Account} for which the auth token is requested.
      * @param authTokenScope The scope of the authToken being requested.
@@ -36,22 +41,34 @@
      * transient error or when user intervention is required (like confirming the credentials)
      * which is expressed as an {@link Intent} to the handler.
      */
+    @WorkerThread
     String getAuthToken(Account account, String authTokenScope) throws AuthException;
 
     /**
      * @param authToken The auth token to invalidate.
      * @throws AuthException Indicates a failure clearing the auth token; can be transient.
      */
+    @WorkerThread
     void invalidateAuthToken(String authToken) throws AuthException;
 
     /**
      * Get all the available authenticator types.
      */
+    @AnyThread
     AuthenticatorDescription[] getAuthenticatorTypes();
 
     /**
      * Check whether the {@code account} has all the features listed in {@code features}.
+     * This method shouldn't be called on the UI thread.
      */
+    @WorkerThread
+    boolean hasFeatures(Account account, String[] features);
+
+    /**
+     * Asynchronous version of {@link #hasFeatures}
+     * This method is deprecated and will be removed soon.
+     */
+    @AnyThread
     void hasFeatures(Account account, String[] features, Callback<Boolean> callback);
 
     /**
@@ -62,5 +79,6 @@
      * sub-Activity to prompt the user to enter a password.
      * @param callback The callback to indicate whether update is succeed or not.
      */
+    @AnyThread
     void updateCredentials(Account account, Activity activity, Callback<Boolean> callback);
 }
diff --git a/components/signin/core/browser/android/java/src/org/chromium/components/signin/SystemAccountManagerDelegate.java b/components/signin/core/browser/android/java/src/org/chromium/components/signin/SystemAccountManagerDelegate.java
index 2700cf05..f26590e8 100644
--- a/components/signin/core/browser/android/java/src/org/chromium/components/signin/SystemAccountManagerDelegate.java
+++ b/components/signin/core/browser/android/java/src/org/chromium/components/signin/SystemAccountManagerDelegate.java
@@ -113,31 +113,35 @@
     }
 
     @Override
-    public void hasFeatures(Account account, String[] features, final Callback<Boolean> callback) {
+    public boolean hasFeatures(Account account, String[] features) {
         if (!hasGetAccountsPermission()) {
-            ThreadUtils.postOnUiThread(new Runnable() {
-                @Override
-                public void run() {
-                    callback.onResult(false);
-                }
-            });
-            return;
+            return false;
         }
-        mAccountManager.hasFeatures(account, features, new AccountManagerCallback<Boolean>() {
+        try {
+            return mAccountManager.hasFeatures(account, features, null, null).getResult();
+        } catch (AuthenticatorException | IOException e) {
+            Log.e(TAG, "Error while checking features: ", e);
+        } catch (OperationCanceledException e) {
+            Log.e(TAG, "Checking features was cancelled. This should not happen.");
+        }
+        return false;
+    }
+
+    @Override
+    public void hasFeatures(
+            final Account account, final String[] features, final Callback<Boolean> callback) {
+        AsyncTask<Void, Void, Boolean> task = new AsyncTask<Void, Void, Boolean>() {
             @Override
-            public void run(AccountManagerFuture<Boolean> future) {
-                assert future.isDone();
-                boolean hasFeatures = false;
-                try {
-                    hasFeatures = future.getResult();
-                } catch (AuthenticatorException | IOException e) {
-                    Log.e(TAG, "Error while checking features: ", e);
-                } catch (OperationCanceledException e) {
-                    Log.e(TAG, "Checking features was cancelled. This should not happen.");
-                }
-                callback.onResult(hasFeatures);
+            public Boolean doInBackground(Void... params) {
+                return hasFeatures(account, features);
             }
-        }, null /* handler */);
+
+            @Override
+            public void onPostExecute(Boolean value) {
+                callback.onResult(value);
+            }
+        };
+        task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
     }
 
     /**
diff --git a/components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/util/MockAccountManager.java b/components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/util/MockAccountManager.java
index 6aa4198..df8486bf 100644
--- a/components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/util/MockAccountManager.java
+++ b/components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/util/MockAccountManager.java
@@ -179,21 +179,26 @@
     }
 
     @Override
-    public void hasFeatures(
-            Account account, final String[] features, final Callback<Boolean> callback) {
+    public boolean hasFeatures(Account account, String[] features) {
         final AccountHolder accountHolder = getAccountHolder(account);
-        accountHolder.addFeaturesCallback(new Runnable() {
+        Set<String> accountFeatures = accountHolder.getFeatures();
+        boolean hasAllFeatures = true;
+        for (String feature : features) {
+            if (!accountFeatures.contains(feature)) {
+                Log.d(TAG, accountFeatures + " does not contain " + feature);
+                hasAllFeatures = false;
+            }
+        }
+        return hasAllFeatures;
+    }
+
+    @Override
+    public void hasFeatures(
+            final Account account, final String[] features, final Callback<Boolean> callback) {
+        ThreadUtils.postOnUiThread(new Runnable() {
             @Override
             public void run() {
-                Set<String> accountFeatures = accountHolder.getFeatures();
-                boolean hasAllFeatures = true;
-                for (String feature : features) {
-                    if (!accountFeatures.contains(feature)) {
-                        Log.d(TAG, accountFeatures + " does not contain " + feature);
-                        hasAllFeatures = false;
-                    }
-                }
-                callback.onResult(hasAllFeatures);
+                callback.onResult(hasFeatures(account, features));
             }
         });
     }
diff --git a/components/signin/core/browser/gaia_cookie_manager_service.cc b/components/signin/core/browser/gaia_cookie_manager_service.cc
index 28f30f1..415f03d3 100644
--- a/components/signin/core/browser/gaia_cookie_manager_service.cc
+++ b/components/signin/core/browser/gaia_cookie_manager_service.cc
@@ -8,6 +8,7 @@
 
 #include <queue>
 
+#include "base/format_macros.h"
 #include "base/json/json_reader.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/stl_util.h"
@@ -298,7 +299,12 @@
       fetcher_retries_(0),
       source_(source),
       external_cc_result_fetched_(false),
-      list_accounts_stale_(true) {
+      list_accounts_stale_(true),
+      // |GaiaCookieManagerService| is created as soon as the profle is
+      // initialized so it is acceptable to use of this
+      // |GaiaCookieManagerService| as the time when the profile is loaded.
+      profile_load_time_(base::Time::Now()),
+      list_accounts_request_counter_(0) {
   DCHECK(!source_.empty());
 }
 
@@ -468,8 +474,21 @@
 
 std::string GaiaCookieManagerService::GetSourceForRequest(
     const GaiaCookieManagerService::GaiaCookieRequest& request) {
-  return request.source().empty() ? GetDefaultSourceForRequest() :
-      request.source();
+  std::string source = request.source().empty() ? GetDefaultSourceForRequest()
+                                                : request.source();
+  if (request.request_type() != LIST_ACCOUNTS)
+    return source;
+
+  // For list accounts requests, the source also includes the time since the
+  // profile was loaded and the number of the request in order to debug channel
+  // ID issues observed on Gaia.
+  // TODO(msarda): Remove this debug code once the investigations on Gaia side
+  // are over.
+  std::string source_with_debug_info = base::StringPrintf(
+      "%s,counter:%" PRId32 ",load_time_ms:%" PRId64, source.c_str(),
+      list_accounts_request_counter_++,
+      (base::Time::Now() - profile_load_time_).InMilliseconds());
+  return source_with_debug_info;
 }
 
 std::string GaiaCookieManagerService::GetDefaultSourceForRequest() {
@@ -754,6 +773,7 @@
 
 void GaiaCookieManagerService::StartFetchingListAccounts() {
   VLOG(1) << "GaiaCookieManagerService::ListAccounts";
+
   gaia_auth_fetcher_.reset(signin_client_->CreateGaiaAuthFetcher(
       this, GetSourceForRequest(requests_.front()),
       signin_client_->GetURLRequestContext()));
diff --git a/components/signin/core/browser/gaia_cookie_manager_service.h b/components/signin/core/browser/gaia_cookie_manager_service.h
index ae42464..ae8a8947 100644
--- a/components/signin/core/browser/gaia_cookie_manager_service.h
+++ b/components/signin/core/browser/gaia_cookie_manager_service.h
@@ -327,6 +327,14 @@
 
   bool list_accounts_stale_;
 
+  // The time when the profile was loaded and used to compute the time passed
+  // between the moment the profile was loaded and the moment a new list
+  // account request is started.
+  base::Time profile_load_time_;
+
+  // Counter for list account requests.
+  int list_accounts_request_counter_;
+
   DISALLOW_COPY_AND_ASSIGN(GaiaCookieManagerService);
 };
 
diff --git a/components/ssl_config/ssl_config_prefs.cc b/components/ssl_config/ssl_config_prefs.cc
index 7a515124..c255286 100644
--- a/components/ssl_config/ssl_config_prefs.cc
+++ b/components/ssl_config/ssl_config_prefs.cc
@@ -12,6 +12,8 @@
 const char kCertRevocationCheckingRequiredLocalAnchors[] =
     "ssl.rev_checking.required_for_local_anchors";
 const char kCertEnableSha1LocalAnchors[] = "ssl.sha1_enabled_for_local_anchors";
+const char kCertEnableCommonNameFallbackLocalAnchors[] =
+    "ssl.common_name_fallback_enabled_for_local_anchors";
 const char kSSLVersionMin[] = "ssl.version_min";
 const char kSSLVersionMax[] = "ssl.version_max";
 const char kCipherSuiteBlacklist[] = "ssl.cipher_suites.blacklist";
diff --git a/components/ssl_config/ssl_config_prefs.h b/components/ssl_config/ssl_config_prefs.h
index c10ed21..2f38652 100644
--- a/components/ssl_config/ssl_config_prefs.h
+++ b/components/ssl_config/ssl_config_prefs.h
@@ -11,6 +11,7 @@
 extern const char kCertRevocationCheckingEnabled[];
 extern const char kCertRevocationCheckingRequiredLocalAnchors[];
 extern const char kCertEnableSha1LocalAnchors[];
+extern const char kCertEnableCommonNameFallbackLocalAnchors[];
 extern const char kSSLVersionMin[];
 extern const char kSSLVersionMax[];
 extern const char kCipherSuiteBlacklist[];
diff --git a/components/ssl_config/ssl_config_service_manager_pref.cc b/components/ssl_config/ssl_config_service_manager_pref.cc
index 2bd06679..4ab20fb 100644
--- a/components/ssl_config/ssl_config_service_manager_pref.cc
+++ b/components/ssl_config/ssl_config_service_manager_pref.cc
@@ -173,6 +173,7 @@
   BooleanPrefMember rev_checking_enabled_;
   BooleanPrefMember rev_checking_required_local_anchors_;
   BooleanPrefMember sha1_local_anchors_enabled_;
+  BooleanPrefMember common_name_fallback_local_anchors_enabled_;
   StringPrefMember ssl_version_min_;
   StringPrefMember ssl_version_max_;
 
@@ -196,7 +197,7 @@
   if (base::FeatureList::IsEnabled(kTLS13Feature)) {
     local_state->SetDefaultPrefValue(
         ssl_config::prefs::kSSLVersionMax,
-        new base::StringValue(switches::kSSLVersionTLSv13));
+        new base::Value(switches::kSSLVersionTLSv13));
   }
 
   PrefChangeRegistrar::NamedChangeCallback local_state_callback =
@@ -211,6 +212,9 @@
   sha1_local_anchors_enabled_.Init(
       ssl_config::prefs::kCertEnableSha1LocalAnchors, local_state,
       local_state_callback);
+  common_name_fallback_local_anchors_enabled_.Init(
+      ssl_config::prefs::kCertEnableCommonNameFallbackLocalAnchors, local_state,
+      local_state_callback);
   ssl_version_min_.Init(ssl_config::prefs::kSSLVersionMin, local_state,
                         local_state_callback);
   ssl_version_max_.Init(ssl_config::prefs::kSSLVersionMax, local_state,
@@ -238,6 +242,8 @@
       default_config.rev_checking_required_local_anchors);
   registry->RegisterBooleanPref(ssl_config::prefs::kCertEnableSha1LocalAnchors,
                                 false);
+  registry->RegisterBooleanPref(
+      ssl_config::prefs::kCertEnableCommonNameFallbackLocalAnchors, false);
   registry->RegisterStringPref(ssl_config::prefs::kSSLVersionMin,
                                std::string());
   registry->RegisterStringPref(ssl_config::prefs::kSSLVersionMax,
@@ -277,6 +283,8 @@
   config->rev_checking_required_local_anchors =
       rev_checking_required_local_anchors_.GetValue();
   config->sha1_local_anchors_enabled = sha1_local_anchors_enabled_.GetValue();
+  config->common_name_fallback_local_anchors_enabled =
+      common_name_fallback_local_anchors_enabled_.GetValue();
   std::string version_min_str = ssl_version_min_.GetValue();
   std::string version_max_str = ssl_version_max_.GetValue();
   config->version_min = net::kDefaultSSLVersionMin;
diff --git a/components/ssl_config/ssl_config_service_manager_pref_unittest.cc b/components/ssl_config/ssl_config_service_manager_pref_unittest.cc
index 12edb50..87988a1 100644
--- a/components/ssl_config/ssl_config_service_manager_pref_unittest.cc
+++ b/components/ssl_config/ssl_config_service_manager_pref_unittest.cc
@@ -163,7 +163,7 @@
 
   TestingPrefServiceSimple local_state;
   local_state.SetUserPref(ssl_config::prefs::kSSLVersionMin,
-                          new base::StringValue("ssl3"));
+                          new base::Value("ssl3"));
   SSLConfigServiceManager::RegisterPrefs(local_state.registry());
 
   std::unique_ptr<SSLConfigServiceManager> config_manager(
@@ -185,7 +185,7 @@
 
   TestingPrefServiceSimple local_state;
   local_state.SetUserPref(ssl_config::prefs::kSSLVersionMax,
-                          new base::StringValue("tls1.3"));
+                          new base::Value("tls1.3"));
   SSLConfigServiceManager::RegisterPrefs(local_state.registry());
 
   std::unique_ptr<SSLConfigServiceManager> config_manager(
@@ -206,7 +206,7 @@
 
   TestingPrefServiceSimple local_state;
   local_state.SetUserPref(ssl_config::prefs::kSSLVersionMax,
-                          new base::StringValue("tls1.1"));
+                          new base::Value("tls1.1"));
   SSLConfigServiceManager::RegisterPrefs(local_state.registry());
 
   std::unique_ptr<SSLConfigServiceManager> config_manager(
@@ -252,7 +252,7 @@
 
   TestingPrefServiceSimple local_state;
   local_state.SetUserPref(ssl_config::prefs::kSSLVersionMax,
-                          new base::StringValue("tls1.2"));
+                          new base::Value("tls1.2"));
   SSLConfigServiceManager::RegisterPrefs(local_state.registry());
 
   std::unique_ptr<SSLConfigServiceManager> config_manager(
diff --git a/components/sync/base/model_type.h b/components/sync/base/model_type.h
index c2840f1..34419ee 100644
--- a/components/sync/base/model_type.h
+++ b/components/sync/base/model_type.h
@@ -17,7 +17,6 @@
 namespace base {
 class ListValue;
 class Value;
-using StringValue = Value;
 }
 
 namespace sync_pb {
@@ -286,7 +285,7 @@
 // Handles all model types, and not just real ones.
 //
 // Caller takes ownership of returned value.
-base::StringValue* ModelTypeToValue(ModelType model_type);
+base::Value* ModelTypeToValue(ModelType model_type);
 
 // Converts a Value into a ModelType - complement to ModelTypeToValue().
 ModelType ModelTypeFromValue(const base::Value& value);
diff --git a/components/sync/engine_impl/js_mutation_event_observer.cc b/components/sync/engine_impl/js_mutation_event_observer.cc
index a4af4da..2554b1a 100644
--- a/components/sync/engine_impl/js_mutation_event_observer.cc
+++ b/components/sync/engine_impl/js_mutation_event_observer.cc
@@ -64,7 +64,7 @@
     changes_value = changes_list;
   } else {
     changes_value =
-        new base::StringValue(base::SizeTToString(changes_size) + " changes");
+        new base::Value(base::SizeTToString(changes_size) + " changes");
   }
   details.Set("changes", changes_value);
   HandleJsEvent(FROM_HERE, "onChangesApplied", JsEventDetails(&details));
diff --git a/components/sync/protocol/proto_value_conversions.cc b/components/sync/protocol/proto_value_conversions.cc
index 89c9983..9f3d5d4e 100644
--- a/components/sync/protocol/proto_value_conversions.cc
+++ b/components/sync/protocol/proto_value_conversions.cc
@@ -84,9 +84,9 @@
 //    ToValue() doesn't have to return base::DictionaryValue though. It might
 //    be more appropriate to serialize GreenProto into a string instead:
 //
-//    std::unique_ptr<base::StringValue> ToValue(
+//    std::unique_ptr<base::Value> ToValue(
 //        const sync_pb::GreenProto& proto) const {
-//      return base::MakeUnique<base::StringValue>(proto.content());
+//      return base::MakeUnique<base::Value>(proto.content());
 //    }
 //
 class ToValueVisitor {
@@ -218,7 +218,7 @@
   std::unique_ptr<base::Value> ToValue(
       const sync_pb::UniquePosition& proto) const {
     UniquePosition pos = UniquePosition::FromProto(proto);
-    return base::MakeUnique<base::StringValue>(pos.ToDebugString());
+    return base::MakeUnique<base::Value>(pos.ToDebugString());
   }
 
  private:
@@ -233,29 +233,29 @@
   static std::unique_ptr<base::Value> BytesToValue(const std::string& bytes) {
     std::string bytes_base64;
     base::Base64Encode(bytes, &bytes_base64);
-    return base::MakeUnique<base::StringValue>(bytes_base64);
+    return base::MakeUnique<base::Value>(bytes_base64);
   }
 
   template <class E>
   static std::unique_ptr<base::Value> EnumToValue(E value) {
-    return base::MakeUnique<base::StringValue>(ProtoEnumToString(value));
+    return base::MakeUnique<base::Value>(ProtoEnumToString(value));
   }
 
   std::unique_ptr<base::Value> ToValue(const std::string& value) const {
-    return base::MakeUnique<base::StringValue>(value);
+    return base::MakeUnique<base::Value>(value);
   }
 
   std::unique_ptr<base::Value> ToValue(int64_t value) const {
-    return base::MakeUnique<base::StringValue>(base::Int64ToString(value));
+    return base::MakeUnique<base::Value>(base::Int64ToString(value));
   }
   std::unique_ptr<base::Value> ToValue(uint64_t value) const {
-    return base::MakeUnique<base::StringValue>(base::Int64ToString(value));
+    return base::MakeUnique<base::Value>(base::Int64ToString(value));
   }
   std::unique_ptr<base::Value> ToValue(uint32_t value) const {
-    return base::MakeUnique<base::StringValue>(base::Int64ToString(value));
+    return base::MakeUnique<base::Value>(base::Int64ToString(value));
   }
   std::unique_ptr<base::Value> ToValue(int32_t value) const {
-    return base::MakeUnique<base::StringValue>(base::Int64ToString(value));
+    return base::MakeUnique<base::Value>(base::Int64ToString(value));
   }
 
   std::unique_ptr<base::Value> ToValue(bool value) const {
diff --git a/components/sync/syncable/entry_kernel.cc b/components/sync/syncable/entry_kernel.cc
index 20cb7b4..591ef92 100644
--- a/components/sync/syncable/entry_kernel.cc
+++ b/components/sync/syncable/entry_kernel.cc
@@ -121,15 +121,15 @@
 
 // Helper functions for SetFieldValues().
 
-base::StringValue* Int64ToValue(int64_t i) {
-  return new base::StringValue(base::Int64ToString(i));
+base::Value* Int64ToValue(int64_t i) {
+  return new base::Value(base::Int64ToString(i));
 }
 
-base::StringValue* TimeToValue(const base::Time& t) {
-  return new base::StringValue(GetTimeDebugString(t));
+base::Value* TimeToValue(const base::Time& t) {
+  return new base::Value(GetTimeDebugString(t));
 }
 
-base::StringValue* IdToValue(const Id& id) {
+base::Value* IdToValue(const Id& id) {
   return id.ToValue();
 }
 
@@ -137,17 +137,16 @@
   return new base::Value(bool_val);
 }
 
-base::StringValue* StringToValue(const std::string& str) {
-  return new base::StringValue(str);
+base::Value* StringToValue(const std::string& str) {
+  return new base::Value(str);
 }
 
-base::StringValue* UniquePositionToValue(const UniquePosition& pos) {
-  return new base::StringValue(pos.ToDebugString());
+base::Value* UniquePositionToValue(const UniquePosition& pos) {
+  return new base::Value(pos.ToDebugString());
 }
 
-base::StringValue* AttachmentMetadataToValue(
-    const sync_pb::AttachmentMetadata& a) {
-  return new base::StringValue(a.SerializeAsString());
+base::Value* AttachmentMetadataToValue(const sync_pb::AttachmentMetadata& a) {
+  return new base::Value(a.SerializeAsString());
 }
 
 }  // namespace
diff --git a/components/sync/syncable/model_type.cc b/components/sync/syncable/model_type.cc
index 9c404a5..b222cd6 100644
--- a/components/sync/syncable/model_type.cc
+++ b/components/sync/syncable/model_type.cc
@@ -553,16 +553,16 @@
   return 0;
 }
 
-base::StringValue* ModelTypeToValue(ModelType model_type) {
+base::Value* ModelTypeToValue(ModelType model_type) {
   if (model_type >= FIRST_REAL_MODEL_TYPE) {
-    return new base::StringValue(ModelTypeToString(model_type));
+    return new base::Value(ModelTypeToString(model_type));
   } else if (model_type == TOP_LEVEL_FOLDER) {
-    return new base::StringValue("Top-level folder");
+    return new base::Value("Top-level folder");
   } else if (model_type == UNSPECIFIED) {
-    return new base::StringValue("Unspecified");
+    return new base::Value("Unspecified");
   }
   NOTREACHED();
-  return new base::StringValue(std::string());
+  return new base::Value(std::string());
 }
 
 ModelType ModelTypeFromValue(const base::Value& value) {
diff --git a/components/sync/syncable/model_type_unittest.cc b/components/sync/syncable/model_type_unittest.cc
index 1b2d974..701f4d3 100644
--- a/components/sync/syncable/model_type_unittest.cc
+++ b/components/sync/syncable/model_type_unittest.cc
@@ -31,7 +31,7 @@
 TEST_F(ModelTypeTest, ModelTypeFromValue) {
   for (int i = FIRST_REAL_MODEL_TYPE; i < MODEL_TYPE_COUNT; ++i) {
     ModelType model_type = ModelTypeFromInt(i);
-    std::unique_ptr<base::StringValue> value(ModelTypeToValue(model_type));
+    std::unique_ptr<base::Value> value(ModelTypeToValue(model_type));
     EXPECT_EQ(model_type, ModelTypeFromValue(*value));
   }
 }
diff --git a/components/sync/syncable/syncable_id.cc b/components/sync/syncable/syncable_id.cc
index 420ad38..24d8dfd 100644
--- a/components/sync/syncable/syncable_id.cc
+++ b/components/sync/syncable/syncable_id.cc
@@ -18,8 +18,8 @@
   return out;
 }
 
-base::StringValue* Id::ToValue() const {
-  return new base::StringValue(s_);
+base::Value* Id::ToValue() const {
+  return new base::Value(s_);
 }
 
 string Id::GetServerId() const {
diff --git a/components/sync/syncable/syncable_id.h b/components/sync/syncable/syncable_id.h
index df74680..100244b 100644
--- a/components/sync/syncable/syncable_id.h
+++ b/components/sync/syncable/syncable_id.h
@@ -16,7 +16,6 @@
 
 namespace base {
 class Value;
-using StringValue = Value;
 }  // namespace base
 
 namespace sql {
@@ -72,7 +71,7 @@
 
   // Dumps the ID as a value and returns it.  Transfers ownership of
   // the StringValue to the caller.
-  base::StringValue* ToValue() const;
+  base::Value* ToValue() const;
 
   // Three functions are used to work with our proto buffers.
   std::string GetServerId() const;
diff --git a/components/sync/syncable/write_transaction_info.cc b/components/sync/syncable/write_transaction_info.cc
index 9a156e86..0c4ac29 100644
--- a/components/sync/syncable/write_transaction_info.cc
+++ b/components/sync/syncable/write_transaction_info.cc
@@ -41,7 +41,7 @@
   if (mutations_size <= max_mutations_size) {
     mutations_value = EntryKernelMutationMapToValue(mutations.Get());
   } else {
-    mutations_value = base::MakeUnique<base::StringValue>(
+    mutations_value = base::MakeUnique<base::Value>(
         base::SizeTToString(mutations_size) + " mutations");
   }
   dict->Set("mutations", std::move(mutations_value));
diff --git a/components/sync/test/fake_server/fake_server_verifier.cc b/components/sync/test/fake_server/fake_server_verifier.cc
index b2497ea..daccde2 100644
--- a/components/sync/test/fake_server/fake_server_verifier.cc
+++ b/components/sync/test/fake_server/fake_server_verifier.cc
@@ -104,7 +104,7 @@
   base::ListValue* entity_list = nullptr;
   size_t actual_count = 0;
   if (entities->GetList(model_type_string, &entity_list)) {
-    base::StringValue name_value(name);
+    base::Value name_value(name);
     for (const auto& entity : *entity_list) {
       if (name_value.Equals(entity.get()))
         actual_count++;
diff --git a/components/sync_preferences/pref_model_associator_unittest.cc b/components/sync_preferences/pref_model_associator_unittest.cc
index eac90d7f..f189891 100644
--- a/components/sync_preferences/pref_model_associator_unittest.cc
+++ b/components/sync_preferences/pref_model_associator_unittest.cc
@@ -117,8 +117,7 @@
   pref_service_->SetString(kStringPrefName, local_url0_);
   const PrefService::Preference* pref =
       pref_service_->FindPreference(kStringPrefName);
-  std::unique_ptr<base::Value> server_value(
-      new base::StringValue(server_url0_));
+  std::unique_ptr<base::Value> server_value(new base::Value(server_url0_));
   std::unique_ptr<base::Value> merged_value(pref_sync_service_->MergePreference(
       pref->name(), *pref->GetValue(), *server_value));
   EXPECT_TRUE(merged_value->Equals(server_value.get()));
diff --git a/components/sync_preferences/pref_service_syncable_unittest.cc b/components/sync_preferences/pref_service_syncable_unittest.cc
index 4123ebe..f449888 100644
--- a/components/sync_preferences/pref_service_syncable_unittest.cc
+++ b/components/sync_preferences/pref_service_syncable_unittest.cc
@@ -273,13 +273,13 @@
 
   syncer::SyncDataList in;
   syncer::SyncChangeList out;
-  AddToRemoteDataList(kStringPrefName, base::StringValue(kExampleUrl1), &in);
+  AddToRemoteDataList(kStringPrefName, base::Value(kExampleUrl1), &in);
   base::ListValue urls_to_restore;
   urls_to_restore.AppendString(kExampleUrl1);
   urls_to_restore.AppendString(kExampleUrl2);
   AddToRemoteDataList(kListPrefName, urls_to_restore, &in);
   AddToRemoteDataList(kDefaultCharsetPrefName,
-                      base::StringValue(kNonDefaultCharsetValue), &in);
+                      base::Value(kNonDefaultCharsetValue), &in);
   InitWithSyncDataTakeOutput(in, &out);
 
   ASSERT_FALSE(FindValue(kStringPrefName, out).get());
@@ -316,7 +316,7 @@
   InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
   out.clear();
 
-  base::StringValue expected(kExampleUrl0);
+  base::Value expected(kExampleUrl0);
   GetPrefs()->Set(kStringPrefName, expected);
 
   std::unique_ptr<base::Value> actual(FindValue(kStringPrefName, out));
@@ -330,7 +330,7 @@
   InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
   out.clear();
 
-  base::StringValue expected(kExampleUrl1);
+  base::Value expected(kExampleUrl1);
   GetPrefs()->Set(kStringPrefName, expected);
 
   std::unique_ptr<base::Value> actual(FindValue(kStringPrefName, out));
@@ -342,7 +342,7 @@
   GetPrefs()->SetString(kStringPrefName, kExampleUrl0);
   InitWithNoSyncData();
 
-  base::StringValue expected(kExampleUrl1);
+  base::Value expected(kExampleUrl1);
   syncer::SyncChangeList list;
   list.push_back(MakeRemoteChange(1, kStringPrefName, expected,
                                   SyncChange::ACTION_UPDATE));
@@ -355,7 +355,7 @@
 TEST_F(PrefServiceSyncableTest, UpdatedSyncNodeActionAdd) {
   InitWithNoSyncData();
 
-  base::StringValue expected(kExampleUrl0);
+  base::Value expected(kExampleUrl0);
   syncer::SyncChangeList list;
   list.push_back(
       MakeRemoteChange(1, kStringPrefName, expected, SyncChange::ACTION_ADD));
@@ -370,7 +370,7 @@
 TEST_F(PrefServiceSyncableTest, UpdatedSyncNodeUnknownPreference) {
   InitWithNoSyncData();
   syncer::SyncChangeList list;
-  base::StringValue expected(kExampleUrl0);
+  base::Value expected(kExampleUrl0);
   list.push_back(MakeRemoteChange(1, "unknown preference", expected,
                                   SyncChange::ACTION_UPDATE));
   pref_sync_service_->ProcessSyncChanges(FROM_HERE, list);
@@ -380,7 +380,7 @@
 
 TEST_F(PrefServiceSyncableTest, ManagedPreferences) {
   // Make the homepage preference managed.
-  base::StringValue managed_value("http://example.com");
+  base::Value managed_value("http://example.com");
   prefs_.SetManagedPref(kStringPrefName, managed_value.DeepCopy());
 
   syncer::SyncChangeList out;
@@ -388,13 +388,13 @@
   out.clear();
 
   // Changing the homepage preference should not sync anything.
-  base::StringValue user_value("http://chromium..com");
+  base::Value user_value("http://chromium..com");
   prefs_.SetUserPref(kStringPrefName, user_value.DeepCopy());
   EXPECT_TRUE(out.empty());
 
   // An incoming sync transaction should change the user value, not the managed
   // value.
-  base::StringValue sync_value("http://crbug.com");
+  base::Value sync_value("http://crbug.com");
   syncer::SyncChangeList list;
   list.push_back(MakeRemoteChange(1, kStringPrefName, sync_value,
                                   SyncChange::ACTION_UPDATE));
@@ -451,14 +451,14 @@
   syncer::SyncChangeList out;
   InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
   out.clear();
-  base::StringValue initial_value("http://example.com/initial");
+  base::Value initial_value("http://example.com/initial");
   GetPrefs()->Set(kStringPrefName, initial_value);
   std::unique_ptr<base::Value> actual(FindValue(kStringPrefName, out));
   ASSERT_TRUE(actual.get());
   EXPECT_TRUE(initial_value.Equals(actual.get()));
 
   // Switch kHomePage to managed and set a different value.
-  base::StringValue managed_value("http://example.com/managed");
+  base::Value managed_value("http://example.com/managed");
   GetTestingPrefService()->SetManagedPref(kStringPrefName,
                                           managed_value.DeepCopy());
 
@@ -477,18 +477,18 @@
   InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
   out.clear();
 
-  base::StringValue initial_value("http://example.com/initial");
+  base::Value initial_value("http://example.com/initial");
   GetPrefs()->Set(kStringPrefName, initial_value);
   std::unique_ptr<base::Value> actual(FindValue(kStringPrefName, out));
   EXPECT_TRUE(initial_value.Equals(actual.get()));
 
   // Switch kHomePage to managed and set a different value.
-  base::StringValue managed_value("http://example.com/managed");
+  base::Value managed_value("http://example.com/managed");
   GetTestingPrefService()->SetManagedPref(kStringPrefName,
                                           managed_value.DeepCopy());
 
   // Change the sync value.
-  base::StringValue sync_value("http://example.com/sync");
+  base::Value sync_value("http://example.com/sync");
   syncer::SyncChangeList list;
   list.push_back(MakeRemoteChange(1, kStringPrefName, sync_value,
                                   SyncChange::ACTION_UPDATE));
@@ -516,7 +516,7 @@
   out.clear();
 
   // Switch kHomePage to managed and set a different value.
-  base::StringValue managed_value("http://example.com/managed");
+  base::Value managed_value("http://example.com/managed");
   GetTestingPrefService()->SetManagedPref(kStringPrefName,
                                           managed_value.DeepCopy());
   // The pref value should be the one dictated by policy.
diff --git a/components/sync_wifi/wifi_credential.cc b/components/sync_wifi/wifi_credential.cc
index a6a0e389ec..0337ee8 100644
--- a/components/sync_wifi/wifi_credential.cc
+++ b/components/sync_wifi/wifi_credential.cc
@@ -55,17 +55,17 @@
   std::unique_ptr<base::DictionaryValue> onc_properties(
       new base::DictionaryValue());
   onc_properties->Set(onc::toplevel_config::kType,
-                      new base::StringValue(onc::network_type::kWiFi));
+                      new base::Value(onc::network_type::kWiFi));
   // TODO(quiche): Switch to the HexSSID property, once ONC fully supports it.
   // crbug.com/432546.
   onc_properties->Set(onc::network_config::WifiProperty(onc::wifi::kSSID),
-                      new base::StringValue(ssid_utf8));
+                      new base::Value(ssid_utf8));
   onc_properties->Set(onc::network_config::WifiProperty(onc::wifi::kSecurity),
-                      new base::StringValue(onc_security));
+                      new base::Value(onc_security));
   if (WifiSecurityClassSupportsPassphrases(security_class())) {
     onc_properties->Set(
         onc::network_config::WifiProperty(onc::wifi::kPassphrase),
-        new base::StringValue(passphrase()));
+        new base::Value(passphrase()));
   }
   return onc_properties;
 }
diff --git a/components/translate/core/browser/translate_prefs.cc b/components/translate/core/browser/translate_prefs.cc
index 31955ad..a61cb1e 100644
--- a/components/translate/core/browser/translate_prefs.cc
+++ b/components/translate/core/browser/translate_prefs.cc
@@ -568,7 +568,7 @@
     NOTREACHED() << "Unregistered translate blacklist pref";
     return;
   }
-  base::StringValue string_value(value);
+  base::Value string_value(value);
   blacklist->Remove(string_value, NULL);
 }
 
diff --git a/components/update_client/request_sender.cc b/components/update_client/request_sender.cc
index 782ada6..b99648a6 100644
--- a/components/update_client/request_sender.cc
+++ b/components/update_client/request_sender.cc
@@ -26,10 +26,10 @@
 namespace {
 
 // This is an ECDSA prime256v1 named-curve key.
-const int kKeyVersion = 7;
+const int kKeyVersion = 6;
 const char kKeyPubBytesBase64[] =
-    "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEj0QKufXIOBN30DtKeOYA5NV64FfY"
-    "HDou4sGqtcNUIlxpTzIbO45rB45QILhW6aDTwwjWLR1YCqpEAGICvFs8dQ==";
+    "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAECEDSRcZPKv8k4JEYbF7MJxxx56m+x8Z+svg5gB"
+    "mRX1J8A9DYRL6NvFkNcmcRtSNemUm7/iqrUnxaadkqcWSODw==";
 
 // The ETag header carries the ECSDA signature of the protocol response, if
 // signing has been used.
diff --git a/components/user_manager/user_manager_base.cc b/components/user_manager/user_manager_base.cc
index 054949f..f0f17d2 100644
--- a/components/user_manager/user_manager_base.cc
+++ b/components/user_manager/user_manager_base.cc
@@ -301,7 +301,7 @@
     // Special case, removing partially-constructed supervised user or
     // boostrapping user during user list loading.
     ListPrefUpdate users_update(GetLocalState(), kRegularUsers);
-    users_update->Remove(base::StringValue(account_id.GetUserEmail()), nullptr);
+    users_update->Remove(base::Value(account_id.GetUserEmail()), nullptr);
     OnUserRemoved(account_id);
   } else {
     NOTREACHED() << "Users are not loaded yet.";
@@ -401,7 +401,7 @@
       DictionaryPrefUpdate display_name_update(GetLocalState(),
                                                kUserDisplayName);
       display_name_update->SetWithoutPathExpansion(
-          account_id.GetUserEmail(), new base::StringValue(display_name));
+          account_id.GetUserEmail(), new base::Value(display_name));
     }
   }
 }
@@ -430,8 +430,8 @@
     return;
 
   DictionaryPrefUpdate display_email_update(GetLocalState(), kUserDisplayEmail);
-  display_email_update->SetWithoutPathExpansion(
-      account_id.GetUserEmail(), new base::StringValue(display_email));
+  display_email_update->SetWithoutPathExpansion(account_id.GetUserEmail(),
+                                                new base::Value(display_email));
 }
 
 std::string UserManagerBase::GetUserDisplayEmail(
@@ -473,8 +473,8 @@
     user->set_given_name(given_name);
     if (!IsUserNonCryptohomeDataEphemeral(account_id)) {
       DictionaryPrefUpdate given_name_update(GetLocalState(), kUserGivenName);
-      given_name_update->SetWithoutPathExpansion(
-          account_id.GetUserEmail(), new base::StringValue(given_name));
+      given_name_update->SetWithoutPathExpansion(account_id.GetUserEmail(),
+                                                 new base::Value(given_name));
     }
   }
 
@@ -867,8 +867,8 @@
 void UserManagerBase::AddUserRecord(User* user) {
   // Add the user to the front of the user list.
   ListPrefUpdate prefs_users_update(GetLocalState(), kRegularUsers);
-  prefs_users_update->Insert(0, base::MakeUnique<base::StringValue>(
-                                    user->GetAccountId().GetUserEmail()));
+  prefs_users_update->Insert(
+      0, base::MakeUnique<base::Value>(user->GetAccountId().GetUserEmail()));
   users_.insert(users_.begin(), user);
 }
 
diff --git a/components/user_prefs/tracked/pref_hash_calculator_unittest.cc b/components/user_prefs/tracked/pref_hash_calculator_unittest.cc
index 11e38f1d..f7eeb22e 100644
--- a/components/user_prefs/tracked/pref_hash_calculator_unittest.cc
+++ b/components/user_prefs/tracked/pref_hash_calculator_unittest.cc
@@ -14,8 +14,8 @@
 #include "testing/gtest/include/gtest/gtest.h"
 
 TEST(PrefHashCalculatorTest, TestCurrentAlgorithm) {
-  base::StringValue string_value_1("string value 1");
-  base::StringValue string_value_2("string value 2");
+  base::Value string_value_1("string value 1");
+  base::Value string_value_2("string value 2");
   base::DictionaryValue dictionary_value_1;
   dictionary_value_1.SetInteger("int value", 1);
   dictionary_value_1.Set("nested empty map", new base::DictionaryValue);
@@ -81,7 +81,7 @@
   std::unique_ptr<base::Value> int_value(new base::Value(1234567890));
   std::unique_ptr<base::Value> double_value(new base::Value(123.0987654321));
   std::unique_ptr<base::Value> string_value(
-      new base::StringValue("testing with special chars:\n<>{}:^^@#$\\/"));
+      new base::Value("testing with special chars:\n<>{}:^^@#$\\/"));
 
   // For legacy reasons, we have to support pruning of empty lists/dictionaries
   // and nested empty ists/dicts in the hash generation algorithm.
@@ -97,10 +97,10 @@
   // A dictionary with an empty dictionary, an empty list, and nested empty
   // dictionaries/lists in it.
   std::unique_ptr<base::DictionaryValue> dict_value(new base::DictionaryValue);
-  dict_value->Set("a", new base::StringValue("foo"));
+  dict_value->Set("a", new base::Value("foo"));
   dict_value->Set("d", new base::ListValue);
   dict_value->Set("b", new base::DictionaryValue);
-  dict_value->Set("c", new base::StringValue("baz"));
+  dict_value->Set("c", new base::Value("baz"));
   dict_value->Set("e", nested_empty_dict.release());
   dict_value->Set("f", nested_empty_list.release());
 
@@ -186,8 +186,7 @@
   static const char kLegacyDeviceId[] = "test_device_id1";
 
   // As in PrefHashCalculatorTest.CatchHashChanges.
-  const base::StringValue string_value(
-      "testing with special chars:\n<>{}:^^@#$\\/");
+  const base::Value string_value("testing with special chars:\n<>{}:^^@#$\\/");
   static const char kExpectedValue[] =
       "05ACCBD3B05C45C36CD06190F63EC577112311929D8380E26E5F13182EB68318";
 
diff --git a/components/user_prefs/tracked/pref_hash_filter.cc b/components/user_prefs/tracked/pref_hash_filter.cc
index 6ae59af..8d9269e 100644
--- a/components/user_prefs/tracked/pref_hash_filter.cc
+++ b/components/user_prefs/tracked/pref_hash_filter.cc
@@ -249,7 +249,7 @@
 
   if (did_reset) {
     pref_store_contents->Set(user_prefs::kPreferenceResetTime,
-                             new base::StringValue(base::Int64ToString(
+                             new base::Value(base::Int64ToString(
                                  base::Time::Now().ToInternalValue())));
     FilterUpdate(user_prefs::kPreferenceResetTime);
 
@@ -302,7 +302,7 @@
             changed_path, inner_it.key(), mac);
       }
     } else {
-      const base::StringValue* value_as_string;
+      const base::Value* value_as_string;
       bool is_string = it.value().GetAsString(&value_as_string);
       DCHECK(is_string);
 
diff --git a/components/user_prefs/tracked/pref_hash_filter_unittest.cc b/components/user_prefs/tracked/pref_hash_filter_unittest.cc
index 42ea4f5..7670407 100644
--- a/components/user_prefs/tracked/pref_hash_filter_unittest.cc
+++ b/components/user_prefs/tracked/pref_hash_filter_unittest.cc
@@ -463,7 +463,7 @@
 std::string MockHashStoreContents::GetStoredMac(const std::string& path) const {
   const base::Value* out_value;
   if (dictionary_.GetWithoutPathExpansion(path, &out_value)) {
-    const base::StringValue* value_as_string;
+    const base::Value* value_as_string;
     EXPECT_TRUE(out_value->GetAsString(&value_as_string));
 
     return value_as_string->GetString();
@@ -481,7 +481,7 @@
     EXPECT_TRUE(out_value->GetAsDictionary(&value_as_dict));
 
     if (value_as_dict->GetWithoutPathExpansion(split_path, &out_value)) {
-      const base::StringValue* value_as_string;
+      const base::Value* value_as_string;
       EXPECT_TRUE(out_value->GetAsString(&value_as_string));
 
       return value_as_string->GetString();
@@ -703,7 +703,7 @@
 TEST_P(PrefHashFilterTest, FilterTrackedPrefUpdate) {
   base::DictionaryValue root_dict;
   // Ownership of |string_value| is transfered to |root_dict|.
-  base::Value* string_value = new base::StringValue("string value");
+  base::Value* string_value = new base::Value("string value");
   root_dict.Set(kAtomicPref, string_value);
 
   // No path should be stored on FilterUpdate.
@@ -784,7 +784,7 @@
 
 TEST_P(PrefHashFilterTest, FilterUntrackedPrefUpdate) {
   base::DictionaryValue root_dict;
-  root_dict.Set("untracked", new base::StringValue("some value"));
+  root_dict.Set("untracked", new base::Value("some value"));
   pref_hash_filter_->FilterUpdate("untracked");
 
   // No paths should be stored on FilterUpdate.
@@ -896,7 +896,7 @@
 
 TEST_P(PrefHashFilterTest, InitialValueUnknown) {
   // Ownership of these values is transfered to |pref_store_contents_|.
-  base::StringValue* string_value = new base::StringValue("string value");
+  base::Value* string_value = new base::Value("string value");
   pref_store_contents_->Set(kAtomicPref, string_value);
 
   base::DictionaryValue* dict_value = new base::DictionaryValue;
@@ -963,7 +963,7 @@
 
 TEST_P(PrefHashFilterTest, InitialValueTrustedUnknown) {
   // Ownership of this value is transfered to |pref_store_contents_|.
-  base::Value* string_value = new base::StringValue("test");
+  base::Value* string_value = new base::Value("test");
   pref_store_contents_->Set(kAtomicPref, string_value);
 
   base::DictionaryValue* dict_value = new base::DictionaryValue;
@@ -1130,7 +1130,7 @@
 
 TEST_P(PrefHashFilterTest, InitialValueUnchangedLegacyId) {
   // Ownership of these values is transfered to |pref_store_contents_|.
-  base::StringValue* string_value = new base::StringValue("string value");
+  base::Value* string_value = new base::Value("string value");
   pref_store_contents_->Set(kAtomicPref, string_value);
 
   base::DictionaryValue* dict_value = new base::DictionaryValue;
diff --git a/components/user_prefs/tracked/pref_hash_store_impl.cc b/components/user_prefs/tracked/pref_hash_store_impl.cc
index bb920ca..6487822 100644
--- a/components/user_prefs/tracked/pref_hash_store_impl.cc
+++ b/components/user_prefs/tracked/pref_hash_store_impl.cc
@@ -271,7 +271,7 @@
 
     for (base::DictionaryValue::Iterator it(*split_macs); !it.IsAtEnd();
          it.Advance()) {
-      const base::StringValue* value_as_string;
+      const base::Value* value_as_string;
       bool is_string = it.value().GetAsString(&value_as_string);
       DCHECK(is_string);
 
diff --git a/components/user_prefs/tracked/pref_hash_store_impl_unittest.cc b/components/user_prefs/tracked/pref_hash_store_impl_unittest.cc
index f5d92182..3abbf91 100644
--- a/components/user_prefs/tracked/pref_hash_store_impl_unittest.cc
+++ b/components/user_prefs/tracked/pref_hash_store_impl_unittest.cc
@@ -31,8 +31,8 @@
 };
 
 TEST_F(PrefHashStoreImplTest, ComputeMac) {
-  base::StringValue string_1("string1");
-  base::StringValue string_2("string2");
+  base::Value string_1("string1");
+  base::Value string_2("string2");
   PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true);
 
   std::string computed_mac_1 = pref_hash_store.ComputeMac("path1", &string_1);
@@ -49,8 +49,8 @@
 
 TEST_F(PrefHashStoreImplTest, ComputeSplitMacs) {
   base::DictionaryValue dict;
-  dict.Set("a", new base::StringValue("string1"));
-  dict.Set("b", new base::StringValue("string2"));
+  dict.Set("a", new base::Value("string1"));
+  dict.Set("b", new base::Value("string2"));
   PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true);
 
   std::unique_ptr<base::DictionaryValue> computed_macs =
@@ -63,15 +63,15 @@
 
   EXPECT_EQ(2U, computed_macs->size());
 
-  base::StringValue string_1("string1");
-  base::StringValue string_2("string2");
+  base::Value string_1("string1");
+  base::Value string_2("string2");
   EXPECT_EQ(pref_hash_store.ComputeMac("foo.bar.a", &string_1), mac_1);
   EXPECT_EQ(pref_hash_store.ComputeMac("foo.bar.b", &string_2), mac_2);
 }
 
 TEST_F(PrefHashStoreImplTest, AtomicHashStoreAndCheck) {
-  base::StringValue string_1("string1");
-  base::StringValue string_2("string2");
+  base::Value string_1("string1");
+  base::Value string_2("string2");
 
   {
     // 32 NULL bytes is the seed that was used to generate the legacy hash.
@@ -97,10 +97,10 @@
               transaction->CheckValue("path1", &string_2));
 
     base::DictionaryValue dict;
-    dict.Set("a", new base::StringValue("foo"));
-    dict.Set("d", new base::StringValue("bad"));
-    dict.Set("b", new base::StringValue("bar"));
-    dict.Set("c", new base::StringValue("baz"));
+    dict.Set("a", new base::Value("foo"));
+    dict.Set("d", new base::Value("bad"));
+    dict.Set("b", new base::Value("bar"));
+    dict.Set("c", new base::Value("baz"));
 
     transaction->StoreHash("path1", &dict);
     EXPECT_EQ(PrefHashStoreTransaction::UNCHANGED,
@@ -142,8 +142,8 @@
 }
 
 TEST_F(PrefHashStoreImplTest, ImportExportOperations) {
-  base::StringValue string_1("string1");
-  base::StringValue string_2("string2");
+  base::Value string_1("string1");
+  base::Value string_2("string2");
 
   // Initial state: no super MAC.
   {
@@ -290,8 +290,8 @@
 }
 
 TEST_F(PrefHashStoreImplTest, SuperMACDisabled) {
-  base::StringValue string_1("string1");
-  base::StringValue string_2("string2");
+  base::Value string_1("string1");
+  base::Value string_2("string2");
 
   {
     // Pass |use_super_mac| => false.
@@ -317,14 +317,14 @@
 
 TEST_F(PrefHashStoreImplTest, SplitHashStoreAndCheck) {
   base::DictionaryValue dict;
-  dict.Set("a", new base::StringValue("to be replaced"));
-  dict.Set("b", new base::StringValue("same"));
-  dict.Set("o", new base::StringValue("old"));
+  dict.Set("a", new base::Value("to be replaced"));
+  dict.Set("b", new base::Value("same"));
+  dict.Set("o", new base::Value("old"));
 
   base::DictionaryValue modified_dict;
-  modified_dict.Set("a", new base::StringValue("replaced"));
-  modified_dict.Set("b", new base::StringValue("same"));
-  modified_dict.Set("c", new base::StringValue("new"));
+  modified_dict.Set("a", new base::Value("replaced"));
+  modified_dict.Set("b", new base::Value("same"));
+  modified_dict.Set("c", new base::Value("new"));
 
   base::DictionaryValue empty_dict;
 
@@ -436,7 +436,7 @@
 
     // Store hashes for a random dict to be overwritten below.
     base::DictionaryValue initial_dict;
-    initial_dict.Set("a", new base::StringValue("foo"));
+    initial_dict.Set("a", new base::Value("foo"));
     transaction->StoreSplitHash("path1", &initial_dict);
 
     // Verify stored empty dictionary matches NULL and empty dictionary back.
@@ -471,8 +471,8 @@
         pref_hash_store2.BeginTransaction(GetHashStoreContents()));
 
     base::DictionaryValue tested_dict;
-    tested_dict.Set("a", new base::StringValue("foo"));
-    tested_dict.Set("b", new base::StringValue("bar"));
+    tested_dict.Set("a", new base::Value("foo"));
+    tested_dict.Set("b", new base::Value("bar"));
     EXPECT_EQ(
         PrefHashStoreTransaction::TRUSTED_UNKNOWN_VALUE,
         transaction->CheckSplitValue("new_path", &tested_dict, &invalid_keys));
@@ -487,13 +487,13 @@
 // turned into split preferences specifically because the atomic hash isn't
 // considered useful.
 TEST_F(PrefHashStoreImplTest, TrustedUnknownSplitValueFromExistingAtomic) {
-  base::StringValue string("string1");
+  base::Value string("string1");
 
   base::DictionaryValue dict;
-  dict.Set("a", new base::StringValue("foo"));
-  dict.Set("d", new base::StringValue("bad"));
-  dict.Set("b", new base::StringValue("bar"));
-  dict.Set("c", new base::StringValue("baz"));
+  dict.Set("a", new base::Value("foo"));
+  dict.Set("d", new base::Value("bad"));
+  dict.Set("b", new base::Value("bar"));
+  dict.Set("c", new base::Value("baz"));
 
   {
     PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true);
diff --git a/components/user_prefs/tracked/segregated_pref_store_unittest.cc b/components/user_prefs/tracked/segregated_pref_store_unittest.cc
index a4b40b1..49199bc 100644
--- a/components/user_prefs/tracked/segregated_pref_store_unittest.cc
+++ b/components/user_prefs/tracked/segregated_pref_store_unittest.cc
@@ -106,10 +106,10 @@
 
   // Properly stores new values.
   segregated_store_->SetValue(kSelectedPref,
-                              base::MakeUnique<base::StringValue>(kValue1),
+                              base::MakeUnique<base::Value>(kValue1),
                               WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
   segregated_store_->SetValue(kUnselectedPref,
-                              base::MakeUnique<base::StringValue>(kValue2),
+                              base::MakeUnique<base::Value>(kValue2),
                               WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
 
   ASSERT_TRUE(selected_store_->GetValue(kSelectedPref, NULL));
@@ -131,10 +131,10 @@
 
 TEST_F(SegregatedPrefStoreTest, ReadValues) {
   selected_store_->SetValue(kSelectedPref,
-                            base::MakeUnique<base::StringValue>(kValue1),
+                            base::MakeUnique<base::Value>(kValue1),
                             WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
   default_store_->SetValue(kUnselectedPref,
-                           base::MakeUnique<base::StringValue>(kValue2),
+                           base::MakeUnique<base::Value>(kValue2),
                            WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
 
   // Works properly with values that are already there.
@@ -159,11 +159,11 @@
   EXPECT_TRUE(observer_.initialization_success);
   EXPECT_TRUE(observer_.changed_keys.empty());
   segregated_store_->SetValue(kSelectedPref,
-                              base::MakeUnique<base::StringValue>(kValue1),
+                              base::MakeUnique<base::Value>(kValue1),
                               WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
   observer_.VerifyAndResetChangedKey(kSelectedPref);
   segregated_store_->SetValue(kUnselectedPref,
-                              base::MakeUnique<base::StringValue>(kValue2),
+                              base::MakeUnique<base::Value>(kValue2),
                               WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
   observer_.VerifyAndResetChangedKey(kUnselectedPref);
 }
@@ -281,13 +281,12 @@
   // To check merge behavior, create selected and default stores so each has a
   // key the other doesn't have and they have one key in common.
   selected_store_->SetValue(kSelectedPref,
-                            base::MakeUnique<base::StringValue>(kValue1),
+                            base::MakeUnique<base::Value>(kValue1),
                             WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
   default_store_->SetValue(kUnselectedPref,
-                           base::MakeUnique<base::StringValue>(kValue2),
+                           base::MakeUnique<base::Value>(kValue2),
                            WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
-  selected_store_->SetValue(kSharedPref,
-                            base::MakeUnique<base::StringValue>(kValue1),
+  selected_store_->SetValue(kSharedPref, base::MakeUnique<base::Value>(kValue1),
                             WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
 
   auto values = segregated_store_->GetValues();
diff --git a/components/user_prefs/tracked/tracked_preferences_migration_unittest.cc b/components/user_prefs/tracked/tracked_preferences_migration_unittest.cc
index b113754..213d431 100644
--- a/components/user_prefs/tracked/tracked_preferences_migration_unittest.cc
+++ b/components/user_prefs/tracked/tracked_preferences_migration_unittest.cc
@@ -163,7 +163,7 @@
     }
     DCHECK(store);
 
-    base::StringValue string_value(value);
+    base::Value string_value(value);
     DictionaryHashStoreContents contents(store);
     pref_hash_store->BeginTransaction(&contents)->StoreHash(key, &string_value);
   }
diff --git a/components/web_resource/BUILD.gn b/components/web_resource/BUILD.gn
index a80ee8d2..c4b874b 100644
--- a/components/web_resource/BUILD.gn
+++ b/components/web_resource/BUILD.gn
@@ -43,6 +43,7 @@
   sources = [
     "eula_accepted_notifier_unittest.cc",
     "resource_request_allowed_notifier_unittest.cc",
+    "web_resource_service_unittest.cc",
   ]
 
   deps = [
diff --git a/components/web_resource/web_resource_service.cc b/components/web_resource/web_resource_service.cc
index 9d2e5d7..ee7279f0 100644
--- a/components/web_resource/web_resource_service.cc
+++ b/components/web_resource/web_resource_service.cc
@@ -44,7 +44,9 @@
     const char* disable_network_switch,
     const ParseJSONCallback& parse_json_callback)
     : prefs_(prefs),
-      resource_request_allowed_notifier_(prefs, disable_network_switch),
+      resource_request_allowed_notifier_(
+          new ResourceRequestAllowedNotifier(prefs, disable_network_switch)),
+      fetch_scheduled_(false),
       in_fetch_(false),
       web_resource_server_(web_resource_server),
       application_locale_(application_locale),
@@ -54,13 +56,13 @@
       request_context_(request_context),
       parse_json_callback_(parse_json_callback),
       weak_ptr_factory_(this) {
-  resource_request_allowed_notifier_.Init(this);
+  resource_request_allowed_notifier_->Init(this);
   DCHECK(prefs);
 }
 
 void WebResourceService::StartAfterDelay() {
   // If resource requests are not allowed, we'll get a callback when they are.
-  if (resource_request_allowed_notifier_.ResourceRequestsAllowed())
+  if (resource_request_allowed_notifier_->ResourceRequestsAllowed())
     OnResourceRequestsAllowed();
 }
 
@@ -100,15 +102,35 @@
 // Delay initial load of resource data into cache so as not to interfere
 // with startup time.
 void WebResourceService::ScheduleFetch(int64_t delay_ms) {
+  if (fetch_scheduled_)
+    return;
+  fetch_scheduled_ = true;
   base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
       FROM_HERE, base::Bind(&WebResourceService::StartFetch,
                             weak_ptr_factory_.GetWeakPtr()),
       base::TimeDelta::FromMilliseconds(delay_ms));
 }
 
+void WebResourceService::SetResourceRequestAllowedNotifier(
+    std::unique_ptr<ResourceRequestAllowedNotifier> notifier) {
+  resource_request_allowed_notifier_ = std::move(notifier);
+  resource_request_allowed_notifier_->Init(this);
+}
+
+bool WebResourceService::GetFetchScheduled() const {
+  return fetch_scheduled_;
+}
+
 // Initializes the fetching of data from the resource server.  Data
 // load calls OnURLFetchComplete.
 void WebResourceService::StartFetch() {
+  // Set to false so that next fetch can be scheduled after this fetch or
+  // if we recieve notification that resource is allowed.
+  fetch_scheduled_ = false;
+  // Check whether fetching is allowed.
+  if (!resource_request_allowed_notifier_->ResourceRequestsAllowed())
+    return;
+
   // First, put our next cache load on the MessageLoop.
   ScheduleFetch(cache_update_delay_ms_);
 
diff --git a/components/web_resource/web_resource_service.h b/components/web_resource/web_resource_service.h
index 1c1103a..d29ab05 100644
--- a/components/web_resource/web_resource_service.h
+++ b/components/web_resource/web_resource_service.h
@@ -64,10 +64,17 @@
   // Then begin updating resources.
   void StartAfterDelay();
 
+  // Sets the ResourceRequestAllowedNotifier to make it configurable.
+  void SetResourceRequestAllowedNotifier(
+      std::unique_ptr<ResourceRequestAllowedNotifier> notifier);
+
  protected:
   PrefService* prefs_;
+  bool GetFetchScheduled() const;
 
  private:
+  friend class WebResourceServiceTest;
+
   // For the subclasses to process the result of a fetch.
   virtual void Unpack(const base::DictionaryValue& parsed_json) = 0;
 
@@ -92,7 +99,15 @@
 
   // Helper class used to tell this service if it's allowed to make network
   // resource requests.
-  ResourceRequestAllowedNotifier resource_request_allowed_notifier_;
+  std::unique_ptr<ResourceRequestAllowedNotifier>
+      resource_request_allowed_notifier_;
+
+  // True if we have scheduled a fetch after start_fetch_delay_ms_
+  // or another one in |cache_update_delay_ms_| time. Set to false
+  // before fetching starts so that next fetch is scheduled. This
+  // is to make sure not more than one fetch is scheduled for given
+  // point in time.
+  bool fetch_scheduled_;
 
   // The tool that fetches the url data from the server.
   std::unique_ptr<net::URLFetcher> url_fetcher_;
diff --git a/components/web_resource/web_resource_service_unittest.cc b/components/web_resource/web_resource_service_unittest.cc
new file mode 100644
index 0000000..fee29fa
--- /dev/null
+++ b/components/web_resource/web_resource_service_unittest.cc
@@ -0,0 +1,154 @@
+// 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 <memory>
+#include <utility>
+
+#include "base/bind.h"
+#include "base/message_loop/message_loop.h"
+#include "base/values.h"
+#include "components/prefs/pref_registry_simple.h"
+#include "components/prefs/testing_pref_service.h"
+#include "components/web_resource/resource_request_allowed_notifier.h"
+#include "components/web_resource/web_resource_service.h"
+#include "net/url_request/test_url_fetcher_factory.h"
+#include "net/url_request/url_request_context_getter.h"
+#include "net/url_request/url_request_status.h"
+#include "net/url_request/url_request_test_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+const std::string kTestUrl = "http://www.test.com";
+const std::string kCacheUpdatePath = "cache_update_path";
+std::string error_message_;
+}  // namespace
+
+namespace web_resource {
+
+class TestResourceRequestAllowedNotifier
+    : public ResourceRequestAllowedNotifier {
+ public:
+  TestResourceRequestAllowedNotifier(PrefService* prefs,
+                                     const char* disable_network_switch)
+      : ResourceRequestAllowedNotifier(prefs, disable_network_switch) {}
+
+  ResourceRequestAllowedNotifier::State GetResourceRequestsAllowedState()
+      override {
+    return state_;
+  }
+
+  void SetState(ResourceRequestAllowedNotifier::State state) { state_ = state; }
+
+  void NotifyState(ResourceRequestAllowedNotifier::State state) {
+    SetState(state);
+    SetObserverRequestedForTesting(true);
+    MaybeNotifyObserver();
+  }
+
+ private:
+  ResourceRequestAllowedNotifier::State state_;
+};
+
+class TestWebResourceService : public WebResourceService {
+ public:
+  TestWebResourceService(PrefService* prefs,
+                         const GURL& web_resource_server,
+                         const std::string& application_locale,
+                         const char* last_update_time_pref_name,
+                         int start_fetch_delay_ms,
+                         int cache_update_delay_ms,
+                         net::URLRequestContextGetter* request_context,
+                         const char* disable_network_switch,
+                         const ParseJSONCallback& parse_json_callback)
+      : WebResourceService(prefs,
+                           web_resource_server,
+                           application_locale,
+                           last_update_time_pref_name,
+                           start_fetch_delay_ms,
+                           cache_update_delay_ms,
+                           request_context,
+                           disable_network_switch,
+                           parse_json_callback){};
+
+  void Unpack(const base::DictionaryValue& parsed_json) override{};
+};
+
+class WebResourceServiceTest : public testing::Test {
+ public:
+  WebResourceServiceTest() {}
+
+  void SetUp() override {
+    request_context_getter_ = new net::TestURLRequestContextGetter(
+        base::ThreadTaskRunnerHandle::Get());
+    local_state_.reset(new TestingPrefServiceSimple());
+    local_state_->registry()->RegisterStringPref(kCacheUpdatePath, "0");
+    test_web_resource_service_.reset(new TestWebResourceService(
+        local_state_.get(), GURL(kTestUrl), "", kCacheUpdatePath.c_str(), 100,
+        5000, request_context_getter_.get(), nullptr,
+        base::Bind(web_resource::WebResourceServiceTest::Parse)));
+    error_message_ = "";
+    TestResourceRequestAllowedNotifier* notifier =
+        new TestResourceRequestAllowedNotifier(local_state_.get(), nullptr);
+    notifier->SetState(ResourceRequestAllowedNotifier::ALLOWED);
+    test_web_resource_service_->SetResourceRequestAllowedNotifier(
+        std::unique_ptr<ResourceRequestAllowedNotifier>(notifier));
+  }
+
+  TestResourceRequestAllowedNotifier* resource_notifier() {
+    return static_cast<TestResourceRequestAllowedNotifier*>(
+        test_web_resource_service_->resource_request_allowed_notifier_.get());
+  }
+
+  bool GetFetchScheduled() {
+    return test_web_resource_service_->GetFetchScheduled();
+  }
+
+  void CallScheduleFetch(int64_t delay_ms) {
+    return test_web_resource_service_->ScheduleFetch(delay_ms);
+  }
+
+  static void Parse(const std::string& unsafe_json,
+                    const WebResourceService::SuccessCallback& success_callback,
+                    const WebResourceService::ErrorCallback& error_callback) {
+    std::unique_ptr<base::Value> value;
+    if (!error_message_.empty())
+      error_callback.Run(error_message_);
+    else
+      success_callback.Run(std::move(value));
+  }
+
+  WebResourceService* web_resource_service() {
+    return test_web_resource_service_.get();
+  }
+
+  void CallStartFetch() { test_web_resource_service_->StartFetch(); }
+
+ private:
+  base::MessageLoop message_loop_;  // needed for TestURLFetcherFactory
+  scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
+  std::unique_ptr<TestingPrefServiceSimple> local_state_;
+  std::unique_ptr<TestWebResourceService> test_web_resource_service_;
+};
+
+TEST_F(WebResourceServiceTest, FetchScheduledAfterStartDelayTest) {
+  web_resource_service()->StartAfterDelay();
+  EXPECT_TRUE(GetFetchScheduled());
+}
+
+TEST_F(WebResourceServiceTest, FetchScheduledOnScheduleFetchTest) {
+  web_resource_service()->StartAfterDelay();
+  resource_notifier()->NotifyState(ResourceRequestAllowedNotifier::ALLOWED);
+  EXPECT_TRUE(GetFetchScheduled());
+}
+
+TEST_F(WebResourceServiceTest, FetchScheduledOnStartFetchTest) {
+  resource_notifier()->NotifyState(
+      ResourceRequestAllowedNotifier::DISALLOWED_NETWORK_DOWN);
+  CallStartFetch();
+  EXPECT_FALSE(GetFetchScheduled());
+  resource_notifier()->NotifyState(ResourceRequestAllowedNotifier::ALLOWED);
+  EXPECT_TRUE(GetFetchScheduled());
+}
+
+}  // namespace web_resource
diff --git a/content/browser/accessibility/accessibility_tree_formatter_mac.mm b/content/browser/accessibility/accessibility_tree_formatter_mac.mm
index a844a94..1d67d2d 100644
--- a/content/browser/accessibility/accessibility_tree_formatter_mac.mm
+++ b/content/browser/accessibility/accessibility_tree_formatter_mac.mm
@@ -92,7 +92,7 @@
   return list;
 }
 
-std::unique_ptr<base::StringValue> StringForBrowserAccessibility(
+std::unique_ptr<base::Value> StringForBrowserAccessibility(
     BrowserAccessibilityCocoa* obj) {
   NSMutableArray* tokens = [[NSMutableArray alloc] init];
 
@@ -122,8 +122,8 @@
   }
 
   NSString* result = [tokens componentsJoinedByString:@" "];
-  return std::unique_ptr<base::StringValue>(
-      new base::StringValue(SysNSStringToUTF16(result)));
+  return std::unique_ptr<base::Value>(
+      new base::Value(SysNSStringToUTF16(result)));
 }
 
 std::unique_ptr<base::Value> PopulateObject(id value) {
@@ -138,7 +138,7 @@
         StringForBrowserAccessibility((BrowserAccessibilityCocoa*)value));
   }
 
-  return std::unique_ptr<base::Value>(new base::StringValue(
+  return std::unique_ptr<base::Value>(new base::Value(
       SysNSStringToUTF16([NSString stringWithFormat:@"%@", value])));
 }
 
diff --git a/content/browser/accessibility/accessibility_ui.cc b/content/browser/accessibility/accessibility_ui.cc
index 7c806268..1f37792 100644
--- a/content/browser/accessibility/accessibility_ui.cc
+++ b/content/browser/accessibility/accessibility_ui.cc
@@ -309,7 +309,7 @@
     std::unique_ptr<base::DictionaryValue> result(new base::DictionaryValue());
     result->SetInteger(kProcessIdField, process_id);
     result->SetInteger(kRouteIdField, route_id);
-    result->Set("error", new base::StringValue("Renderer no longer exists."));
+    result->Set("error", new base::Value("Renderer no longer exists."));
     web_ui()->CallJavascriptFunctionUnsafe("accessibility.showTree",
                                            *(result.get()));
     return;
@@ -338,8 +338,7 @@
   formatter->FormatAccessibilityTree(ax_mgr->GetRoot(),
                                      &accessibility_contents_utf16);
   result->Set("tree",
-              new base::StringValue(
-                  base::UTF16ToUTF8(accessibility_contents_utf16)));
+              new base::Value(base::UTF16ToUTF8(accessibility_contents_utf16)));
   web_ui()->CallJavascriptFunctionUnsafe("accessibility.showTree",
                                          *(result.get()));
 }
diff --git a/content/browser/appcache/appcache_internals_ui.cc b/content/browser/appcache/appcache_internals_ui.cc
index 28f33e71..e9ad038 100644
--- a/content/browser/appcache/appcache_internals_ui.cc
+++ b/content/browser/appcache/appcache_internals_ui.cc
@@ -422,7 +422,7 @@
     incognito_path_prefix = "Incognito ";
   web_ui()->CallJavascriptFunctionUnsafe(
       kFunctionOnAllAppCacheInfoReady,
-      base::StringValue(incognito_path_prefix + partition_path.AsUTF8Unsafe()),
+      base::Value(incognito_path_prefix + partition_path.AsUTF8Unsafe()),
       *GetListValueFromAppCacheInfoCollection(collection.get()));
 }
 
@@ -432,8 +432,8 @@
     bool deleted) {
   web_ui()->CallJavascriptFunctionUnsafe(
       kFunctionOnAppCacheInfoDeleted,
-      base::StringValue(partition_path.AsUTF8Unsafe()),
-      base::StringValue(manifest_url), base::Value(deleted));
+      base::Value(partition_path.AsUTF8Unsafe()), base::Value(manifest_url),
+      base::Value(deleted));
 }
 
 void AppCacheInternalsUI::OnAppCacheDetailsReady(
@@ -442,13 +442,13 @@
     std::unique_ptr<AppCacheResourceInfoVector> resource_info_vector) {
   if (resource_info_vector) {
     web_ui()->CallJavascriptFunctionUnsafe(
-        kFunctionOnAppCacheDetailsReady, base::StringValue(manifest_url),
-        base::StringValue(partition_path.AsUTF8Unsafe()),
+        kFunctionOnAppCacheDetailsReady, base::Value(manifest_url),
+        base::Value(partition_path.AsUTF8Unsafe()),
         *GetListValueForAppCacheResourceInfoVector(resource_info_vector.get()));
   } else {
     web_ui()->CallJavascriptFunctionUnsafe(
-        kFunctionOnAppCacheDetailsReady, base::StringValue(manifest_url),
-        base::StringValue(partition_path.AsUTF8Unsafe()));
+        kFunctionOnAppCacheDetailsReady, base::Value(manifest_url),
+        base::Value(partition_path.AsUTF8Unsafe()));
   }
 }
 
@@ -487,7 +487,7 @@
   web_ui()->CallJavascriptFunctionUnsafe(
       kFunctionOnFileDetailsReady,
       *GetDictionaryValueForResponseEnquiry(response_enquiry),
-      base::StringValue(headers), base::StringValue(hex_dump));
+      base::Value(headers), base::Value(hex_dump));
 }
 
 void AppCacheInternalsUI::OnFileDetailsFailed(
diff --git a/content/browser/devtools/devtools_http_handler.cc b/content/browser/devtools/devtools_http_handler.cc
index 58c0c46..22dbbadd 100644
--- a/content/browser/devtools/devtools_http_handler.cc
+++ b/content/browser/devtools/devtools_http_handler.cc
@@ -774,7 +774,7 @@
         *value, base::JSONWriter::OPTIONS_PRETTY_PRINT, &json_value);
   }
   std::string json_message;
-  base::JSONWriter::Write(base::StringValue(message), &json_message);
+  base::JSONWriter::Write(base::Value(message), &json_message);
 
   net::HttpServerResponseInfo response(status_code);
   response.SetBody(json_value + message, "application/json; charset=UTF-8");
diff --git a/content/browser/devtools/protocol_string.cc b/content/browser/devtools/protocol_string.cc
index 452949a2..994e478 100644
--- a/content/browser/devtools/protocol_string.cc
+++ b/content/browser/devtools/protocol_string.cc
@@ -93,7 +93,7 @@
   if (value->type() == protocol::Value::TypeString) {
     std::string inner;
     value->asString(&inner);
-    return base::WrapUnique(new base::StringValue(inner));
+    return base::WrapUnique(new base::Value(inner));
   }
   if (value->type() == protocol::Value::TypeArray) {
     protocol::ListValue* list = protocol::ListValue::cast(value);
diff --git a/content/browser/devtools/render_frame_devtools_agent_host.cc b/content/browser/devtools/render_frame_devtools_agent_host.cc
index e5d64bff..478d1f0 100644
--- a/content/browser/devtools/render_frame_devtools_agent_host.cc
+++ b/content/browser/devtools/render_frame_devtools_agent_host.cc
@@ -657,8 +657,8 @@
       }
       if (session())
         protocol::TargetHandler::FromSession(session())->UpdateServiceWorkers();
-    } else if (pending_ &&
-               pending_->host() == navigation_handle->GetRenderFrameHost()) {
+    } else if (pending_ && pending_->host()->GetFrameTreeNodeId() ==
+                               navigation_handle->GetFrameTreeNodeId()) {
       DiscardPending();
     }
     DCHECK(CheckConsistency());
diff --git a/content/browser/frame_host/navigator_impl.cc b/content/browser/frame_host/navigator_impl.cc
index 07f3cc9..b2533a8 100644
--- a/content/browser/frame_host/navigator_impl.cc
+++ b/content/browser/frame_host/navigator_impl.cc
@@ -685,7 +685,8 @@
 
   // After setting the last committed origin, reset the feature policy in the
   // RenderFrameHost to a blank policy based on the parent frame.
-  render_frame_host->ResetFeaturePolicy();
+  if (did_navigate && !is_navigation_within_page)
+    render_frame_host->ResetFeaturePolicy();
 
   // Send notification about committed provisional loads. This notification is
   // different from the NAV_ENTRY_COMMITTED notification which doesn't include
diff --git a/content/browser/frame_host/navigator_impl_unittest.cc b/content/browser/frame_host/navigator_impl_unittest.cc
index 41e14e77..c5b35f16 100644
--- a/content/browser/frame_host/navigator_impl_unittest.cc
+++ b/content/browser/frame_host/navigator_impl_unittest.cc
@@ -1240,4 +1240,49 @@
   EXPECT_EQ(speculative_rfh, main_test_rfh());
 }
 
+// Feature Policy: Test that the feature policy is reset when navigating pages
+// within a site.
+TEST_F(NavigatorTestWithBrowserSideNavigation,
+       FeaturePolicySameSiteNavigation) {
+  const GURL kUrl1("http://www.chromium.org/");
+  const GURL kUrl2("http://www.chromium.org/Home");
+
+  contents()->NavigateAndCommit(kUrl1);
+
+  // Check the feature policy before navigation.
+  FeaturePolicy* original_feature_policy =
+      main_test_rfh()->get_feature_policy();
+  ASSERT_TRUE(original_feature_policy);
+
+  // Navigate to the new URL.
+  contents()->NavigateAndCommit(kUrl2);
+
+  // Check the feature policy after navigation.
+  FeaturePolicy* final_feature_policy = main_test_rfh()->get_feature_policy();
+  ASSERT_TRUE(final_feature_policy);
+  ASSERT_NE(original_feature_policy, final_feature_policy);
+}
+
+// Feature Policy: Test that the feature policy is not reset when navigating
+// within a page.
+TEST_F(NavigatorTestWithBrowserSideNavigation,
+       FeaturePolicyFragmentNavigation) {
+  const GURL kUrl1("http://www.chromium.org/");
+  const GURL kUrl2("http://www.chromium.org/#Home");
+
+  contents()->NavigateAndCommit(kUrl1);
+
+  // Check the feature policy before navigation.
+  FeaturePolicy* original_feature_policy =
+      main_test_rfh()->get_feature_policy();
+  ASSERT_TRUE(original_feature_policy);
+
+  // Navigate to the new URL.
+  contents()->NavigateAndCommit(kUrl2);
+
+  // Check the feature policy after navigation.
+  FeaturePolicy* final_feature_policy = main_test_rfh()->get_feature_policy();
+  ASSERT_EQ(original_feature_policy, final_feature_policy);
+}
+
 }  // namespace content
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc
index 419beed..ff676db 100644
--- a/content/browser/frame_host/render_frame_host_impl.cc
+++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -1305,7 +1305,7 @@
   if (frame_tree_node_->IsMainFrame() && GetView() &&
       !validated_params.was_within_same_page) {
     RenderWidgetHostImpl::From(GetView()->GetRenderWidgetHost())
-        ->StartNewContentRenderingTimeout(validated_params.content_source_id);
+        ->StartNewContentRenderingTimeout();
   }
 }
 
diff --git a/content/browser/indexed_db/indexed_db_internals_ui.cc b/content/browser/indexed_db/indexed_db_internals_ui.cc
index f2811c5..d09cc57 100644
--- a/content/browser/indexed_db/indexed_db_internals_ui.cc
+++ b/content/browser/indexed_db/indexed_db_internals_ui.cc
@@ -126,7 +126,7 @@
     const base::FilePath& path) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   web_ui()->CallJavascriptFunctionUnsafe("indexeddb.onOriginsReady", *origins,
-                                         base::StringValue(path.value()));
+                                         base::Value(path.value()));
 }
 
 static void FindContext(const base::FilePath& partition_path,
@@ -270,8 +270,8 @@
                                          const Origin& origin,
                                          size_t connection_count) {
   web_ui()->CallJavascriptFunctionUnsafe(
-      "indexeddb.onForcedClose", base::StringValue(partition_path.value()),
-      base::StringValue(origin.Serialize()),
+      "indexeddb.onForcedClose", base::Value(partition_path.value()),
+      base::Value(origin.Serialize()),
       base::Value(static_cast<double>(connection_count)));
 }
 
@@ -358,9 +358,8 @@
 
   item->AddObserver(new FileDeleter(temp_path));
   web_ui()->CallJavascriptFunctionUnsafe(
-      "indexeddb.onOriginDownloadReady",
-      base::StringValue(partition_path.value()),
-      base::StringValue(origin.Serialize()),
+      "indexeddb.onOriginDownloadReady", base::Value(partition_path.value()),
+      base::Value(origin.Serialize()),
       base::Value(static_cast<double>(connection_count)));
 }
 
diff --git a/content/browser/loader/DEPS b/content/browser/loader/DEPS
index 9a132f78..b49f115 100644
--- a/content/browser/loader/DEPS
+++ b/content/browser/loader/DEPS
@@ -180,7 +180,6 @@
     "+content/browser/bad_message.h",
     "+content/browser/blob_storage/chrome_blob_storage_context.h",
     "+content/browser/child_process_security_policy_impl.h",
-    "+content/browser/download/save_types.h",
     "+content/browser/frame_host/frame_tree.h",
     "+content/browser/frame_host/navigation_handle_impl.h",
     "+content/browser/frame_host/navigation_request_info.h",
@@ -204,16 +203,13 @@
     "+content/browser/streams/stream_context.h",
     "+content/browser/streams/stream_registry.h",
     "+content/common/content_export.h",
-    "+content/common/navigation_params.h",
     "+content/common/net/url_request_service_worker_data.h",
-    "+content/common/site_isolation_policy.h",
     "+content/public/browser/browser_thread.h",
     "+content/public/browser/navigation_ui_data.h",
     "+content/public/browser/plugin_service.h",
     "+content/public/browser/resource_request_details.h",
     "+content/public/browser/stream_handle.h",
     "+content/public/browser/stream_info.h",
-    "+content/public/browser/web_contents_observer.h",
     "+content/public/common/browser_side_navigation_policy.h",
     "+content/public/common/content_features.h",
     "+content/public/common/content_switches.h",
diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc
index 3e200a2..081d917 100644
--- a/content/browser/loader/resource_dispatcher_host_impl.cc
+++ b/content/browser/loader/resource_dispatcher_host_impl.cc
@@ -74,13 +74,11 @@
 #include "content/browser/streams/stream.h"
 #include "content/browser/streams/stream_context.h"
 #include "content/browser/streams/stream_registry.h"
-#include "content/common/navigation_params.h"
 #include "content/common/net/url_request_service_worker_data.h"
 #include "content/common/resource_messages.h"
 #include "content/common/resource_request.h"
 #include "content/common/resource_request_body_impl.h"
 #include "content/common/resource_request_completion_status.h"
-#include "content/common/site_isolation_policy.h"
 #include "content/common/view_messages.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/global_request_id.h"
diff --git a/content/browser/memory/memory_condition_observer.cc b/content/browser/memory/memory_condition_observer.cc
index 8c02504..d429f07 100644
--- a/content/browser/memory/memory_condition_observer.cc
+++ b/content/browser/memory/memory_condition_observer.cc
@@ -135,23 +135,14 @@
   static constexpr char kMemoryCoordinatorV0Trial[] = "MemoryCoordinatorV0";
   std::map<std::string, std::string> params;
   variations::GetVariationParams(kMemoryCoordinatorV0Trial, &params);
-  // TODO(bashi): Renaming (throttled -> warning, suspended -> critical) is
-  // ongoing. Get variation parameters from both until server-side change
-  // is done. crbug.com/696844
   SetIntVariationParameter(params, "expected_renderer_size",
                            &expected_renderer_size_);
-  SetIntVariationParameter(params, "new_renderers_until_throttled",
-                           &new_renderers_until_warning_);
   SetIntVariationParameter(params, "new_renderers_until_warning",
                            &new_renderers_until_warning_);
-  SetIntVariationParameter(params, "new_renderers_until_suspended",
-                           &new_renderers_until_critical_);
   SetIntVariationParameter(params, "new_renderers_until_critical",
                            &new_renderers_until_critical_);
   SetIntVariationParameter(params, "new_renderers_back_to_normal",
                            &new_renderers_back_to_normal_);
-  SetIntVariationParameter(params, "new_renderers_back_to_throttled",
-                           &new_renderers_back_to_warning_);
   SetIntVariationParameter(params, "new_renderers_back_to_warning",
                            &new_renderers_back_to_warning_);
   SetSecondsVariationParameter(params, "monitoring_interval",
diff --git a/content/browser/memory/memory_coordinator_impl.cc b/content/browser/memory/memory_coordinator_impl.cc
index 75727c01..0262491 100644
--- a/content/browser/memory/memory_coordinator_impl.cc
+++ b/content/browser/memory/memory_coordinator_impl.cc
@@ -57,6 +57,25 @@
   return "N/A";
 }
 
+MemoryState CalculateMemoryStateForProcess(MemoryCondition condition,
+                                           bool is_visible) {
+  // The current heuristics for state calculation:
+  // - Foregrounded(visible) processes: THROTTLED when condition is CRITICAL,
+  //   otherwise NORMAL.
+  // - Backgrounded(invisible) processes: THROTTLED when condition is
+  //   WARNING/CRITICAL, otherwise NORMAL.
+  switch (condition) {
+    case MemoryCondition::NORMAL:
+      return MemoryState::NORMAL;
+    case MemoryCondition::WARNING:
+      return is_visible ? MemoryState::NORMAL : MemoryState::THROTTLED;
+    case MemoryCondition::CRITICAL:
+      return MemoryState::THROTTLED;
+  }
+  NOTREACHED();
+  return MemoryState::NORMAL;
+}
+
 }  // namespace
 
 // The implementation of MemoryCoordinatorHandle. See memory_coordinator.mojom
@@ -237,25 +256,8 @@
   RenderProcessHost* process = render_widget_host->GetProcess();
   if (!process)
     return;
-  auto iter = children().find(process->GetID());
-  if (iter == children().end())
-    return;
-
-  iter->second.is_visible = *Details<bool>(details).ptr();
-  // The current heuristics for state calculation:
-  // - Foregrounded renderers: THROTTLED when condition is CRITICAL, otherwise
-  //   NORMAL.
-  // - Backgrounded renderers: THROTTLED when condition is WARNING/CRITICAL,
-  //   otherwise NORMAL.
-  MemoryState new_state = MemoryState::NORMAL;
-  MemoryCondition condition = GetMemoryCondition();
-  if (condition == MemoryCondition::WARNING) {
-    new_state =
-        iter->second.is_visible ? MemoryState::NORMAL : MemoryState::THROTTLED;
-  } else if (condition == MemoryCondition::CRITICAL) {
-    new_state = MemoryState::THROTTLED;
-  }
-  SetChildMemoryState(iter->first, new_state);
+  bool is_visible = *Details<bool>(details).ptr();
+  OnChildVisibilityChanged(process->GetID(), is_visible);
 }
 
 MemoryState MemoryCoordinatorImpl::GetStateForProcess(
@@ -357,13 +359,28 @@
 }
 
 void MemoryCoordinatorImpl::OnChildAdded(int render_process_id) {
-  // Populate an initial state of a newly created process, assuming it's
-  // foregrounded.
-  // TODO(bashi): Don't assume the process is foregrounded. It can be added
-  // as a background process.
-  auto new_state = GetMemoryCondition() == MemoryCondition::CRITICAL
-                       ? MemoryState::THROTTLED
-                       : MemoryState::NORMAL;
+  RenderProcessHost* render_process_host =
+      GetRenderProcessHost(render_process_id);
+  if (!render_process_host)
+    return;
+
+  // Populate an initial state of a newly created process.
+  // TODO(bashi): IsProcessBackgrounded() may return true even when tabs in the
+  // renderer process are invisible (e.g. restoring tabs all at once).
+  // Figure out a better way to set visibility.
+  OnChildVisibilityChanged(render_process_id,
+                           !render_process_host->IsProcessBackgrounded());
+}
+
+void MemoryCoordinatorImpl::OnChildVisibilityChanged(int render_process_id,
+                                                     bool is_visible) {
+  auto iter = children().find(render_process_id);
+  if (iter == children().end())
+    return;
+
+  iter->second.is_visible = is_visible;
+  MemoryState new_state =
+      CalculateMemoryStateForProcess(GetMemoryCondition(), is_visible);
   SetChildMemoryState(render_process_id, new_state);
 }
 
diff --git a/content/browser/memory/memory_coordinator_impl.h b/content/browser/memory/memory_coordinator_impl.h
index 7bf66b1..4b63fb4c 100644
--- a/content/browser/memory/memory_coordinator_impl.h
+++ b/content/browser/memory/memory_coordinator_impl.h
@@ -160,6 +160,7 @@
   FRIEND_TEST_ALL_PREFIXES(MemoryCoordinatorWithServiceWorkerTest,
                            CannotSuspendRendererWithServiceWorker);
 #endif
+  FRIEND_TEST_ALL_PREFIXES(MemoryCoordinatorImplTest, OnChildVisibilityChanged);
   FRIEND_TEST_ALL_PREFIXES(MemoryCoordinatorImplTest, CalculateNextCondition);
   FRIEND_TEST_ALL_PREFIXES(MemoryCoordinatorImplTest, UpdateCondition);
   FRIEND_TEST_ALL_PREFIXES(MemoryCoordinatorImplTest, SetMemoryStateForTesting);
@@ -171,6 +172,9 @@
   // Called when ChildMemoryCoordinator calls AddChild().
   void OnChildAdded(int render_process_id);
 
+  // Called when visibility of a child process is changed.
+  void OnChildVisibilityChanged(int render_process_id, bool is_visible);
+
   // Called by SetChildMemoryState() to determine a child memory state based on
   // the current status of the child process.
   MemoryState OverrideState(MemoryState memroy_state, const ChildInfo& child);
diff --git a/content/browser/memory/memory_coordinator_impl_unittest.cc b/content/browser/memory/memory_coordinator_impl_unittest.cc
index d0c7413..7104ef9 100644
--- a/content/browser/memory/memory_coordinator_impl_unittest.cc
+++ b/content/browser/memory/memory_coordinator_impl_unittest.cc
@@ -303,6 +303,38 @@
   render_process_host->DecrementSharedWorkerRefCount();
 }
 
+TEST_F(MemoryCoordinatorImplTest, OnChildVisibilityChanged) {
+  auto* child = coordinator_->CreateChildMemoryCoordinator(1);
+
+  coordinator_->memory_condition_ = MemoryCondition::NORMAL;
+  coordinator_->OnChildVisibilityChanged(1, true);
+  RunUntilIdle();
+  EXPECT_EQ(mojom::MemoryState::NORMAL, child->state());
+  coordinator_->OnChildVisibilityChanged(1, false);
+  RunUntilIdle();
+#if defined(OS_ANDROID)
+  EXPECT_EQ(mojom::MemoryState::THROTTLED, child->state());
+#else
+  EXPECT_EQ(mojom::MemoryState::NORMAL, child->state());
+#endif
+
+  coordinator_->memory_condition_ = MemoryCondition::WARNING;
+  coordinator_->OnChildVisibilityChanged(1, true);
+  RunUntilIdle();
+  EXPECT_EQ(mojom::MemoryState::NORMAL, child->state());
+  coordinator_->OnChildVisibilityChanged(1, false);
+  RunUntilIdle();
+  EXPECT_EQ(mojom::MemoryState::THROTTLED, child->state());
+
+  coordinator_->memory_condition_ = MemoryCondition::CRITICAL;
+  coordinator_->OnChildVisibilityChanged(1, true);
+  RunUntilIdle();
+  EXPECT_EQ(mojom::MemoryState::THROTTLED, child->state());
+  coordinator_->OnChildVisibilityChanged(1, false);
+  RunUntilIdle();
+  EXPECT_EQ(mojom::MemoryState::THROTTLED, child->state());
+}
+
 TEST_F(MemoryCoordinatorImplTest, CalculateNextCondition) {
   auto* condition_observer = coordinator_->condition_observer_.get();
   condition_observer->expected_renderer_size_ = 10;
diff --git a/content/browser/renderer_host/media/media_stream_ui_proxy.cc b/content/browser/renderer_host/media/media_stream_ui_proxy.cc
index 051a647..307d0b3 100644
--- a/content/browser/renderer_host/media/media_stream_ui_proxy.cc
+++ b/content/browser/renderer_host/media/media_stream_ui_proxy.cc
@@ -48,10 +48,6 @@
   ~Core();
 
   void RequestAccess(std::unique_ptr<MediaStreamRequest> request);
-  bool CheckAccess(const GURL& security_origin,
-                   MediaStreamType type,
-                   int process_id,
-                   int frame_id);
   void OnStarted(gfx::NativeViewId* window_id);
 
  private:
@@ -106,20 +102,6 @@
                            weak_factory_.GetWeakPtr()));
 }
 
-bool MediaStreamUIProxy::Core::CheckAccess(const GURL& security_origin,
-                                           MediaStreamType type,
-                                           int render_process_id,
-                                           int render_frame_id) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
-  RenderFrameHostDelegate* render_delegate =
-      GetRenderFrameHostDelegate(render_process_id, render_frame_id);
-  if (!render_delegate)
-    return false;
-
-  return render_delegate->CheckMediaAccessPermission(security_origin, type);
-}
-
 void MediaStreamUIProxy::Core::OnStarted(gfx::NativeViewId* window_id) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   if (ui_) {
@@ -194,23 +176,6 @@
                  base::Passed(&request)));
 }
 
-void MediaStreamUIProxy::CheckAccess(
-    const url::Origin& security_origin,
-    MediaStreamType type,
-    int render_process_id,
-    int render_frame_id,
-    const base::Callback<void(bool)>& callback) {
-  DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
-  BrowserThread::PostTaskAndReplyWithResult(
-      BrowserThread::UI, FROM_HERE,
-      base::Bind(&Core::CheckAccess, base::Unretained(core_.get()),
-                 security_origin.GetURL(), type, render_process_id,
-                 render_frame_id),
-      base::Bind(&MediaStreamUIProxy::OnCheckedAccess,
-                 weak_factory_.GetWeakPtr(), callback));
-}
-
 void MediaStreamUIProxy::OnStarted(const base::Closure& stop_callback,
                                    const WindowIdCallback& window_id_callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -257,14 +222,6 @@
     window_id_callback.Run(*window_id);
 }
 
-void MediaStreamUIProxy::OnCheckedAccess(
-    const base::Callback<void(bool)>& callback,
-    bool have_access) {
-  DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  if (!callback.is_null())
-    callback.Run(have_access);
-}
-
 FakeMediaStreamUIProxy::FakeMediaStreamUIProxy()
   : MediaStreamUIProxy(NULL),
     mic_access_(true),
@@ -346,33 +303,6 @@
                      MEDIA_DEVICE_OK));
 }
 
-void FakeMediaStreamUIProxy::CheckAccess(
-    const url::Origin& security_origin,
-    MediaStreamType type,
-    int render_process_id,
-    int render_frame_id,
-    const base::Callback<void(bool)>& callback) {
-  DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  DCHECK(type == MEDIA_DEVICE_AUDIO_CAPTURE ||
-         type == MEDIA_DEVICE_VIDEO_CAPTURE);
-
-  bool have_access = false;
-  if (base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
-          switches::kUseFakeUIForMediaStream) != "deny") {
-    have_access =
-        type == MEDIA_DEVICE_AUDIO_CAPTURE ? mic_access_ : camera_access_;
-  }
-
-  BrowserThread::PostTask(
-      BrowserThread::IO,
-      FROM_HERE,
-      base::Bind(&MediaStreamUIProxy::OnCheckedAccess,
-                 weak_factory_.GetWeakPtr(),
-                 callback,
-                 have_access));
-  return;
-}
-
 void FakeMediaStreamUIProxy::OnStarted(
     const base::Closure& stop_callback,
     const WindowIdCallback& window_id_callback) {}
diff --git a/content/browser/renderer_host/media/media_stream_ui_proxy.h b/content/browser/renderer_host/media/media_stream_ui_proxy.h
index 2e2e037..8f9a9f6 100644
--- a/content/browser/renderer_host/media/media_stream_ui_proxy.h
+++ b/content/browser/renderer_host/media/media_stream_ui_proxy.h
@@ -13,10 +13,6 @@
 #include "content/public/browser/browser_thread.h"
 #include "content/public/common/media_stream_request.h"
 
-namespace url {
-class Origin;
-}
-
 namespace content {
 
 class RenderFrameHostDelegate;
@@ -46,16 +42,6 @@
   virtual void RequestAccess(std::unique_ptr<MediaStreamRequest> request,
                              const ResponseCallback& response_callback);
 
-  // Checks if we have permission to access the microphone or camera. Note that
-  // this does not query the user, it checks any stored settings such as policy
-  // or extension permissions. |type| must be MEDIA_DEVICE_AUDIO_CAPTURE
-  // or MEDIA_DEVICE_VIDEO_CAPTURE.
-  virtual void CheckAccess(const url::Origin& security_origin,
-                           MediaStreamType type,
-                           int render_process_id,
-                           int render_frame_id,
-                           const base::Callback<void(bool)>& callback);
-
   // Notifies the UI that the MediaStream has been started. Must be called after
   // access has been approved using RequestAccess(). |stop_callback| is be
   // called on the IO thread after the user has requests the stream to be
@@ -104,11 +90,6 @@
   // MediaStreamUIProxy overrides.
   void RequestAccess(std::unique_ptr<MediaStreamRequest> request,
                      const ResponseCallback& response_callback) override;
-  void CheckAccess(const url::Origin& security_origin,
-                   MediaStreamType type,
-                   int render_process_id,
-                   int render_frame_id,
-                   const base::Callback<void(bool)>& callback) override;
   void OnStarted(const base::Closure& stop_callback,
                  const WindowIdCallback& window_id_callback) override;
 
diff --git a/content/browser/renderer_host/media/media_stream_ui_proxy_unittest.cc b/content/browser/renderer_host/media/media_stream_ui_proxy_unittest.cc
index 90fc678..adb4a76 100644
--- a/content/browser/renderer_host/media/media_stream_ui_proxy_unittest.cc
+++ b/content/browser/renderer_host/media/media_stream_ui_proxy_unittest.cc
@@ -258,14 +258,4 @@
   base::RunLoop().RunUntilIdle();
 }
 
-TEST_F(MediaStreamUIProxyTest, CheckAccess) {
-  proxy_->CheckAccess(url::Origin(GURL("http://origin/")),
-                      MEDIA_DEVICE_AUDIO_CAPTURE, 0, 0,
-                      base::Bind(&MockResponseCallback::OnCheckResponse,
-                                 base::Unretained(&response_callback_)));
-  EXPECT_CALL(delegate_, CheckMediaAccessPermission(_, _));
-  EXPECT_CALL(response_callback_, OnCheckResponse(_));
-  base::RunLoop().RunUntilIdle();
-}
-
 }  // namespace content
diff --git a/content/browser/renderer_host/pepper/pepper_socket_utils.cc b/content/browser/renderer_host/pepper/pepper_socket_utils.cc
index 822bc565..bf2a4c7fc 100644
--- a/content/browser/renderer_host/pepper/pepper_socket_utils.cc
+++ b/content/browser/renderer_host/pepper/pepper_socket_utils.cc
@@ -80,36 +80,36 @@
                           ppapi::PPB_X509Certificate_Fields* fields) {
   const net::CertPrincipal& issuer = cert.issuer();
   fields->SetField(PP_X509CERTIFICATE_PRIVATE_ISSUER_COMMON_NAME,
-                   base::MakeUnique<base::StringValue>(issuer.common_name));
+                   base::MakeUnique<base::Value>(issuer.common_name));
   fields->SetField(PP_X509CERTIFICATE_PRIVATE_ISSUER_LOCALITY_NAME,
-                   base::MakeUnique<base::StringValue>(issuer.locality_name));
+                   base::MakeUnique<base::Value>(issuer.locality_name));
   fields->SetField(
       PP_X509CERTIFICATE_PRIVATE_ISSUER_STATE_OR_PROVINCE_NAME,
-      base::MakeUnique<base::StringValue>(issuer.state_or_province_name));
+      base::MakeUnique<base::Value>(issuer.state_or_province_name));
   fields->SetField(PP_X509CERTIFICATE_PRIVATE_ISSUER_COUNTRY_NAME,
-                   base::MakeUnique<base::StringValue>(issuer.country_name));
+                   base::MakeUnique<base::Value>(issuer.country_name));
   fields->SetField(PP_X509CERTIFICATE_PRIVATE_ISSUER_ORGANIZATION_NAME,
-                   base::MakeUnique<base::StringValue>(
+                   base::MakeUnique<base::Value>(
                        base::JoinString(issuer.organization_names, "\n")));
   fields->SetField(PP_X509CERTIFICATE_PRIVATE_ISSUER_ORGANIZATION_UNIT_NAME,
-                   base::MakeUnique<base::StringValue>(
+                   base::MakeUnique<base::Value>(
                        base::JoinString(issuer.organization_unit_names, "\n")));
 
   const net::CertPrincipal& subject = cert.subject();
   fields->SetField(PP_X509CERTIFICATE_PRIVATE_SUBJECT_COMMON_NAME,
-                   base::MakeUnique<base::StringValue>(subject.common_name));
+                   base::MakeUnique<base::Value>(subject.common_name));
   fields->SetField(PP_X509CERTIFICATE_PRIVATE_SUBJECT_LOCALITY_NAME,
-                   base::MakeUnique<base::StringValue>(subject.locality_name));
+                   base::MakeUnique<base::Value>(subject.locality_name));
   fields->SetField(
       PP_X509CERTIFICATE_PRIVATE_SUBJECT_STATE_OR_PROVINCE_NAME,
-      base::MakeUnique<base::StringValue>(subject.state_or_province_name));
+      base::MakeUnique<base::Value>(subject.state_or_province_name));
   fields->SetField(PP_X509CERTIFICATE_PRIVATE_SUBJECT_COUNTRY_NAME,
-                   base::MakeUnique<base::StringValue>(subject.country_name));
+                   base::MakeUnique<base::Value>(subject.country_name));
   fields->SetField(PP_X509CERTIFICATE_PRIVATE_SUBJECT_ORGANIZATION_NAME,
-                   base::MakeUnique<base::StringValue>(
+                   base::MakeUnique<base::Value>(
                        base::JoinString(subject.organization_names, "\n")));
   fields->SetField(PP_X509CERTIFICATE_PRIVATE_SUBJECT_ORGANIZATION_UNIT_NAME,
-                   base::MakeUnique<base::StringValue>(base::JoinString(
+                   base::MakeUnique<base::Value>(base::JoinString(
                        subject.organization_unit_names, "\n")));
 
   const std::string& serial_number = cert.serial_number();
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
index 4afec65e..15b8995 100644
--- a/content/browser/renderer_host/render_widget_host_impl.cc
+++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -294,7 +294,6 @@
       last_event_type_(blink::WebInputEvent::Undefined),
       new_content_rendering_delay_(
           base::TimeDelta::FromMilliseconds(kNewContentRenderingDelayMs)),
-      current_content_source_id_(0),
       weak_factory_(this) {
   CHECK(delegate_);
   CHECK_NE(MSG_ROUTING_NONE, routing_id_);
@@ -986,9 +985,7 @@
   RendererIsResponsive();
 }
 
-void RenderWidgetHostImpl::StartNewContentRenderingTimeout(
-    uint32_t next_source_id) {
-  current_content_source_id_ = next_source_id;
+void RenderWidgetHostImpl::StartNewContentRenderingTimeout() {
   // It is possible for a compositor frame to arrive before the browser is
   // notified about the page being committed, in which case no timer is
   // necessary.
@@ -1832,13 +1829,7 @@
   if (touch_emulator_)
     touch_emulator_->SetDoubleTapSupportForPageEnabled(!is_mobile_optimized);
 
-  // Ignore this frame if its content has already been unloaded. Source ID
-  // is always zero for an OOPIF because we are only concerned with displaying
-  // stale graphics on top-level frames. We accept frames that have a source ID
-  // greater than |current_content_source_id_| because in some cases the first
-  // compositor frame can arrive before the navigation commit message that
-  // updates that value.
-  if (view_ && frame.metadata.content_source_id >= current_content_source_id_) {
+  if (view_) {
     view_->OnSwapCompositorFrame(compositor_frame_sink_id, std::move(frame));
     view_->DidReceiveRendererFrame();
   } else {
diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h
index 11dddf1..b6aa99ec 100644
--- a/content/browser/renderer_host/render_widget_host_impl.h
+++ b/content/browser/renderer_host/render_widget_host_impl.h
@@ -325,10 +325,8 @@
   void StopHangMonitorTimeout();
 
   // Starts the rendering timeout, which will clear displayed graphics if
-  // a new compositor frame is not received before it expires. This also causes
-  // any new compositor frames received with content_source_id less than
-  // |next_source_id| to be discarded.
-  void StartNewContentRenderingTimeout(uint32_t next_source_id);
+  // a new compositor frame is not received before it expires.
+  void StartNewContentRenderingTimeout();
 
   // Notification that a new compositor frame has been generated following
   // a page load. This stops |new_content_rendering_timeout_|, or prevents
@@ -891,14 +889,6 @@
   // renderer process before clearing any previously displayed content.
   base::TimeDelta new_content_rendering_delay_;
 
-  // This identifier tags compositor frames according to the page load with
-  // which they are associated, to prevent an unloaded web page from being
-  // drawn after a navigation to a new page has already committed. This is
-  // a no-op for non-top-level RenderWidgets, as that should always be zero.
-  // TODO(kenrb, fsamuel): We should use SurfaceIDs for this purpose when they
-  // are available in the renderer process. See https://crbug.com/695579.
-  uint32_t current_content_source_id_;
-
 #if defined(OS_MACOSX)
   std::unique_ptr<device::PowerSaveBlocker> power_save_blocker_;
 #endif
diff --git a/content/browser/renderer_host/render_widget_host_unittest.cc b/content/browser/renderer_host/render_widget_host_unittest.cc
index 7b74276..439ffcc 100644
--- a/content/browser/renderer_host/render_widget_host_unittest.cc
+++ b/content/browser/renderer_host/render_widget_host_unittest.cc
@@ -1242,7 +1242,7 @@
       base::TimeDelta::FromMicroseconds(10));
 
   // Test immediate start and stop, ensuring that the timeout doesn't fire.
-  host_->StartNewContentRenderingTimeout(0);
+  host_->StartNewContentRenderingTimeout();
   host_->OnFirstPaintAfterLoad();
   base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
       FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(),
@@ -1254,7 +1254,7 @@
   // Test that the timer doesn't fire if it receives a stop before
   // a start.
   host_->OnFirstPaintAfterLoad();
-  host_->StartNewContentRenderingTimeout(0);
+  host_->StartNewContentRenderingTimeout();
   base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
       FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(),
       TimeDelta::FromMicroseconds(20));
@@ -1263,7 +1263,7 @@
   EXPECT_FALSE(host_->new_content_rendering_timeout_fired());
 
   // Test with a long delay to ensure that it does fire this time.
-  host_->StartNewContentRenderingTimeout(0);
+  host_->StartNewContentRenderingTimeout();
   base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
       FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(),
       TimeDelta::FromMicroseconds(20));
@@ -1271,39 +1271,6 @@
   EXPECT_TRUE(host_->new_content_rendering_timeout_fired());
 }
 
-// This tests that a compositor frame received with a stale content source ID
-// in its metadata is properly discarded.
-TEST_F(RenderWidgetHostTest, SwapCompositorFrameWithBadSourceId) {
-  host_->StartNewContentRenderingTimeout(100);
-  host_->OnFirstPaintAfterLoad();
-
-  // First swap a frame with an invalid ID.
-  cc::CompositorFrame frame;
-  frame.metadata.content_source_id = 99;
-  host_->OnMessageReceived(ViewHostMsg_SwapCompositorFrame(
-      0, 0, frame, std::vector<IPC::Message>()));
-  EXPECT_FALSE(
-      static_cast<TestView*>(host_->GetView())->did_swap_compositor_frame());
-  static_cast<TestView*>(host_->GetView())->reset_did_swap_compositor_frame();
-
-  // Test with a valid content ID as a control.
-  frame.metadata.content_source_id = 100;
-  host_->OnMessageReceived(ViewHostMsg_SwapCompositorFrame(
-      0, 0, frame, std::vector<IPC::Message>()));
-  EXPECT_TRUE(
-      static_cast<TestView*>(host_->GetView())->did_swap_compositor_frame());
-  static_cast<TestView*>(host_->GetView())->reset_did_swap_compositor_frame();
-
-  // We also accept frames with higher content IDs, to cover the case where
-  // the browser process receives a compositor frame for a new page before
-  // the corresponding DidCommitProvisionalLoad (it's a race).
-  frame.metadata.content_source_id = 101;
-  host_->OnMessageReceived(ViewHostMsg_SwapCompositorFrame(
-      0, 0, frame, std::vector<IPC::Message>()));
-  EXPECT_TRUE(
-      static_cast<TestView*>(host_->GetView())->did_swap_compositor_frame());
-}
-
 TEST_F(RenderWidgetHostTest, TouchEmulator) {
   simulated_event_time_delta_seconds_ = 0.1;
   // Immediately ack all touches instead of sending them to the renderer.
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm
index b67a5f3..4bbf13f 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -3419,7 +3419,7 @@
   BOOL returnTypeIsString = [returnType isEqual:NSStringPboardType];
   const content::TextInputManager::TextSelection* selection =
       renderWidgetHostView_->GetTextSelection();
-  BOOL hasText = !selection || selection->selected_text().empty();
+  BOOL hasText = selection && !selection->selected_text().empty();
   BOOL takesText =
       renderWidgetHostView_->GetTextInputType() != ui::TEXT_INPUT_TYPE_NONE;
 
diff --git a/content/browser/service_worker/service_worker_internals_ui.cc b/content/browser/service_worker/service_worker_internals_ui.cc
index a0665f4..5dd7a48a0 100644
--- a/content/browser/service_worker/service_worker_internals_ui.cc
+++ b/content/browser/service_worker/service_worker_internals_ui.cc
@@ -36,7 +36,6 @@
 
 using base::DictionaryValue;
 using base::ListValue;
-using base::StringValue;
 using base::Value;
 using base::WeakPtr;
 
@@ -262,7 +261,7 @@
   args.push_back(GetVersionListValue(live_versions));
   args.push_back(GetRegistrationListValue(stored_registrations));
   args.push_back(base::MakeUnique<Value>(partition_id));
-  args.push_back(base::MakeUnique<StringValue>(context_path.value()));
+  args.push_back(base::MakeUnique<Value>(context_path.value()));
   internals->web_ui()->CallJavascriptFunctionUnsafe(
       "serviceworker.onPartitionData", ConvertToRawPtrVector(args));
 }
@@ -281,14 +280,14 @@
     DCHECK_CURRENTLY_ON(BrowserThread::UI);
     web_ui_->CallJavascriptFunctionUnsafe(
         "serviceworker.onRunningStateChanged", Value(partition_id_),
-        StringValue(base::Int64ToString(version_id)));
+        Value(base::Int64ToString(version_id)));
   }
   void OnVersionStateChanged(int64_t version_id,
                              ServiceWorkerVersion::Status) override {
     DCHECK_CURRENTLY_ON(BrowserThread::UI);
     web_ui_->CallJavascriptFunctionUnsafe(
         "serviceworker.onVersionStateChanged", Value(partition_id_),
-        StringValue(base::Int64ToString(version_id)));
+        Value(base::Int64ToString(version_id)));
   }
   void OnErrorReported(int64_t version_id,
                        int process_id,
@@ -297,8 +296,7 @@
     DCHECK_CURRENTLY_ON(BrowserThread::UI);
     std::vector<std::unique_ptr<const Value>> args;
     args.push_back(base::MakeUnique<Value>(partition_id_));
-    args.push_back(
-        base::MakeUnique<StringValue>(base::Int64ToString(version_id)));
+    args.push_back(base::MakeUnique<Value>(base::Int64ToString(version_id)));
     args.push_back(base::MakeUnique<Value>(process_id));
     args.push_back(base::MakeUnique<Value>(thread_id));
     auto value = base::MakeUnique<DictionaryValue>();
@@ -317,8 +315,7 @@
     DCHECK_CURRENTLY_ON(BrowserThread::UI);
     std::vector<std::unique_ptr<const Value>> args;
     args.push_back(base::MakeUnique<Value>(partition_id_));
-    args.push_back(
-        base::MakeUnique<StringValue>(base::Int64ToString(version_id)));
+    args.push_back(base::MakeUnique<Value>(base::Int64ToString(version_id)));
     args.push_back(base::MakeUnique<Value>(process_id));
     args.push_back(base::MakeUnique<Value>(thread_id));
     auto value = base::MakeUnique<DictionaryValue>();
@@ -335,12 +332,12 @@
                             const GURL& pattern) override {
     DCHECK_CURRENTLY_ON(BrowserThread::UI);
     web_ui_->CallJavascriptFunctionUnsafe("serviceworker.onRegistrationStored",
-                                          StringValue(pattern.spec()));
+                                          Value(pattern.spec()));
   }
   void OnRegistrationDeleted(int64_t registration_id,
                              const GURL& pattern) override {
     web_ui_->CallJavascriptFunctionUnsafe("serviceworker.onRegistrationDeleted",
-                                          StringValue(pattern.spec()));
+                                          Value(pattern.spec()));
   }
   int partition_id() const { return partition_id_; }
 
diff --git a/content/browser/tracing/etw_tracing_agent_win.cc b/content/browser/tracing/etw_tracing_agent_win.cc
index 8d4cfa20..4392084 100644
--- a/content/browser/tracing/etw_tracing_agent_win.cc
+++ b/content/browser/tracing/etw_tracing_agent_win.cc
@@ -166,15 +166,12 @@
 
   // Add fields to the event.
   std::unique_ptr<base::DictionaryValue> value(new base::DictionaryValue());
-  value->Set("guid", new base::StringValue("ClockSync"));
-  value->Set("walltime", new base::StringValue(
-      base::StringPrintf("%08X%08X",
-                         walltime_in_us.HighPart,
-                         walltime_in_us.LowPart)));
-  value->Set("tick", new base::StringValue(
-      base::StringPrintf("%08X%08X",
-                         now_in_us.HighPart,
-                         now_in_us.LowPart)));
+  value->Set("guid", new base::Value("ClockSync"));
+  value->Set("walltime",
+             new base::Value(base::StringPrintf(
+                 "%08X%08X", walltime_in_us.HighPart, walltime_in_us.LowPart)));
+  value->Set("tick", new base::Value(base::StringPrintf(
+                         "%08X%08X", now_in_us.HighPart, now_in_us.LowPart)));
 
   // Append it to the events buffer.
   events_->Append(value.release());
@@ -188,10 +185,10 @@
   // Add header fields to the event.
   LARGE_INTEGER ts_us;
   ts_us.QuadPart = event->Header.TimeStamp.QuadPart / 10;
-  value->Set("ts", new base::StringValue(
-      base::StringPrintf("%08X%08X", ts_us.HighPart, ts_us.LowPart)));
+  value->Set("ts", new base::Value(base::StringPrintf(
+                       "%08X%08X", ts_us.HighPart, ts_us.LowPart)));
 
-  value->Set("guid", new base::StringValue(GuidToString(event->Header.Guid)));
+  value->Set("guid", new base::Value(GuidToString(event->Header.Guid)));
 
   value->Set("op", new Value(event->Header.Class.Type));
   value->Set("ver", new Value(event->Header.Class.Version));
@@ -204,7 +201,7 @@
                            event->MofLength);
   std::string payload;
   base::Base64Encode(buffer, &payload);
-  value->Set("payload", new base::StringValue(payload));
+  value->Set("payload", new base::Value(payload));
 
   // Append it to the events buffer.
   events_->Append(value.release());
@@ -228,7 +225,7 @@
     const StopAgentTracingCallback& callback) {
   // Add the header information to the stream.
   std::unique_ptr<base::DictionaryValue> header(new base::DictionaryValue());
-  header->Set("name", new base::StringValue("ETW"));
+  header->Set("name", new base::Value("ETW"));
 
   // Release and pass the events buffer.
   header->Set("content", events_.release());
diff --git a/content/browser/tracing/tracing_ui.cc b/content/browser/tracing/tracing_ui.cc
index ca612ba23..56a4c05 100644
--- a/content/browser/tracing/tracing_ui.cc
+++ b/content/browser/tracing/tracing_ui.cc
@@ -247,7 +247,7 @@
   std::string file_contents_base64;
   if (!args || args->empty() || !args->GetString(0, &file_contents_base64)) {
     web_ui()->CallJavascriptFunctionUnsafe("onUploadError",
-                                           base::StringValue("Missing data"));
+                                           base::Value("Missing data"));
     return;
   }
 
@@ -263,7 +263,7 @@
   std::string file_contents;
   if (!args || args->empty() || !args->GetString(0, &file_contents)) {
     web_ui()->CallJavascriptFunctionUnsafe("onUploadError",
-                                           base::StringValue("Missing data"));
+                                           base::Value("Missing data"));
     return;
   }
 
@@ -273,14 +273,14 @@
 void TracingUI::DoUploadInternal(const std::string& file_contents,
                                  TraceUploader::UploadMode upload_mode) {
   if (!delegate_) {
-    web_ui()->CallJavascriptFunctionUnsafe(
-        "onUploadError", base::StringValue("Not implemented"));
+    web_ui()->CallJavascriptFunctionUnsafe("onUploadError",
+                                           base::Value("Not implemented"));
     return;
   }
 
   if (trace_uploader_) {
-    web_ui()->CallJavascriptFunctionUnsafe(
-        "onUploadError", base::StringValue("Upload in progress"));
+    web_ui()->CallJavascriptFunctionUnsafe("onUploadError",
+                                           base::Value("Upload in progress"));
     return;
   }
 
@@ -306,18 +306,18 @@
   int percent = (current / total) * 100;
   web_ui()->CallJavascriptFunctionUnsafe(
       "onUploadProgress", base::Value(percent),
-      base::StringValue(base::StringPrintf("%" PRId64, current)),
-      base::StringValue(base::StringPrintf("%" PRId64, total)));
+      base::Value(base::StringPrintf("%" PRId64, current)),
+      base::Value(base::StringPrintf("%" PRId64, total)));
 }
 
 void TracingUI::OnTraceUploadComplete(bool success,
                                       const std::string& feedback) {
   if (success) {
     web_ui()->CallJavascriptFunctionUnsafe("onUploadComplete",
-                                           base::StringValue(feedback));
+                                           base::Value(feedback));
   } else {
     web_ui()->CallJavascriptFunctionUnsafe("onUploadError",
-                                           base::StringValue(feedback));
+                                           base::Value(feedback));
   }
   trace_uploader_.reset();
 }
diff --git a/content/browser/web_contents/web_contents_android.cc b/content/browser/web_contents/web_contents_android.cc
index 842b860..a93fad88 100644
--- a/content/browser/web_contents/web_contents_android.cc
+++ b/content/browser/web_contents/web_contents_android.cc
@@ -39,6 +39,7 @@
 #include "net/android/network_library.h"
 #include "ui/accessibility/ax_node_data.h"
 #include "ui/android/overscroll_refresh_handler.h"
+#include "ui/android/window_android.h"
 #include "ui/gfx/android/java_bitmap.h"
 #include "ui/gfx/geometry/rect.h"
 
@@ -284,6 +285,15 @@
   return base::android::ScopedJavaLocalRef<jobject>(obj_);
 }
 
+base::android::ScopedJavaLocalRef<jobject>
+WebContentsAndroid::GetTopLevelNativeWindow(JNIEnv* env,
+                                            const JavaParamRef<jobject>& obj) {
+  ui::WindowAndroid* window_android = web_contents_->GetTopLevelNativeWindow();
+  if (!window_android)
+    return nullptr;
+  return window_android->GetJavaObject();
+}
+
 ScopedJavaLocalRef<jstring> WebContentsAndroid::GetTitle(
     JNIEnv* env,
     const JavaParamRef<jobject>& obj) const {
diff --git a/content/browser/web_contents/web_contents_android.h b/content/browser/web_contents/web_contents_android.h
index 171006b5..041014da 100644
--- a/content/browser/web_contents/web_contents_android.h
+++ b/content/browser/web_contents/web_contents_android.h
@@ -39,6 +39,9 @@
   base::android::ScopedJavaLocalRef<jobject> GetJavaObject();
 
   // Methods called from Java
+  base::android::ScopedJavaLocalRef<jobject> GetTopLevelNativeWindow(
+      JNIEnv* env,
+      const base::android::JavaParamRef<jobject>& obj);
   base::android::ScopedJavaLocalRef<jstring> GetTitle(
       JNIEnv* env,
       const base::android::JavaParamRef<jobject>& obj) const;
diff --git a/content/browser/webrtc/webrtc_internals.cc b/content/browser/webrtc/webrtc_internals.cc
index dee0c97f..6f22232 100644
--- a/content/browser/webrtc/webrtc_internals.cc
+++ b/content/browser/webrtc/webrtc_internals.cc
@@ -35,20 +35,26 @@
 
 namespace {
 
-static base::LazyInstance<WebRTCInternals>::Leaky g_webrtc_internals =
+base::LazyInstance<WebRTCInternals>::Leaky g_webrtc_internals =
     LAZY_INSTANCE_INITIALIZER;
 
 // Makes sure that |dict| has a ListValue under path "log".
-static base::ListValue* EnsureLogList(base::DictionaryValue* dict) {
+base::ListValue* EnsureLogList(base::DictionaryValue* dict) {
   base::ListValue* log = NULL;
   if (!dict->GetList("log", &log)) {
     log = new base::ListValue();
-    if (log)
-      dict->Set("log", log);
+    dict->Set("log", log);
   }
   return log;
 }
 
+// Removes the log entry associated with a given record.
+void FreeLogList(base::Value* value) {
+  DCHECK(value->IsType(base::Value::Type::DICTIONARY));
+  auto* dict = static_cast<base::DictionaryValue*>(value);
+  dict->Remove("log", nullptr);
+}
+
 }  // namespace
 
 WebRTCInternals::PendingUpdate::PendingUpdate(
@@ -123,6 +129,9 @@
                                           const string& constraints) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
+  // TODO(tommi): Consider changing this design so that webrtc-internals has
+  // minimal impact if chrome://webrtc-internals isn't open.
+
   std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
   dict->SetInteger("rid", render_process_id);
   dict->SetInteger("pid", static_cast<int>(pid));
@@ -148,28 +157,19 @@
 
 void WebRTCInternals::OnRemovePeerConnection(ProcessId pid, int lid) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  for (size_t i = 0; i < peer_connection_data_.GetSize(); ++i) {
-    base::DictionaryValue* dict = NULL;
-    peer_connection_data_.GetDictionary(i, &dict);
 
-    int this_pid = 0;
-    int this_lid = 0;
-    dict->GetInteger("pid", &this_pid);
-    dict->GetInteger("lid", &this_lid);
-
-    if (this_pid != static_cast<int>(pid) || this_lid != lid)
-      continue;
-
+  size_t index;
+  base::DictionaryValue* dict = FindRecord(pid, lid, &index);
+  if (dict) {
     MaybeClosePeerConnection(dict);
-    peer_connection_data_.Remove(i, NULL);
+    peer_connection_data_.Remove(index, NULL);
+  }
 
-    if (observers_.might_have_observers()) {
-      std::unique_ptr<base::DictionaryValue> id(new base::DictionaryValue());
-      id->SetInteger("pid", static_cast<int>(pid));
-      id->SetInteger("lid", lid);
-      SendUpdate("removePeerConnection", std::move(id));
-    }
-    break;
+  if (observers_.might_have_observers()) {
+    std::unique_ptr<base::DictionaryValue> id(new base::DictionaryValue());
+    id->SetInteger("pid", static_cast<int>(pid));
+    id->SetInteger("lid", lid);
+    SendUpdate("removePeerConnection", std::move(id));
   }
 }
 
@@ -177,49 +177,34 @@
     ProcessId pid, int lid, const string& type, const string& value) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
-  for (size_t i = 0; i < peer_connection_data_.GetSize(); ++i) {
-    base::DictionaryValue* record = NULL;
-    peer_connection_data_.GetDictionary(i, &record);
-
-    int this_pid = 0, this_lid = 0;
-    record->GetInteger("pid", &this_pid);
-    record->GetInteger("lid", &this_lid);
-
-    if (this_pid != static_cast<int>(pid) || this_lid != lid)
-      continue;
-
-    if (type == "stop") {
-      MaybeClosePeerConnection(record);
-    }
-
-    // Append the update to the end of the log.
-    base::ListValue* log = EnsureLogList(record);
-    if (!log)
-      return;
-
-    std::unique_ptr<base::DictionaryValue> log_entry(
-        new base::DictionaryValue());
-
-    double epoch_time = base::Time::Now().ToJsTime();
-    string time = base::DoubleToString(epoch_time);
-    log_entry->SetString("time", time);
-    log_entry->SetString("type", type);
-    log_entry->SetString("value", value);
-
-    if (observers_.might_have_observers()) {
-      std::unique_ptr<base::DictionaryValue> update(
-          new base::DictionaryValue());
-      update->SetInteger("pid", static_cast<int>(pid));
-      update->SetInteger("lid", lid);
-      update->MergeDictionary(log_entry.get());
-
-      SendUpdate("updatePeerConnection", std::move(update));
-    }
-
-    log->Append(std::move(log_entry));
-
+  base::DictionaryValue* record = FindRecord(pid, lid);
+  if (!record)
     return;
-  }
+
+  if (type == "stop")
+    MaybeClosePeerConnection(record);
+
+  // Don't update entries if there aren't any observers.
+  if (!observers_.might_have_observers())
+    return;
+
+  std::unique_ptr<base::DictionaryValue> log_entry(new base::DictionaryValue());
+
+  double epoch_time = base::Time::Now().ToJsTime();
+  string time = base::DoubleToString(epoch_time);
+  log_entry->SetString("time", time);
+  log_entry->SetString("type", type);
+  log_entry->SetString("value", value);
+
+  std::unique_ptr<base::DictionaryValue> update(new base::DictionaryValue());
+  update->SetInteger("pid", static_cast<int>(pid));
+  update->SetInteger("lid", lid);
+  update->MergeDictionary(log_entry.get());
+
+  SendUpdate("updatePeerConnection", std::move(update));
+
+  // Append the update to the end of the log.
+  EnsureLogList(record)->Append(std::move(log_entry));
 }
 
 void WebRTCInternals::OnAddStats(base::ProcessId pid, int lid,
@@ -274,14 +259,17 @@
 void WebRTCInternals::RemoveObserver(WebRTCInternalsUIObserver* observer) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   observers_.RemoveObserver(observer);
+  if (observers_.might_have_observers())
+    return;
 
   // Disables event log and audio debug recordings if enabled and the last
   // webrtc-internals page is going away.
-  if (!observers_.might_have_observers()) {
-    if (audio_debug_recordings_)
-      DisableAudioDebugRecordings();
-    DisableEventLogRecordings();
-  }
+  DisableAudioDebugRecordings();
+  DisableEventLogRecordings();
+
+  // TODO(tommi): Consider removing all the peer_connection_data_.
+  for (auto& dictionary : peer_connection_data_)
+    FreeLogList(dictionary.get());
 }
 
 void WebRTCInternals::UpdateObserver(WebRTCInternalsUIObserver* observer) {
@@ -320,6 +308,9 @@
 void WebRTCInternals::DisableAudioDebugRecordings() {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 #if BUILDFLAG(ENABLE_WEBRTC)
+  if (!audio_debug_recordings_)
+    return;
+
   audio_debug_recordings_ = false;
 
   // Tear down the dialog since the user has unchecked the audio debug
@@ -577,4 +568,26 @@
   }
 }
 
+base::DictionaryValue* WebRTCInternals::FindRecord(
+    ProcessId pid,
+    int lid,
+    size_t* index /*= nullptr*/) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+  base::DictionaryValue* record = nullptr;
+  for (size_t i = 0; i < peer_connection_data_.GetSize(); ++i) {
+    peer_connection_data_.GetDictionary(i, &record);
+
+    int this_pid = 0, this_lid = 0;
+    record->GetInteger("pid", &this_pid);
+    record->GetInteger("lid", &this_lid);
+
+    if (this_pid == static_cast<int>(pid) && this_lid == lid) {
+      if (index)
+        *index = i;
+      return record;
+    }
+  }
+  return nullptr;
+}
 }  // namespace content
diff --git a/content/browser/webrtc/webrtc_internals.h b/content/browser/webrtc/webrtc_internals.h
index c20a5fb1..f2cde8a7 100644
--- a/content/browser/webrtc/webrtc_internals.h
+++ b/content/browser/webrtc/webrtc_internals.h
@@ -175,6 +175,10 @@
   // notifications.
   void ProcessPendingUpdates();
 
+  base::DictionaryValue* FindRecord(base::ProcessId pid,
+                                    int lid,
+                                    size_t* index = nullptr);
+
   base::ObserverList<WebRTCInternalsUIObserver> observers_;
 
   // |peer_connection_data_| is a list containing all the PeerConnection
diff --git a/content/browser/webrtc/webrtc_internals_unittest.cc b/content/browser/webrtc/webrtc_internals_unittest.cc
index cfea70f1..d14eef08 100644
--- a/content/browser/webrtc/webrtc_internals_unittest.cc
+++ b/content/browser/webrtc/webrtc_internals_unittest.cc
@@ -27,13 +27,9 @@
   MockWebRtcInternalsProxy() : loop_(nullptr) {}
   explicit MockWebRtcInternalsProxy(base::RunLoop* loop) : loop_(loop) {}
 
-  const std::string& command() const {
-    return command_;
-  }
+  const std::string& command() const { return command_; }
 
-  base::Value* value() {
-    return value_.get();
-  }
+  base::Value* value() { return value_.get(); }
 
  private:
   void OnUpdate(const char* command, const base::Value* value) override {
@@ -116,12 +112,10 @@
 
   webrtc_internals.RemoveObserver(&observer);
   // The observer should not get notified of this activity.
-  webrtc_internals.OnAddPeerConnection(
-      0, 3, 4, kUrl, kRtcConfiguration, kContraints);
+  webrtc_internals.OnAddPeerConnection(0, 3, 4, kUrl, kRtcConfiguration,
+                                       kContraints);
 
-  BrowserThread::PostDelayedTask(BrowserThread::UI, FROM_HERE,
-      loop.QuitClosure(),
-      base::TimeDelta::FromMilliseconds(5));
+  BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, loop.QuitClosure());
   loop.Run();
 
   EXPECT_EQ("", observer.command());
@@ -129,13 +123,74 @@
   webrtc_internals.OnRemovePeerConnection(3, 4);
 }
 
+TEST_F(WebRtcInternalsTest, EnsureNoLogWhenNoObserver) {
+  base::RunLoop loop;
+  WebRTCInternalsForTest webrtc_internals;
+  webrtc_internals.OnAddPeerConnection(0, 3, 4, kUrl, kRtcConfiguration,
+                                       kContraints);
+  webrtc_internals.OnUpdatePeerConnection(3, 4, "update_type", "update_value");
+  BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, loop.QuitClosure());
+  loop.Run();
+
+  // Make sure we don't have a log entry since there was no observer.
+  MockWebRtcInternalsProxy observer;
+  webrtc_internals.UpdateObserver(&observer);
+  EXPECT_EQ("updateAllPeerConnections", observer.command());
+
+  base::ListValue* list = nullptr;
+  ASSERT_TRUE(observer.value()->GetAsList(&list));
+  EXPECT_EQ(1U, list->GetSize());
+  base::DictionaryValue* dict = nullptr;
+  ASSERT_TRUE((*list->begin())->GetAsDictionary(&dict));
+  base::ListValue* log = nullptr;
+  ASSERT_FALSE(dict->GetList("log", &log));
+
+  webrtc_internals.OnRemovePeerConnection(3, 4);
+}
+
+TEST_F(WebRtcInternalsTest, EnsureLogIsRemovedWhenObserverIsRemoved) {
+  base::RunLoop loop;
+  WebRTCInternalsForTest webrtc_internals;
+  MockWebRtcInternalsProxy observer;
+  webrtc_internals.AddObserver(&observer);
+  webrtc_internals.OnAddPeerConnection(0, 3, 4, kUrl, kRtcConfiguration,
+                                       kContraints);
+  webrtc_internals.OnUpdatePeerConnection(3, 4, "update_type", "update_value");
+  BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, loop.QuitClosure());
+  loop.Run();
+
+  // Make sure we have a log entry since there was an observer.
+  webrtc_internals.UpdateObserver(&observer);
+  EXPECT_EQ("updateAllPeerConnections", observer.command());
+
+  base::ListValue* list = nullptr;
+  ASSERT_TRUE(observer.value()->GetAsList(&list));
+  EXPECT_EQ(1U, list->GetSize());
+  base::DictionaryValue* dict = nullptr;
+  ASSERT_TRUE((*list->begin())->GetAsDictionary(&dict));
+  base::ListValue* log = nullptr;
+  ASSERT_TRUE(dict->GetList("log", &log));
+
+  // Make sure we the log entry was removed when the last observer was removed.
+  webrtc_internals.RemoveObserver(&observer);
+  webrtc_internals.UpdateObserver(&observer);
+  EXPECT_EQ("updateAllPeerConnections", observer.command());
+
+  ASSERT_TRUE(observer.value()->GetAsList(&list));
+  EXPECT_EQ(1U, list->GetSize());
+  ASSERT_TRUE((*list->begin())->GetAsDictionary(&dict));
+  ASSERT_FALSE(dict->GetList("log", &log));
+
+  webrtc_internals.OnRemovePeerConnection(3, 4);
+}
+
 TEST_F(WebRtcInternalsTest, SendAddPeerConnectionUpdate) {
   base::RunLoop loop;
   MockWebRtcInternalsProxy observer(&loop);
   WebRTCInternalsForTest webrtc_internals;
   webrtc_internals.AddObserver(&observer);
-  webrtc_internals.OnAddPeerConnection(
-      0, 1, 2, kUrl, kRtcConfiguration, kContraints);
+  webrtc_internals.OnAddPeerConnection(0, 1, 2, kUrl, kRtcConfiguration,
+                                       kContraints);
 
   loop.Run();
 
@@ -159,8 +214,8 @@
   MockWebRtcInternalsProxy observer(&loop);
   WebRTCInternalsForTest webrtc_internals;
   webrtc_internals.AddObserver(&observer);
-  webrtc_internals.OnAddPeerConnection(
-      0, 1, 2, kUrl, kRtcConfiguration, kContraints);
+  webrtc_internals.OnAddPeerConnection(0, 1, 2, kUrl, kRtcConfiguration,
+                                       kContraints);
   webrtc_internals.OnRemovePeerConnection(1, 2);
 
   loop.Run();
@@ -181,13 +236,12 @@
   MockWebRtcInternalsProxy observer(&loop);
   WebRTCInternalsForTest webrtc_internals;
   webrtc_internals.AddObserver(&observer);
-  webrtc_internals.OnAddPeerConnection(
-      0, 1, 2, kUrl, kRtcConfiguration, kContraints);
+  webrtc_internals.OnAddPeerConnection(0, 1, 2, kUrl, kRtcConfiguration,
+                                       kContraints);
 
   const std::string update_type = "fakeType";
   const std::string update_value = "fakeValue";
-  webrtc_internals.OnUpdatePeerConnection(
-      1, 2, update_type, update_value);
+  webrtc_internals.OnUpdatePeerConnection(1, 2, update_type, update_value);
 
   loop.Run();
 
@@ -221,14 +275,14 @@
   const int pid = 2;
   const std::string audio_constraint = "aaa";
   const std::string video_constraint = "vvv";
-  webrtc_internals.OnGetUserMedia(
-      rid, pid, kUrl, true, true, audio_constraint, video_constraint);
+  webrtc_internals.OnGetUserMedia(rid, pid, kUrl, true, true, audio_constraint,
+                                  video_constraint);
 
   loop.Run();
 
   ASSERT_EQ("addGetUserMedia", observer.command());
-  VerifyGetUserMediaData(
-      observer.value(), rid, pid, kUrl, audio_constraint, video_constraint);
+  VerifyGetUserMediaData(observer.value(), rid, pid, kUrl, audio_constraint,
+                         video_constraint);
 
   webrtc_internals.RemoveObserver(&observer);
 }
@@ -239,8 +293,8 @@
   const std::string audio_constraint = "aaa";
   const std::string video_constraint = "vvv";
   WebRTCInternalsForTest webrtc_internals;
-  webrtc_internals.OnGetUserMedia(
-      rid, pid, kUrl, true, true, audio_constraint, video_constraint);
+  webrtc_internals.OnGetUserMedia(rid, pid, kUrl, true, true, audio_constraint,
+                                  video_constraint);
 
   MockWebRtcInternalsProxy observer;
   // Add one observer after "getUserMedia".
@@ -248,8 +302,8 @@
   webrtc_internals.UpdateObserver(&observer);
 
   EXPECT_EQ("addGetUserMedia", observer.command());
-  VerifyGetUserMediaData(
-      observer.value(), rid, pid, kUrl, audio_constraint, video_constraint);
+  VerifyGetUserMediaData(observer.value(), rid, pid, kUrl, audio_constraint,
+                         video_constraint);
 
   webrtc_internals.RemoveObserver(&observer);
 }
@@ -261,14 +315,13 @@
 
   WebRTCInternalsForTest webrtc_internals;
 
-  webrtc_internals.OnAddPeerConnection(
-      rid, pid, lid, kUrl, kRtcConfiguration, kContraints);
-  webrtc_internals.OnUpdatePeerConnection(
-      pid, lid, update_type, update_value);
-
   MockWebRtcInternalsProxy observer;
   webrtc_internals.AddObserver(&observer);
 
+  webrtc_internals.OnAddPeerConnection(rid, pid, lid, kUrl, kRtcConfiguration,
+                                       kContraints);
+  webrtc_internals.OnUpdatePeerConnection(pid, lid, update_type, update_value);
+
   webrtc_internals.UpdateObserver(&observer);
 
   EXPECT_EQ("updateAllPeerConnections", observer.command());
@@ -289,7 +342,7 @@
   VerifyString(dict, "constraints", kContraints);
 
   base::ListValue* log = NULL;
-  EXPECT_TRUE(dict->GetList("log", &log));
+  ASSERT_TRUE(dict->GetList("log", &log));
   EXPECT_EQ(1U, log->GetSize());
 
   EXPECT_TRUE((*log->begin())->GetAsDictionary(&dict));
@@ -306,8 +359,8 @@
   MockWebRtcInternalsProxy observer(&loop);
   WebRTCInternalsForTest webrtc_internals;
   webrtc_internals.AddObserver(&observer);
-  webrtc_internals.OnAddPeerConnection(
-      rid, pid, lid, kUrl, kRtcConfiguration, kContraints);
+  webrtc_internals.OnAddPeerConnection(rid, pid, lid, kUrl, kRtcConfiguration,
+                                       kContraints);
 
   base::ListValue list;
   list.AppendString("xxx");
@@ -344,8 +397,8 @@
 
 TEST_F(WebRtcInternalsTest, PowerSaveBlock) {
   int kRenderProcessId = 1;
-  int pid = 1;
-  int lid[] = {1, 2, 3};
+  const int pid = 1;
+  const int lid[] = {1, 2, 3};
 
   WebRTCInternalsForTest webrtc_internals;
 
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc
index c4073ed..28608481 100644
--- a/content/child/runtime_features.cc
+++ b/content/child/runtime_features.cc
@@ -45,6 +45,7 @@
   // Android does not yet support SystemMonitor.
   WebRuntimeFeatures::enableOnDeviceChange(false);
   WebRuntimeFeatures::enableMediaSession(true);
+  WebRuntimeFeatures::enableMediaControlsOverlayPlayButton(true);
 #else  // defined(OS_ANDROID)
   WebRuntimeFeatures::enableNavigatorContentUtils(true);
   if (base::FeatureList::IsEnabled(
diff --git a/content/child/v8_value_converter_impl.cc b/content/child/v8_value_converter_impl.cc
index c57bd15..b445760f 100644
--- a/content/child/v8_value_converter_impl.cc
+++ b/content/child/v8_value_converter_impl.cc
@@ -386,8 +386,7 @@
 
   if (val->IsString()) {
     v8::String::Utf8Value utf8(val);
-    return base::MakeUnique<base::StringValue>(
-        std::string(*utf8, utf8.length()));
+    return base::MakeUnique<base::Value>(std::string(*utf8, utf8.length()));
   }
 
   if (val->IsUndefined()) {
@@ -413,7 +412,7 @@
     if (!reg_exp_allowed_)
       // JSON.stringify converts to an object.
       return FromV8Object(val.As<v8::Object>(), state, isolate);
-    return base::MakeUnique<base::StringValue>(*v8::String::Utf8Value(val));
+    return base::MakeUnique<base::Value>(*v8::String::Utf8Value(val));
   }
 
   // v8::Value doesn't have a ToArray() method for some reason.
diff --git a/content/child/v8_value_converter_impl_unittest.cc b/content/child/v8_value_converter_impl_unittest.cc
index 83bf27e..2997770e 100644
--- a/content/child/v8_value_converter_impl_unittest.cc
+++ b/content/child/v8_value_converter_impl_unittest.cc
@@ -418,7 +418,7 @@
 
   converter.SetRegExpAllowed(true);
   TestWeirdType(converter, regex, base::Value::Type::STRING,
-                std::unique_ptr<base::Value>(new base::StringValue("/./")));
+                std::unique_ptr<base::Value>(new base::Value("/./")));
 }
 
 TEST_F(V8ValueConverterImplTest, Prototype) {
@@ -1021,7 +1021,7 @@
 
  private:
   static std::unique_ptr<base::Value> NewReferenceValue() {
-    return base::MakeUnique<base::StringValue>("strategy");
+    return base::MakeUnique<base::Value>("strategy");
   }
   std::unique_ptr<base::Value> reference_value_;
 };
diff --git a/content/child/web_url_loader_impl.cc b/content/child/web_url_loader_impl.cc
index eb948a9..e57df2a 100644
--- a/content/child/web_url_loader_impl.cc
+++ b/content/child/web_url_loader_impl.cc
@@ -928,9 +928,12 @@
   // For compatibility reasons on Android we need to expose top-level data://
   // to the browser. In tests resource_dispatcher_ can be null, and test pages
   // need to be loaded locally.
+  // For PlzNavigate, navigation requests were already checked in the browser.
   if (resource_dispatcher_ &&
-      request_.getFrameType() == WebURLRequest::FrameTypeTopLevel)
-    return false;
+      request_.getFrameType() == WebURLRequest::FrameTypeTopLevel) {
+    if (!IsBrowserSideNavigationEnabled())
+      return false;
+  }
 #endif
 
   if (request_.getFrameType() != WebURLRequest::FrameTypeTopLevel &&
diff --git a/content/common/common_param_traits_unittest.cc b/content/common/common_param_traits_unittest.cc
index 4756e22b..c5acf22 100644
--- a/content/common/common_param_traits_unittest.cc
+++ b/content/common/common_param_traits_unittest.cc
@@ -83,7 +83,7 @@
 TEST(IPCMessageTest, ListValue) {
   base::ListValue input;
   input.Set(0, new base::Value(42.42));
-  input.Set(1, new base::StringValue("forty"));
+  input.Set(1, new base::Value("forty"));
   input.Set(2, base::Value::CreateNullValue());
 
   IPC::Message msg(1, 2, IPC::Message::PRIORITY_NORMAL);
@@ -109,13 +109,13 @@
   input.Set("int", new base::Value(42));
 
   std::unique_ptr<base::DictionaryValue> subdict(new base::DictionaryValue());
-  subdict->Set("str", new base::StringValue("forty two"));
+  subdict->Set("str", new base::Value("forty two"));
   subdict->Set("bool", new base::Value(false));
 
   std::unique_ptr<base::ListValue> sublist(new base::ListValue());
   sublist->Set(0, new base::Value(42.42));
-  sublist->Set(1, new base::StringValue("forty"));
-  sublist->Set(2, new base::StringValue("two"));
+  sublist->Set(1, new base::Value("forty"));
+  sublist->Set(2, new base::Value("two"));
   subdict->Set("list", sublist.release());
 
   input.Set("dict", subdict.release());
diff --git a/content/common/font_list_mac.mm b/content/common/font_list_mac.mm
index d4768ae..5eebf2c 100644
--- a/content/common/font_list_mac.mm
+++ b/content/common/font_list_mac.mm
@@ -34,8 +34,8 @@
     base::ListValue* font_item = new base::ListValue();
     base::string16 family = base::SysNSStringToUTF16(family_name);
     base::string16 loc_family = base::SysNSStringToUTF16(localized_family_name);
-    font_item->Append(new base::StringValue(family));
-    font_item->Append(new base::StringValue(loc_family));
+    font_item->Append(new base::Value(family));
+    font_item->Append(new base::Value(loc_family));
     font_list->Append(font_item);
   }
 
diff --git a/content/common/font_list_win.cc b/content/common/font_list_win.cc
index 8d00e0a..38402c5 100644
--- a/content/common/font_list_win.cc
+++ b/content/common/font_list_win.cc
@@ -46,8 +46,8 @@
   std::set<base::string16>::iterator iter;
   for (iter = font_names.begin(); iter != font_names.end(); ++iter) {
     base::ListValue* font_item = new base::ListValue();
-    font_item->Append(new base::StringValue(*iter));
-    font_item->Append(new base::StringValue(*iter));
+    font_item->Append(new base::Value(*iter));
+    font_item->Append(new base::Value(*iter));
     font_list->Append(font_item);
   }
   return font_list;
diff --git a/content/common/frame_messages.h b/content/common/frame_messages.h
index 0442702..023494a3 100644
--- a/content/common/frame_messages.h
+++ b/content/common/frame_messages.h
@@ -301,11 +301,6 @@
   // in BeginNavigationParams.
   IPC_STRUCT_MEMBER(GURL, searchable_form_url)
   IPC_STRUCT_MEMBER(std::string, searchable_form_encoding)
-
-  // This is a non-decreasing value that the browser process can use to
-  // identify and discard compositor frames that correspond to now-unloaded
-  // web content.
-  IPC_STRUCT_MEMBER(uint32_t, content_source_id)
 IPC_STRUCT_END()
 
 IPC_STRUCT_BEGIN(FrameMsg_PostMessage_Params)
diff --git a/content/common/origin_trials/trial_token.cc b/content/common/origin_trials/trial_token.cc
index ab9debf..ecb8608 100644
--- a/content/common/origin_trials/trial_token.cc
+++ b/content/common/origin_trials/trial_token.cc
@@ -50,13 +50,19 @@
     blink::WebOriginTrialTokenStatus* out_status) {
   DCHECK(out_status);
   std::string token_payload;
-  *out_status = Extract(token_text, public_key, &token_payload);
+  std::string token_signature;
+  *out_status =
+      Extract(token_text, public_key, &token_payload, &token_signature);
   if (*out_status != blink::WebOriginTrialTokenStatus::Success) {
     return nullptr;
   }
   std::unique_ptr<TrialToken> token = Parse(token_payload);
-  *out_status = token ? blink::WebOriginTrialTokenStatus::Success
-                      : blink::WebOriginTrialTokenStatus::Malformed;
+  if (token) {
+    token->signature_ = token_signature;
+    *out_status = blink::WebOriginTrialTokenStatus::Success;
+  } else {
+    *out_status = blink::WebOriginTrialTokenStatus::Malformed;
+  }
   return token;
 }
 
@@ -78,7 +84,8 @@
 blink::WebOriginTrialTokenStatus TrialToken::Extract(
     const std::string& token_text,
     base::StringPiece public_key,
-    std::string* out_token_payload) {
+    std::string* out_token_payload,
+    std::string* out_token_signature) {
   if (token_text.empty()) {
     return blink::WebOriginTrialTokenStatus::Malformed;
   }
@@ -129,8 +136,9 @@
     return blink::WebOriginTrialTokenStatus::InvalidSignature;
   }
 
-  // Return just the payload, as a new string.
+  // Return the payload and signature, as new strings.
   *out_token_payload = token_contents.substr(kPayloadOffset, payload_length);
+  *out_token_signature = signature.as_string();
   return blink::WebOriginTrialTokenStatus::Success;
 }
 
diff --git a/content/common/origin_trials/trial_token.h b/content/common/origin_trials/trial_token.h
index 943275639..31daae3 100644
--- a/content/common/origin_trials/trial_token.h
+++ b/content/common/origin_trials/trial_token.h
@@ -60,6 +60,7 @@
   bool match_subdomains() const { return match_subdomains_; }
   std::string feature_name() { return feature_name_; }
   base::Time expiry_time() { return expiry_time_; }
+  std::string signature() { return signature_; }
 
  protected:
   // Tests can access the Parse method directly to validate it, and so are
@@ -69,14 +70,16 @@
   friend class TrialTokenTest;
   friend int ::LLVMFuzzerTestOneInput(const uint8_t*, size_t);
 
-  // If the string represents a properly signed and well-formed token, the token
-  // payload is returned in the |out_token_payload| parameter and success is
-  // returned. Otherwise,the return code indicates what was wrong with the
-  // string, and |out_token_payload| is unchanged.
+  // If the string represents a properly signed and well-formed token, success
+  // is returned, with the token payload and signature returned in the
+  // |out_token_payload| and |out_token_signature| parameters, respectively.
+  // Otherwise,the return code indicates what was wrong with the string, and
+  // |out_token_payload| and |out_token_signature| are unchanged.
   static blink::WebOriginTrialTokenStatus Extract(
       const std::string& token_text,
       base::StringPiece public_key,
-      std::string* out_token_payload);
+      std::string* out_token_payload,
+      std::string* out_token_signature);
 
   // Returns a token object if the string represents a well-formed JSON token
   // payload, or nullptr otherwise.
@@ -107,6 +110,9 @@
 
   // The time until which this token should be considered valid.
   base::Time expiry_time_;
+
+  // The signature identifying the fully signed contents of the token.
+  std::string signature_;
 };
 
 }  // namespace content
diff --git a/content/common/origin_trials/trial_token_unittest.cc b/content/common/origin_trials/trial_token_unittest.cc
index b5d396c..bffb88d 100644
--- a/content/common/origin_trials/trial_token_unittest.cc
+++ b/content/common/origin_trials/trial_token_unittest.cc
@@ -64,6 +64,13 @@
     "7FO5L22sNvkZZnacLvmfNwsAAABZeyJvcmlnaW4iOiAiaHR0cHM6Ly92YWxpZC5l"
     "eGFtcGxlLmNvbTo0NDMiLCAiZmVhdHVyZSI6ICJGcm9idWxhdGUiLCAiZXhwaXJ5"
     "IjogMTQ1ODc2NjI3N30=";
+const uint8_t kSampleTokenSignature[] = {
+    0x9f, 0x90, 0xfd, 0x09, 0xb4, 0x10, 0xb6, 0x9d, 0x66, 0xa9, 0x7e,
+    0x76, 0x51, 0x06, 0x4b, 0x09, 0xc0, 0x56, 0xc1, 0x59, 0x2a, 0x00,
+    0x84, 0xb5, 0x46, 0x60, 0xf2, 0x27, 0x50, 0x0b, 0x7b, 0x9e, 0x92,
+    0x42, 0x1e, 0x49, 0x92, 0x18, 0xd6, 0xd7, 0xed, 0xa1, 0x87, 0x6b,
+    0xc2, 0x1a, 0xa3, 0xec, 0x53, 0xb9, 0x2f, 0x6d, 0xac, 0x36, 0xf9,
+    0x19, 0x66, 0x76, 0x9c, 0x2e, 0xf9, 0x9f, 0x37, 0x0b};
 
 // This is a good subdomain trial token, signed with the above test private key.
 // Generate this token with the command (in tools/origin_trials):
@@ -74,6 +81,13 @@
     "FjpbmQG+VCPk1NrldVXZng4AAABoeyJvcmlnaW4iOiAiaHR0cHM6Ly9leGFtcGxl"
     "LmNvbTo0NDMiLCAiaXNTdWJkb21haW4iOiB0cnVlLCAiZmVhdHVyZSI6ICJGcm9i"
     "dWxhdGUiLCAiZXhwaXJ5IjogMTQ1ODc2NjI3N30=";
+const uint8_t kSampleSubdomainTokenSignature[] = {
+    0xeb, 0xbe, 0x8f, 0xd9, 0xd7, 0x01, 0x0a, 0x32, 0xe7, 0xeb, 0x74,
+    0xd0, 0xc8, 0x96, 0x6a, 0x46, 0x70, 0x14, 0x4c, 0x5c, 0x74, 0xd0,
+    0xbc, 0x10, 0xd9, 0x11, 0x74, 0xad, 0x60, 0x2f, 0x83, 0x8c, 0x14,
+    0x74, 0xb4, 0x01, 0xb6, 0x42, 0xb1, 0xcb, 0x25, 0x0d, 0x37, 0x0f,
+    0xd5, 0xf8, 0xcd, 0x16, 0x3a, 0x5b, 0x99, 0x01, 0xbe, 0x54, 0x23,
+    0xe4, 0xd4, 0xda, 0xe5, 0x75, 0x55, 0xd9, 0x9e, 0x0e};
 
 // This is a good trial token, explicitly not a subdomain, signed with the above
 // test private key. Generate this token with the command:
@@ -84,6 +98,13 @@
     "lvH52Winvy39tHbsU2gJJQYAAABveyJvcmlnaW4iOiAiaHR0cHM6Ly92YWxpZC5l"
     "eGFtcGxlLmNvbTo0NDMiLCAiaXNTdWJkb21haW4iOiBmYWxzZSwgImZlYXR1cmUi"
     "OiAiRnJvYnVsYXRlIiwgImV4cGlyeSI6IDE0NTg3NjYyNzd9";
+const uint8_t kSampleNonSubdomainTokenSignature[] = {
+    0xb7, 0x83, 0xf7, 0xbf, 0x43, 0xee, 0xd3, 0xb4, 0x96, 0xe4, 0x99,
+    0x4e, 0xbd, 0x7e, 0xff, 0xe2, 0x7a, 0x13, 0x44, 0x92, 0x8f, 0xf1,
+    0x84, 0x53, 0x22, 0xca, 0xe3, 0x5a, 0x35, 0x85, 0x71, 0x73, 0x5f,
+    0x0d, 0x51, 0xed, 0x9d, 0x61, 0x08, 0x31, 0xec, 0xd2, 0x05, 0xd6,
+    0x55, 0x2b, 0xb5, 0x96, 0xf1, 0xf9, 0xd9, 0x68, 0xa7, 0xbf, 0x2d,
+    0xfd, 0xb4, 0x76, 0xec, 0x53, 0x68, 0x09, 0x25, 0x06};
 
 const char* kExpectedFeatureName = "Frobulate";
 const char* kExpectedOrigin = "https://valid.example.com";
@@ -198,6 +219,15 @@
         expected_expiry_(base::Time::FromDoubleT(kExpectedExpiry)),
         valid_timestamp_(base::Time::FromDoubleT(kValidTimestamp)),
         invalid_timestamp_(base::Time::FromDoubleT(kInvalidTimestamp)),
+        expected_signature_(
+            std::string(reinterpret_cast<const char*>(kSampleTokenSignature),
+                        arraysize(kSampleTokenSignature))),
+        expected_subdomain_signature_(std::string(
+            reinterpret_cast<const char*>(kSampleSubdomainTokenSignature),
+            arraysize(kSampleSubdomainTokenSignature))),
+        expected_nonsubdomain_signature_(std::string(
+            reinterpret_cast<const char*>(kSampleNonSubdomainTokenSignature),
+            arraysize(kSampleNonSubdomainTokenSignature))),
         correct_public_key_(
             base::StringPiece(reinterpret_cast<const char*>(kTestPublicKey),
                               arraysize(kTestPublicKey))),
@@ -208,15 +238,18 @@
  protected:
   blink::WebOriginTrialTokenStatus Extract(const std::string& token_text,
                                            base::StringPiece public_key,
-                                           std::string* token_payload) {
-    return TrialToken::Extract(token_text, public_key, token_payload);
+                                           std::string* token_payload,
+                                           std::string* token_signature) {
+    return TrialToken::Extract(token_text, public_key, token_payload,
+                               token_signature);
   }
 
   blink::WebOriginTrialTokenStatus ExtractIgnorePayload(
       const std::string& token_text,
       base::StringPiece public_key) {
     std::string token_payload;
-    return Extract(token_text, public_key, &token_payload);
+    std::string token_signature;
+    return Extract(token_text, public_key, &token_payload, &token_signature);
   }
 
   std::unique_ptr<TrialToken> Parse(const std::string& token_payload) {
@@ -251,6 +284,10 @@
   const base::Time valid_timestamp_;
   const base::Time invalid_timestamp_;
 
+  std::string expected_signature_;
+  std::string expected_subdomain_signature_;
+  std::string expected_nonsubdomain_signature_;
+
  private:
   base::StringPiece correct_public_key_;
   base::StringPiece incorrect_public_key_;
@@ -264,26 +301,34 @@
 // token.
 TEST_F(TrialTokenTest, ValidateValidSignature) {
   std::string token_payload;
-  blink::WebOriginTrialTokenStatus status =
-      Extract(kSampleToken, correct_public_key(), &token_payload);
+  std::string token_signature;
+  blink::WebOriginTrialTokenStatus status = Extract(
+      kSampleToken, correct_public_key(), &token_payload, &token_signature);
   ASSERT_EQ(blink::WebOriginTrialTokenStatus::Success, status);
   EXPECT_STREQ(kSampleTokenJSON, token_payload.c_str());
+  EXPECT_EQ(expected_signature_, token_signature);
 }
 
 TEST_F(TrialTokenTest, ValidateSubdomainValidSignature) {
   std::string token_payload;
+  std::string token_signature;
   blink::WebOriginTrialTokenStatus status =
-      Extract(kSampleSubdomainToken, correct_public_key(), &token_payload);
+      Extract(kSampleSubdomainToken, correct_public_key(), &token_payload,
+              &token_signature);
   ASSERT_EQ(blink::WebOriginTrialTokenStatus::Success, status);
   EXPECT_STREQ(kSampleSubdomainTokenJSON, token_payload.c_str());
+  EXPECT_EQ(expected_subdomain_signature_, token_signature);
 }
 
 TEST_F(TrialTokenTest, ValidateNonSubdomainValidSignature) {
   std::string token_payload;
+  std::string token_signature;
   blink::WebOriginTrialTokenStatus status =
-      Extract(kSampleNonSubdomainToken, correct_public_key(), &token_payload);
+      Extract(kSampleNonSubdomainToken, correct_public_key(), &token_payload,
+              &token_signature);
   ASSERT_EQ(blink::WebOriginTrialTokenStatus::Success, status);
   EXPECT_STREQ(kSampleNonSubdomainTokenJSON, token_payload.c_str());
+  EXPECT_EQ(expected_nonsubdomain_signature_, token_signature);
 }
 
 TEST_F(TrialTokenTest, ValidateInvalidSignature) {
@@ -430,13 +475,15 @@
             token->IsValid(expected_origin_, invalid_timestamp_));
 }
 
-// Test overall extraction, to ensure output status matches returned token
+// Test overall extraction, to ensure output status matches returned token, and
+// signature is provided.
 TEST_F(TrialTokenTest, ExtractValidToken) {
   blink::WebOriginTrialTokenStatus status;
   std::unique_ptr<TrialToken> token =
       TrialToken::From(kSampleToken, correct_public_key(), &status);
   EXPECT_TRUE(token);
   EXPECT_EQ(blink::WebOriginTrialTokenStatus::Success, status);
+  EXPECT_EQ(expected_signature_, token->signature());
 }
 
 TEST_F(TrialTokenTest, ExtractInvalidSignature) {
diff --git a/content/common/origin_trials/trial_token_validator.cc b/content/common/origin_trials/trial_token_validator.cc
index 2cb1dd3d..1460fe4 100644
--- a/content/common/origin_trials/trial_token_validator.cc
+++ b/content/common/origin_trials/trial_token_validator.cc
@@ -47,6 +47,10 @@
   if (origin_trial_policy->IsFeatureDisabled(trial_token->feature_name()))
     return blink::WebOriginTrialTokenStatus::FeatureDisabled;
 
+  // TODO(chasej): Add a new status for disabled tokens
+  if (origin_trial_policy->IsTokenDisabled(trial_token->signature()))
+    return blink::WebOriginTrialTokenStatus::FeatureDisabled;
+
   *feature_name = trial_token->feature_name();
   return blink::WebOriginTrialTokenStatus::Success;
 }
diff --git a/content/common/origin_trials/trial_token_validator_unittest.cc b/content/common/origin_trials/trial_token_validator_unittest.cc
index cf196cc..a41f386 100644
--- a/content/common/origin_trials/trial_token_validator_unittest.cc
+++ b/content/common/origin_trials/trial_token_validator_unittest.cc
@@ -60,6 +60,13 @@
     "O4fM3Sa+MEd+5JcIgSZafw8AAABZeyJvcmlnaW4iOiAiaHR0cHM6Ly92YWxpZC5l"
     "eGFtcGxlLmNvbTo0NDMiLCAiZmVhdHVyZSI6ICJGcm9idWxhdGUiLCAiZXhwaXJ5"
     "IjogMjAwMDAwMDAwMH0=";
+const uint8_t kSampleTokenSignature[] = {
+    0xe4, 0x7f, 0xd6, 0x68, 0x3e, 0xff, 0x0e, 0x51, 0x38, 0xb3, 0x79,
+    0xe0, 0xe9, 0x36, 0xd2, 0xb0, 0x29, 0x2b, 0x7a, 0x29, 0x81, 0x1e,
+    0xd3, 0xab, 0xd6, 0x5f, 0xce, 0x10, 0x13, 0x42, 0x69, 0xc2, 0x6b,
+    0xe0, 0x6d, 0x3c, 0x0d, 0x51, 0x47, 0x0e, 0x0d, 0x8a, 0x07, 0xf7,
+    0xdf, 0xaa, 0xfe, 0x3b, 0x87, 0xcc, 0xdd, 0x26, 0xbe, 0x30, 0x47,
+    0x7e, 0xe4, 0x97, 0x08, 0x81, 0x26, 0x5a, 0x7f, 0x0f};
 
 // The token should be valid for this origin and for this feature.
 const char kAppropriateOrigin[] = "https://valid.example.com";
@@ -85,6 +92,13 @@
     "RrOtlAwa0gPqqn+A8GTD3AQAAABZeyJvcmlnaW4iOiAiaHR0cHM6Ly92YWxpZC5l"
     "eGFtcGxlLmNvbTo0NDMiLCAiZmVhdHVyZSI6ICJGcm9idWxhdGUiLCAiZXhwaXJ5"
     "IjogMTAwMDAwMDAwMH0=";
+const uint8_t kExpiredTokenSignature[] = {
+    0x61, 0xcf, 0x50, 0x85, 0xcc, 0x69, 0x77, 0xbd, 0x8d, 0x65, 0xbc,
+    0x90, 0x97, 0x83, 0x15, 0x7a, 0x25, 0x56, 0x34, 0xfd, 0xde, 0x9e,
+    0x17, 0x32, 0x72, 0xb8, 0xfa, 0x33, 0x18, 0x77, 0x6a, 0x63, 0xaa,
+    0xd1, 0x5c, 0x60, 0x1d, 0x5b, 0x52, 0x67, 0x43, 0xf0, 0xfb, 0xa7,
+    0x40, 0xa3, 0x3e, 0x46, 0xb3, 0xad, 0x94, 0x0c, 0x1a, 0xd2, 0x03,
+    0xea, 0xaa, 0x7f, 0x80, 0xf0, 0x64, 0xc3, 0xdc, 0x04};
 
 const char kUnparsableToken[] = "abcde";
 
@@ -119,10 +133,19 @@
   void DisableFeature(const std::string& feature) {
     disabled_features_.insert(feature);
   }
+  void DisableToken(const std::string& token) {
+    disabled_tokens_.insert(token);
+  }
+
+ protected:
+  bool IsTokenDisabled(base::StringPiece token_signature) const override {
+    return disabled_tokens_.count(token_signature.as_string()) > 0;
+  }
 
  private:
   const uint8_t* key_ = nullptr;
   std::set<std::string> disabled_features_;
+  std::set<std::string> disabled_tokens_;
 };
 
 class TestContentClient : public ContentClient {
@@ -138,6 +161,9 @@
   void DisableFeature(const std::string& feature) {
     origin_trial_policy_.DisableFeature(feature);
   }
+  void DisableToken(const std::string& token_signature) {
+    origin_trial_policy_.DisableToken(token_signature);
+  }
 
  private:
   TestOriginTrialPolicy origin_trial_policy_;
@@ -151,6 +177,12 @@
       : appropriate_origin_(GURL(kAppropriateOrigin)),
         inappropriate_origin_(GURL(kInappropriateOrigin)),
         insecure_origin_(GURL(kInsecureOrigin)),
+        valid_token_signature_(
+            std::string(reinterpret_cast<const char*>(kSampleTokenSignature),
+                        arraysize(kSampleTokenSignature))),
+        expired_token_signature_(
+            std::string(reinterpret_cast<const char*>(kExpiredTokenSignature),
+                        arraysize(kExpiredTokenSignature))),
         response_headers_(new net::HttpResponseHeaders("")) {
     SetPublicKey(kTestPublicKey);
     SetContentClient(&test_content_client_);
@@ -175,10 +207,17 @@
     test_content_client_.DisableFeature(feature);
   }
 
+  void DisableToken(const std::string& token_signature) {
+    test_content_client_.DisableToken(token_signature);
+  }
+
   const url::Origin appropriate_origin_;
   const url::Origin inappropriate_origin_;
   const url::Origin insecure_origin_;
 
+  std::string valid_token_signature_;
+  std::string expired_token_signature_;
+
   scoped_refptr<net::HttpResponseHeaders> response_headers_;
 
  private:
@@ -259,6 +298,22 @@
                                                appropriate_origin_, &feature));
 }
 
+TEST_F(TrialTokenValidatorTest, ValidatorRespectsDisabledTokens) {
+  std::string feature;
+  // Disable an irrelevant token; token should still validate
+  DisableToken(expired_token_signature_);
+  EXPECT_EQ(blink::WebOriginTrialTokenStatus::Success,
+            TrialTokenValidator::ValidateToken(kSampleToken,
+                                               appropriate_origin_, &feature));
+  EXPECT_EQ(kAppropriateFeatureName, feature);
+  // Disable the token; it should no longer be valid
+  DisableToken(valid_token_signature_);
+  // TODO(chasej): Add a new status for disabled tokens
+  EXPECT_EQ(blink::WebOriginTrialTokenStatus::FeatureDisabled,
+            TrialTokenValidator::ValidateToken(kSampleToken,
+                                               appropriate_origin_, &feature));
+}
+
 TEST_F(TrialTokenValidatorTest, ValidateRequestInsecure) {
   response_headers_->AddHeader(std::string("Origin-Trial: ") +
                                kInsecureOriginToken);
diff --git a/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java b/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java
index 13aa756..e948d064 100644
--- a/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java
+++ b/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java
@@ -32,6 +32,7 @@
 import org.chromium.content_public.browser.WebContentsObserver;
 import org.chromium.ui.OverscrollRefreshHandler;
 import org.chromium.ui.accessibility.AXTextStyle;
+import org.chromium.ui.base.WindowAndroid;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -148,6 +149,11 @@
     }
 
     @Override
+    public WindowAndroid getTopLevelNativeWindow() {
+        return nativeGetTopLevelNativeWindow(mNativeWebContentsAndroid);
+    }
+
+    @Override
     public void destroy() {
         if (!ThreadUtils.runningOnUiThread()) {
             throw new IllegalStateException("Attempting to destroy WebContents on non-UI thread");
@@ -557,6 +563,7 @@
 
     private static native WebContents nativeFromNativePtr(long webContentsAndroidPtr);
 
+    private native WindowAndroid nativeGetTopLevelNativeWindow(long nativeWebContentsAndroid);
     private native String nativeGetTitle(long nativeWebContentsAndroid);
     private native String nativeGetVisibleURL(long nativeWebContentsAndroid);
     private native boolean nativeIsLoading(long nativeWebContentsAndroid);
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/WebContents.java b/content/public/android/java/src/org/chromium/content_public/browser/WebContents.java
index 22d5e91..48e7450d 100644
--- a/content/public/android/java/src/org/chromium/content_public/browser/WebContents.java
+++ b/content/public/android/java/src/org/chromium/content_public/browser/WebContents.java
@@ -11,6 +11,7 @@
 
 import org.chromium.base.VisibleForTesting;
 import org.chromium.ui.OverscrollRefreshHandler;
+import org.chromium.ui.base.WindowAndroid;
 
 /**
  * The WebContents Java wrapper to allow communicating with the native WebContents object.
@@ -38,6 +39,11 @@
  */
 public interface WebContents extends Parcelable {
     /**
+     * @return The top level WindowAndroid associated with this WebContents.  This can be null.
+     */
+    WindowAndroid getTopLevelNativeWindow();
+
+    /**
      * Deletes the Web Contents object.
      */
     void destroy();
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ClipboardTest.java b/content/public/android/javatests/src/org/chromium/content/browser/ClipboardTest.java
index dfa50a29..47b53b6 100644
--- a/content/public/android/javatests/src/org/chromium/content/browser/ClipboardTest.java
+++ b/content/public/android/javatests/src/org/chromium/content/browser/ClipboardTest.java
@@ -16,6 +16,7 @@
 import org.chromium.content.browser.test.util.Criteria;
 import org.chromium.content.browser.test.util.CriteriaHelper;
 import org.chromium.content_public.browser.WebContents;
+import org.chromium.content_shell_apk.ContentShellActivityTestRule.RerunWithUpdatedContainerView;
 import org.chromium.content_shell_apk.ContentShellTestBase;
 
 /**
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ContentViewScrollingTest.java b/content/public/android/javatests/src/org/chromium/content/browser/ContentViewScrollingTest.java
index 4f77f08..3485bed 100644
--- a/content/public/android/javatests/src/org/chromium/content/browser/ContentViewScrollingTest.java
+++ b/content/public/android/javatests/src/org/chromium/content/browser/ContentViewScrollingTest.java
@@ -17,6 +17,7 @@
 import org.chromium.content.browser.ContentViewCore.InternalAccessDelegate;
 import org.chromium.content.browser.test.util.Criteria;
 import org.chromium.content.browser.test.util.CriteriaHelper;
+import org.chromium.content_shell_apk.ContentShellActivityTestRule.RerunWithUpdatedContainerView;
 import org.chromium.content_shell_apk.ContentShellTestBase;
 
 /**
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/input/SelectPopupTest.java b/content/public/android/javatests/src/org/chromium/content/browser/input/SelectPopupTest.java
index 380b99f..51529251 100644
--- a/content/public/android/javatests/src/org/chromium/content/browser/input/SelectPopupTest.java
+++ b/content/public/android/javatests/src/org/chromium/content/browser/input/SelectPopupTest.java
@@ -17,6 +17,7 @@
 import org.chromium.content.browser.test.util.DOMUtils;
 import org.chromium.content.browser.test.util.TestCallbackHelperContainer;
 import org.chromium.content.browser.test.util.TestCallbackHelperContainer.OnPageFinishedHelper;
+import org.chromium.content_shell_apk.ContentShellActivityTestRule.RerunWithUpdatedContainerView;
 import org.chromium.content_shell_apk.ContentShellTestBase;
 
 import java.util.concurrent.TimeUnit;
diff --git a/content/public/test/test_utils.cc b/content/public/test/test_utils.cc
index 4afe2321..1d2da32a 100644
--- a/content/public/test/test_utils.cc
+++ b/content/public/test/test_utils.cc
@@ -292,8 +292,8 @@
     return;
 
   running_ = true;
-  message_loop_runner_ = new MessageLoopRunner;
-  message_loop_runner_->Run();
+  run_loop_.reset(new base::RunLoop);
+  run_loop_->Run();
   EXPECT_TRUE(seen_);
 }
 
@@ -310,7 +310,7 @@
   if (!running_)
     return;
 
-  message_loop_runner_->Quit();
+  run_loop_->Quit();
   running_ = false;
 }
 
diff --git a/content/public/test/test_utils.h b/content/public/test/test_utils.h
index 29f5965..ed1f8e6 100644
--- a/content/public/test/test_utils.h
+++ b/content/public/test/test_utils.h
@@ -235,7 +235,7 @@
 
   NotificationSource source_;
   NotificationDetails details_;
-  scoped_refptr<MessageLoopRunner> message_loop_runner_;
+  std::unique_ptr<base::RunLoop> run_loop_;
 
   DISALLOW_COPY_AND_ASSIGN(WindowedNotificationObserver);
 };
diff --git a/content/renderer/gpu/render_widget_compositor.cc b/content/renderer/gpu/render_widget_compositor.cc
index ec1b8579..f1c6a7b5 100644
--- a/content/renderer/gpu/render_widget_compositor.cc
+++ b/content/renderer/gpu/render_widget_compositor.cc
@@ -1130,8 +1130,4 @@
   is_for_oopif_ = is_for_oopif;
 }
 
-void RenderWidgetCompositor::SetContentSourceId(uint32_t id) {
-  layer_tree_host_->SetContentSourceId(id);
-}
-
 }  // namespace content
diff --git a/content/renderer/gpu/render_widget_compositor.h b/content/renderer/gpu/render_widget_compositor.h
index 2367818..99cfc21 100644
--- a/content/renderer/gpu/render_widget_compositor.h
+++ b/content/renderer/gpu/render_widget_compositor.h
@@ -113,7 +113,6 @@
   void SetPaintedDeviceScaleFactor(float device_scale);
   void SetDeviceColorSpace(const gfx::ColorSpace& color_space);
   void SetIsForOopif(bool is_for_oopif);
-  void SetContentSourceId(uint32_t);
 
   // WebLayerTreeView implementation.
   cc::FrameSinkId getFrameSinkId() override;
diff --git a/content/renderer/media_recorder/video_track_recorder.cc b/content/renderer/media_recorder/video_track_recorder.cc
index d699e7e..d77d300 100644
--- a/content/renderer/media_recorder/video_track_recorder.cc
+++ b/content/renderer/media_recorder/video_track_recorder.cc
@@ -30,6 +30,10 @@
 #include "third_party/libyuv/include/libyuv.h"
 #include "ui/gfx/geometry/size.h"
 
+#if defined(OS_WIN)
+#include "base/win/windows_version.h"
+#endif
+
 #if BUILDFLAG(RTC_USE_H264)
 #include "third_party/openh264/src/codec/api/svc/codec_api.h"
 #include "third_party/openh264/src/codec/api/svc/codec_app_def.h"
@@ -117,6 +121,12 @@
   return;
 #endif
 
+#if defined(OS_WIN)
+  // See https://crbug.com/698441.
+  if (base::win::GetVersion() < base::win::VERSION_WIN10)
+    return;
+#endif
+
   content::RenderThreadImpl* const render_thread_impl =
       content::RenderThreadImpl::current();
   if (!render_thread_impl) {
diff --git a/content/renderer/mus/renderer_window_tree_client.cc b/content/renderer/mus/renderer_window_tree_client.cc
index 0e9f0b64..65fe281 100644
--- a/content/renderer/mus/renderer_window_tree_client.cc
+++ b/content/renderer/mus/renderer_window_tree_client.cc
@@ -114,7 +114,8 @@
 void RendererWindowTreeClient::OnWindowBoundsChanged(
     ui::Id window_id,
     const gfx::Rect& old_bounds,
-    const gfx::Rect& new_bounds) {}
+    const gfx::Rect& new_bounds,
+    const base::Optional<cc::LocalSurfaceId>& local_surface_id) {}
 
 void RendererWindowTreeClient::OnClientAreaChanged(
     uint32_t window_id,
diff --git a/content/renderer/mus/renderer_window_tree_client.h b/content/renderer/mus/renderer_window_tree_client.h
index 48fb20e..53cf3c8 100644
--- a/content/renderer/mus/renderer_window_tree_client.h
+++ b/content/renderer/mus/renderer_window_tree_client.h
@@ -74,9 +74,11 @@
                          ui::mojom::WindowDataPtr data,
                          int64_t display_id,
                          bool drawn) override;
-  void OnWindowBoundsChanged(ui::Id window_id,
-                             const gfx::Rect& old_bounds,
-                             const gfx::Rect& new_bounds) override;
+  void OnWindowBoundsChanged(
+      ui::Id window_id,
+      const gfx::Rect& old_bounds,
+      const gfx::Rect& new_bounds,
+      const base::Optional<cc::LocalSurfaceId>& local_frame_id) override;
   void OnClientAreaChanged(
       uint32_t window_id,
       const gfx::Insets& new_client_area,
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index db3193f..27feea5 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -2241,7 +2241,7 @@
     V8ValueConverterImpl converter;
     converter.SetDateAllowed(true);
     converter.SetRegExpAllowed(true);
-    std::unique_ptr<base::Value> value(new base::StringValue(params.data));
+    std::unique_ptr<base::Value> value(new base::Value(params.data));
     v8::Local<v8::Value> result_value = converter.ToV8Value(value.get(),
                                                              context);
     serialized_script_value = WebSerializedScriptValue::serialize(result_value);
@@ -3617,7 +3617,6 @@
   // For new page navigations, the browser process needs to be notified of the
   // first paint of that page, so it can cancel the timer that waits for it.
   if (is_main_frame_ && !navigation_state->WasWithinSamePage()) {
-    GetRenderWidget()->IncrementContentSourceId();
     render_view_->QueueMessage(
         new ViewHostMsg_DidFirstPaintAfterLoad(render_view_->routing_id_),
         MESSAGE_DELIVERY_POLICY_WITH_VISUAL_STATE);
@@ -4206,9 +4205,10 @@
   // TODO(mkwst): It would be cleaner to adjust blink::ResourceRequest to
   // initialize itself with a `nullptr` initiator so that this can be a simple
   // `isNull()` check. https://crbug.com/625969
+  WebDocument frame_document = frame->document();
   if (request.requestorOrigin().isUnique() &&
-      !frame->document().getSecurityOrigin().isUnique()) {
-    request.setRequestorOrigin(frame->document().getSecurityOrigin());
+      !frame_document.getSecurityOrigin().isUnique()) {
+    request.setRequestorOrigin(frame_document.getSecurityOrigin());
   }
 
   WebDataSource* provisional_data_source = frame->provisionalDataSource();
@@ -4321,7 +4321,7 @@
   extra_data->set_render_frame_id(routing_id_);
   extra_data->set_is_main_frame(!parent);
   extra_data->set_frame_origin(
-      url::Origin(frame->document().getSecurityOrigin()));
+      url::Origin(frame_document.getSecurityOrigin()));
   extra_data->set_parent_is_main_frame(parent && !parent->parent());
   extra_data->set_parent_render_frame_id(parent_routing_id);
   extra_data->set_allow_download(
@@ -4337,7 +4337,7 @@
       is_prefetch &&
       WebURLRequestToResourceType(request) != RESOURCE_TYPE_MAIN_FRAME);
   extra_data->set_initiated_in_secure_context(
-      frame->document().isSecureContext());
+      frame_document.isSecureContext());
 
   // Renderer process transfers apply only to navigational requests.
   bool is_navigational_request =
@@ -4859,20 +4859,21 @@
   params.socket_address.set_port(response.remotePort());
   params.was_within_same_page = navigation_state->WasWithinSamePage();
 
+  WebDocument frame_document = frame->document();
   // Set the origin of the frame.  This will be replicated to the corresponding
   // RenderFrameProxies in other processes.
-  params.origin = frame->document().getSecurityOrigin();
+  WebSecurityOrigin frame_origin = frame_document.getSecurityOrigin();
+  params.origin = frame_origin;
 
   params.insecure_request_policy = frame->getInsecureRequestPolicy();
 
   params.has_potentially_trustworthy_unique_origin =
-      frame->document().getSecurityOrigin().isUnique() &&
-      frame->document().getSecurityOrigin().isPotentiallyTrustworthy();
+      frame_origin.isUnique() && frame_origin.isPotentiallyTrustworthy();
 
   // Set the URL to be displayed in the browser UI to the user.
   params.url = GetLoadingUrl();
-  if (GURL(frame->document().baseURL()) != params.url)
-    params.base_url = frame->document().baseURL();
+  if (GURL(frame_document.baseURL()) != params.url)
+    params.base_url = frame_document.baseURL();
 
   GetRedirectChain(ds, &params.redirects);
   params.should_update_history =
@@ -4890,8 +4891,6 @@
   // corresponding FrameNavigationEntry.
   params.page_state = SingleHistoryItemToPageState(item);
 
-  params.content_source_id = GetRenderWidget()->GetContentSourceId();
-
   params.method = request.httpMethod().latin1();
   if (params.method == "POST")
     params.post_id = ExtractPostId(item);
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc
index 85a9fa91..09fd4bb6 100644
--- a/content/renderer/render_view_impl.cc
+++ b/content/renderer/render_view_impl.cc
@@ -1025,7 +1025,6 @@
   web_view->setIgnoreViewportTagScaleLimits(prefs.force_enable_zoom);
   settings->setAutoZoomFocusedNodeToLegibleScale(true);
   settings->setDoubleTapToZoomEnabled(prefs.double_tap_to_zoom_enabled);
-  settings->setMediaControlsOverlayPlayButtonEnabled(true);
   settings->setMediaPlaybackRequiresUserGesture(
       prefs.user_gesture_required_for_media_playback);
   settings->setMediaPlaybackGestureWhitelistScope(
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc
index 6a4442fa..f5f43f0 100644
--- a/content/renderer/render_widget.cc
+++ b/content/renderer/render_widget.cc
@@ -378,7 +378,6 @@
       focused_pepper_plugin_(nullptr),
       time_to_first_active_paint_recorded_(true),
       was_shown_time_(base::TimeTicks::Now()),
-      current_content_source_id_(0),
       weak_ptr_factory_(this) {
   DCHECK_NE(routing_id_, MSG_ROUTING_NONE);
   if (!swapped_out)
@@ -1287,7 +1286,6 @@
   compositor_->setViewportSize(physical_backing_size_);
   OnDeviceScaleFactorChanged();
   compositor_->SetDeviceColorSpace(screen_info_.icc_profile.GetColorSpace());
-  compositor_->SetContentSourceId(current_content_source_id_);
   // For background pages and certain tests, we don't want to trigger
   // CompositorFrameSink creation.
   if (compositor_never_visible_ || !RenderThreadImpl::current())
@@ -2302,15 +2300,6 @@
                                      possible_drag_event_info_));
 }
 
-uint32_t RenderWidget::GetContentSourceId() {
-  return current_content_source_id_;
-}
-
-void RenderWidget::IncrementContentSourceId() {
-  if (compositor_)
-    compositor_->SetContentSourceId(++current_content_source_id_);
-}
-
 blink::WebWidget* RenderWidget::GetWebWidget() const {
   return webwidget_internal_;
 }
diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h
index e43cd4d..e808bcc2 100644
--- a/content/renderer/render_widget.h
+++ b/content/renderer/render_widget.h
@@ -414,9 +414,6 @@
   virtual void TransferActiveWheelFlingAnimation(
       const blink::WebActiveWheelFlingParameters& params) {}
 
-  uint32_t GetContentSourceId();
-  void IncrementContentSourceId();
-
  protected:
   // Friend RefCounted so that the dtor can be non-public. Using this class
   // without ref-counting is an error.
@@ -850,19 +847,6 @@
   bool time_to_first_active_paint_recorded_;
   base::TimeTicks was_shown_time_;
 
-  // This is initialized to zero and is incremented on each non-same-page
-  // navigation commit by RenderFrameImpl. At that time it is sent to the
-  // compositor so that it can tag compositor frames, and RenderFrameImpl is
-  // responsible for sending it to the browser process to be used to match
-  // each compositor frame to the most recent page navigation before it was
-  // generated.
-  // This only applies to main frames, and is not touched for subframe
-  // RenderWidgets, where there is no concern around displaying unloaded
-  // content.
-  // TODO(kenrb, fsamuel): This should be removed when SurfaceIDs can be used
-  // to replace it. See https://crbug.com/695579.
-  uint32_t current_content_source_id_;
-
   base::WeakPtrFactory<RenderWidget> weak_ptr_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(RenderWidget);
diff --git a/content/shell/BUILD.gn b/content/shell/BUILD.gn
index d31f4685..53caa14 100644
--- a/content/shell/BUILD.gn
+++ b/content/shell/BUILD.gn
@@ -369,7 +369,7 @@
   }
 
   if (is_linux) {
-    deps += [ "//third_party/freetype-android:freetype" ]
+    deps += [ "//third_party/freetype" ]
   }
 
   if (!enable_plugins) {
diff --git a/content/shell/android/BUILD.gn b/content/shell/android/BUILD.gn
index 278ab5f..7831a5c 100644
--- a/content/shell/android/BUILD.gn
+++ b/content/shell/android/BUILD.gn
@@ -144,13 +144,17 @@
     "//content/public/android:content_java",
     "//content/public/test/android:content_java_test_support",
     "//content/shell/android:content_shell_java",
+    "//third_party/android_support_test_runner:rules_java",
     "//third_party/android_support_test_runner:runner_java",
+    "//third_party/junit:junit",
     "//ui/android:ui_java",
   ]
   java_files = [
     "javatests/src/org/chromium/content_shell_apk/ContentShellPreconditionsTest.java",
     "javatests/src/org/chromium/content_shell_apk/ContentShellShellManagementTest.java",
     "javatests/src/org/chromium/content_shell_apk/ContentShellTestBase.java",
+    "javatests/src/org/chromium/content_shell_apk/ContentShellTestCommon.java",
+    "javatests/src/org/chromium/content_shell_apk/ContentShellActivityTestRule.java",
     "javatests/src/org/chromium/content_shell_apk/ContentShellUrlTest.java",
   ]
 }
diff --git a/content/shell/android/javatests/AndroidManifest.xml b/content/shell/android/javatests/AndroidManifest.xml
index 1f0780d0..1a4f916 100644
--- a/content/shell/android/javatests/AndroidManifest.xml
+++ b/content/shell/android/javatests/AndroidManifest.xml
@@ -16,6 +16,11 @@
         <activity android:name="org.chromium.test.broker.OnDeviceInstrumentationBroker"
             android:exported="true"/>
     </application>
+
+    <instrumentation android:name="org.chromium.base.test.BaseChromiumAndroidJUnitRunner"
+        android:targetPackage="org.chromium.content_shell_apk"
+        chromium-junit4="true"
+        android:label="JUnit4-based tests for org.chromium.content_shell_apk" />
     <instrumentation android:name="org.chromium.base.test.BaseChromiumInstrumentationTestRunner"
         android:targetPackage="org.chromium.content_shell_apk"
         android:label="Tests for org.chromium.content_shell_apk"/>
diff --git a/content/shell/android/javatests/src/org/chromium/content_shell_apk/ContentShellActivityTestRule.java b/content/shell/android/javatests/src/org/chromium/content_shell_apk/ContentShellActivityTestRule.java
new file mode 100644
index 0000000..df1fcdf9b
--- /dev/null
+++ b/content/shell/android/javatests/src/org/chromium/content_shell_apk/ContentShellActivityTestRule.java
@@ -0,0 +1,184 @@
+// Copyright 2017 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.
+
+package org.chromium.content_shell_apk;
+
+import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout;
+
+import android.app.Instrumentation;
+import android.content.Intent;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.rule.ActivityTestRule;
+
+import org.junit.Assert;
+
+import org.chromium.base.test.util.CallbackHelper;
+import org.chromium.content.browser.ContentView;
+import org.chromium.content.browser.ContentViewCore;
+import org.chromium.content.browser.test.util.TestCallbackHelperContainer;
+import org.chromium.content_public.browser.LoadUrlParams;
+import org.chromium.content_public.browser.NavigationController;
+import org.chromium.content_public.browser.WebContents;
+import org.chromium.content_shell.Shell;
+import org.chromium.content_shell_apk.ContentShellTestCommon.TestCommonCallback;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.concurrent.ExecutionException;
+
+/**
+ * ActivityTestRule for ContentShellActivity.
+ *
+ * Test can use this ActivityTestRule to launch or get ContentShellActivity.
+ */
+public class ContentShellActivityTestRule extends ActivityTestRule<ContentShellActivity>
+        implements TestCommonCallback<ContentShellActivity> {
+    private final ContentShellTestCommon mDelegate;
+    private final boolean mLaunchActivity;
+
+    protected static final long WAIT_PAGE_LOADING_TIMEOUT_SECONDS = scaleTimeout(15);
+
+    public ContentShellActivityTestRule() {
+        this(false, false);
+    }
+
+    public ContentShellActivityTestRule(boolean initialTouchMode, boolean launchActivity) {
+        super(ContentShellActivity.class, initialTouchMode, launchActivity);
+        mLaunchActivity = launchActivity;
+        mDelegate = new ContentShellTestCommon(this);
+    }
+
+    @Override
+    public ContentShellActivity getActivityForTestCommon() {
+        return getActivity();
+    }
+
+    @Override
+    public Instrumentation getInstrumentationForTestCommon() {
+        return InstrumentationRegistry.getInstrumentation();
+    }
+
+    @Override
+    public ContentShellActivity launchActivityWithIntentForTestCommon(Intent t) {
+        return launchActivity(t);
+    }
+
+    @Override
+    public void runOnUiThreadForTestCommon(Runnable runnable) throws Throwable {
+        runOnUiThread(runnable);
+    }
+
+    @Override
+    protected void beforeActivityLaunched() {
+        mDelegate.assertScreenIsOn();
+    }
+
+    /**
+     * Starts the ContentShell activity and loads the given URL.
+     * The URL can be null, in which case will default to ContentShellActivity.DEFAULT_SHELL_URL.
+     */
+    public ContentShellActivity launchContentShellWithUrl(String url) {
+        Assert.assertFalse(mLaunchActivity);
+        return mDelegate.launchContentShellWithUrl(url);
+    }
+
+    /**
+     * Starts the content shell activity with the provided test url.
+     * The url is synchronously loaded.
+     * @param url Test url to load.
+     */
+    public void launchContentShellWithUrlSync(String url) {
+        Assert.assertFalse(mLaunchActivity);
+        mDelegate.launchContentShellWithUrlSync(url);
+    }
+
+    /**
+     * Returns the current ContentViewCore or null if there is no ContentView.
+     */
+    public ContentViewCore getContentViewCore() {
+        return mDelegate.getContentViewCore();
+    }
+
+    /**
+     * Returns the WebContents of this Shell.
+     */
+    public WebContents getWebContents() {
+        return mDelegate.getWebContents();
+    }
+
+    /**
+     * Waits for the Active shell to finish loading.  This times out after
+     * WAIT_FOR_ACTIVE_SHELL_LOADING_TIMEOUT milliseconds and it shouldn't be used for long
+     * loading pages. Instead it should be used more for test initialization. The proper way
+     * to wait is to use a TestCallbackHelperContainer after the initial load is completed.
+     */
+    public void waitForActiveShellToBeDoneLoading() {
+        mDelegate.waitForActiveShellToBeDoneLoading();
+    }
+
+    /**
+     * Creates a new {@link Shell} and waits for it to finish loading.
+     * @param url The URL to create the new {@link Shell} with.
+     * @return A new instance of a {@link Shell}.
+     * @throws ExecutionException
+     */
+    public Shell loadNewShell(String url) throws ExecutionException {
+        return mDelegate.loadNewShell(url);
+    }
+
+    /**
+     * Loads a URL in the specified content view.
+     *
+     * @param navigationController The navigation controller to load the URL in.
+     * @param callbackHelperContainer The callback helper container used to monitor progress.
+     * @param params The URL params to use.
+     */
+    public void loadUrl(NavigationController navigationController,
+            TestCallbackHelperContainer callbackHelperContainer, LoadUrlParams params)
+            throws Throwable {
+        mDelegate.loadUrl(navigationController, callbackHelperContainer, params);
+    }
+
+    /**
+     * Handles performing an action on the UI thread that will return when the specified callback
+     * is incremented.
+     *
+     * @param callbackHelper The callback helper that will be blocked on.
+     * @param action The action to be performed on the UI thread.
+     */
+    public void handleBlockingCallbackAction(CallbackHelper callbackHelper, Runnable action)
+            throws Throwable {
+        mDelegate.handleBlockingCallbackAction(callbackHelper, action);
+    }
+
+    // TODO(aelias): This method needs to be removed once http://crbug.com/179511 is fixed.
+    // Meanwhile, we have to wait if the page has the <meta viewport> tag.
+    /**
+     * Waits till the ContentViewCore receives the expected page scale factor
+     * from the compositor and asserts that this happens.
+     */
+    public void assertWaitForPageScaleFactorMatch(float expectedScale) {
+        mDelegate.assertWaitForPageScaleFactorMatch(expectedScale);
+    }
+
+    /**
+     * Replaces the {@link ContentViewCore#mContainerView} with a newly created
+     * {@link ContentView}.
+     */
+    public void replaceContainerView() throws Throwable {
+        mDelegate.replaceContainerView();
+    }
+
+    /**
+     * Annotation for tests that should be executed a second time after replacing
+     * the ContentViewCore's container view.
+     * <p>Please note that activity launch is only invoked once before both runs,
+     * and that any state changes produced by the first run are visible to the second run.
+     */
+    @Target(ElementType.METHOD)
+    @Retention(RetentionPolicy.RUNTIME)
+    public @interface RerunWithUpdatedContainerView {}
+}
diff --git a/content/shell/android/javatests/src/org/chromium/content_shell_apk/ContentShellPreconditionsTest.java b/content/shell/android/javatests/src/org/chromium/content_shell_apk/ContentShellPreconditionsTest.java
index 21495fc..ab3f798 100644
--- a/content/shell/android/javatests/src/org/chromium/content_shell_apk/ContentShellPreconditionsTest.java
+++ b/content/shell/android/javatests/src/org/chromium/content_shell_apk/ContentShellPreconditionsTest.java
@@ -1,4 +1,4 @@
-// Copyright 2012 The Chromium Authors. All rights reserved.
+// Copyright 2017 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.
 
@@ -8,26 +8,34 @@
 import android.content.Context;
 import android.os.Build;
 import android.os.PowerManager;
+import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.MediumTest;
 
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.chromium.base.test.BaseJUnit4ClassRunner;
 import org.chromium.base.test.util.Feature;
 
 /**
  * Test that verifies preconditions for tests to run.
  */
-public class ContentShellPreconditionsTest extends ContentShellTestBase {
+@RunWith(BaseJUnit4ClassRunner.class)
+public class ContentShellPreconditionsTest {
+    @Test
     @TargetApi(Build.VERSION_CODES.KITKAT_WATCH)
     @SuppressWarnings("deprecation")
     @MediumTest
     @Feature({"TestInfrastructure"})
     public void testScreenIsOn() throws Exception {
-        PowerManager pm = (PowerManager) getInstrumentation().getContext().getSystemService(
+        PowerManager pm = (PowerManager) InstrumentationRegistry.getContext().getSystemService(
                 Context.POWER_SERVICE);
 
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
-            assertTrue("Many tests will fail if the screen is not on.", pm.isInteractive());
+            Assert.assertTrue("Many tests will fail if the screen is not on.", pm.isInteractive());
         } else {
-            assertTrue("Many tests will fail if the screen is not on.", pm.isScreenOn());
+            Assert.assertTrue("Many tests will fail if the screen is not on.", pm.isScreenOn());
         }
     }
 }
diff --git a/content/shell/android/javatests/src/org/chromium/content_shell_apk/ContentShellShellManagementTest.java b/content/shell/android/javatests/src/org/chromium/content_shell_apk/ContentShellShellManagementTest.java
index f782574b..e5f81048 100644
--- a/content/shell/android/javatests/src/org/chromium/content_shell_apk/ContentShellShellManagementTest.java
+++ b/content/shell/android/javatests/src/org/chromium/content_shell_apk/ContentShellShellManagementTest.java
@@ -1,4 +1,4 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
+// Copyright 2017 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.
 
@@ -6,6 +6,12 @@
 
 import android.support.test.filters.SmallTest;
 
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.chromium.base.test.BaseJUnit4ClassRunner;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.base.test.util.UrlUtils;
@@ -16,31 +22,36 @@
 /**
  * Test suite to verify the behavior of the shell management logic.
  */
-public class ContentShellShellManagementTest extends ContentShellTestBase {
+@RunWith(BaseJUnit4ClassRunner.class)
+public class ContentShellShellManagementTest {
+    @Rule
+    public ContentShellActivityTestRule mActivityTestRule = new ContentShellActivityTestRule();
 
     private static final String TEST_PAGE_1 = UrlUtils.encodeHtmlDataUri(
             "<html><body style='background: red;'></body></html>");
     private static final String TEST_PAGE_2 = UrlUtils.encodeHtmlDataUri(
             "<html><body style='background: green;'></body></html>");
 
+    @Test
     @SmallTest
     @Feature({"Main"})
     @RetryOnFailure
     public void testMultipleShellsLaunched() throws InterruptedException, ExecutionException {
-        final ContentShellActivity activity = launchContentShellWithUrl(TEST_PAGE_1);
-        assertEquals(TEST_PAGE_1, activity.getActiveShell().getContentViewCore()
-                .getWebContents().getUrl());
+        final ContentShellActivity activity =
+                mActivityTestRule.launchContentShellWithUrl(TEST_PAGE_1);
+        Assert.assertEquals(TEST_PAGE_1,
+                activity.getActiveShell().getContentViewCore().getWebContents().getUrl());
 
         Shell previousActiveShell = activity.getActiveShell();
-        assertFalse(previousActiveShell.isDestroyed());
+        Assert.assertFalse(previousActiveShell.isDestroyed());
 
-        loadNewShell(TEST_PAGE_2);
-        assertEquals(TEST_PAGE_2, activity.getActiveShell().getContentViewCore()
-                .getWebContents().getUrl());
+        mActivityTestRule.loadNewShell(TEST_PAGE_2);
+        Assert.assertEquals(TEST_PAGE_2,
+                activity.getActiveShell().getContentViewCore().getWebContents().getUrl());
 
-        assertNotSame(previousActiveShell, activity.getActiveShell());
-        assertTrue(previousActiveShell.isDestroyed());
-        assertFalse(previousActiveShell.getContentViewCore().isAlive());
+        Assert.assertNotSame(previousActiveShell, activity.getActiveShell());
+        Assert.assertTrue(previousActiveShell.isDestroyed());
+        Assert.assertFalse(previousActiveShell.getContentViewCore().isAlive());
     }
 
 }
diff --git a/content/shell/android/javatests/src/org/chromium/content_shell_apk/ContentShellTestBase.java b/content/shell/android/javatests/src/org/chromium/content_shell_apk/ContentShellTestBase.java
index 3fa2a4d..8d1d7386 100644
--- a/content/shell/android/javatests/src/org/chromium/content_shell_apk/ContentShellTestBase.java
+++ b/content/shell/android/javatests/src/org/chromium/content_shell_apk/ContentShellTestBase.java
@@ -4,90 +4,80 @@
 
 package org.chromium.content_shell_apk;
 
-import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout;
-
-import android.annotation.TargetApi;
-import android.content.ComponentName;
-import android.content.Context;
+import android.app.Instrumentation;
 import android.content.Intent;
-import android.net.Uri;
-import android.os.Build;
-import android.os.PowerManager;
-import android.text.TextUtils;
-import android.view.ViewGroup;
 
-import org.chromium.base.ThreadUtils;
 import org.chromium.base.test.BaseActivityInstrumentationTestCase;
 import org.chromium.base.test.util.CallbackHelper;
 import org.chromium.base.test.util.CommandLineFlags;
-import org.chromium.base.test.util.UrlUtils;
 import org.chromium.content.browser.ContentView;
 import org.chromium.content.browser.ContentViewCore;
-import org.chromium.content.browser.test.util.Criteria;
-import org.chromium.content.browser.test.util.CriteriaHelper;
 import org.chromium.content.browser.test.util.TestCallbackHelperContainer;
 import org.chromium.content.common.ContentSwitches;
 import org.chromium.content_public.browser.LoadUrlParams;
 import org.chromium.content_public.browser.NavigationController;
 import org.chromium.content_public.browser.WebContents;
 import org.chromium.content_shell.Shell;
+import org.chromium.content_shell_apk.ContentShellActivityTestRule.RerunWithUpdatedContainerView;
+import org.chromium.content_shell_apk.ContentShellTestCommon.TestCommonCallback;
 
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
 import java.lang.reflect.AnnotatedElement;
-import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
 
 /**
  * Base test class for all ContentShell based tests.
  */
 @CommandLineFlags.Add(ContentSwitches.ENABLE_TEST_INTENTS)
-public class ContentShellTestBase
-        extends BaseActivityInstrumentationTestCase<ContentShellActivity> {
-    /** The maximum time the waitForActiveShellToBeDoneLoading method will wait. */
-    private static final long WAIT_FOR_ACTIVE_SHELL_LOADING_TIMEOUT = scaleTimeout(10000);
+public class ContentShellTestBase extends BaseActivityInstrumentationTestCase<ContentShellActivity>
+        implements TestCommonCallback<ContentShellActivity> {
+    protected static final long WAIT_PAGE_LOADING_TIMEOUT_SECONDS =
+            ContentShellTestCommon.WAIT_PAGE_LOADING_TIMEOUT_SECONDS;
 
-    protected static final long WAIT_PAGE_LOADING_TIMEOUT_SECONDS = scaleTimeout(15);
+    private ContentShellTestCommon mDelegate;
 
     public ContentShellTestBase() {
         super(ContentShellActivity.class);
+        mDelegate = new ContentShellTestCommon(this);
+    }
+
+    @SuppressWarnings("deprecation")
+    @Override
+    public ContentShellActivity getActivityForTestCommon() {
+        return getActivity();
     }
 
     @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        assertScreenIsOn();
+    @SuppressWarnings("deprecation")
+    public Instrumentation getInstrumentationForTestCommon() {
+        return getInstrumentation();
     }
 
-    @TargetApi(Build.VERSION_CODES.KITKAT_WATCH)
     @SuppressWarnings("deprecation")
-    private void assertScreenIsOn() {
-        PowerManager pm = (PowerManager) getInstrumentation().getContext().getSystemService(
-                Context.POWER_SERVICE);
+    @Override
+    public ContentShellActivity launchActivityWithIntentForTestCommon(Intent intent) {
+        setActivityIntent(intent);
+        return getActivity();
+    }
 
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
-            assertTrue("Many tests will fail if the screen is not on.", pm.isInteractive());
-        } else {
-            assertTrue("Many tests will fail if the screen is not on.", pm.isScreenOn());
-        }
+    @SuppressWarnings("deprecation")
+    @Override
+    public void runOnUiThreadForTestCommon(Runnable runnable) throws Throwable {
+        runTestOnUiThread(runnable);
+    }
+
+    @Override
+    @SuppressWarnings("deprecation")
+    protected void setUp() throws Exception {
+        super.setUp();
+        mDelegate.assertScreenIsOn();
     }
 
     /**
      * Starts the ContentShell activity and loads the given URL.
      * The URL can be null, in which case will default to ContentShellActivity.DEFAULT_SHELL_URL.
      */
-    protected ContentShellActivity launchContentShellWithUrl(String url) {
-        Intent intent = new Intent(Intent.ACTION_MAIN);
-        intent.addCategory(Intent.CATEGORY_LAUNCHER);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        if (url != null) intent.setData(Uri.parse(url));
-        intent.setComponent(new ComponentName(getInstrumentation().getTargetContext(),
-                ContentShellActivity.class));
-        setActivityIntent(intent);
-        return getActivity();
+    public ContentShellActivity launchContentShellWithUrl(String url) {
+        return mDelegate.launchContentShellWithUrl(url);
     }
 
     // TODO(cjhopman): These functions are inconsistent with launchContentShell***. Should be
@@ -98,26 +88,22 @@
      * The url is synchronously loaded.
      * @param url Test url to load.
      */
-    protected void startActivityWithTestUrl(String url) {
-        launchContentShellWithUrl(UrlUtils.getIsolatedTestFileUrl(url));
-        assertNotNull(getActivity());
-        waitForActiveShellToBeDoneLoading();
-        assertEquals(UrlUtils.getIsolatedTestFileUrl(url),
-                getContentViewCore().getWebContents().getUrl());
+    public void startActivityWithTestUrl(String url) {
+        mDelegate.launchContentShellWithUrlSync(url);
     }
 
     /**
      * Returns the current ContentViewCore or null if there is no ContentView.
      */
-    protected ContentViewCore getContentViewCore() {
-        return getActivity().getActiveShell().getContentViewCore();
+    public ContentViewCore getContentViewCore() {
+        return mDelegate.getContentViewCore();
     }
 
     /**
      * Returns the WebContents of this Shell.
      */
-    protected WebContents getWebContents() {
-        return getActivity().getActiveShell().getWebContents();
+    public WebContents getWebContents() {
+        return mDelegate.getWebContents();
     }
 
     /**
@@ -126,33 +112,8 @@
      * loading pages. Instead it should be used more for test initialization. The proper way
      * to wait is to use a TestCallbackHelperContainer after the initial load is completed.
      */
-    protected void waitForActiveShellToBeDoneLoading() {
-        final ContentShellActivity activity = getActivity();
-
-        // Wait for the Content Shell to be initialized.
-        CriteriaHelper.pollUiThread(new Criteria() {
-            @Override
-            public boolean isSatisfied() {
-                Shell shell = activity.getActiveShell();
-                // There are two cases here that need to be accounted for.
-                // The first is that we've just created a Shell and it isn't
-                // loading because it has no URL set yet.  The second is that
-                // we've set a URL and it actually is loading.
-                if (shell == null) {
-                    updateFailureReason("Shell is null.");
-                    return false;
-                }
-                if (shell.isLoading()) {
-                    updateFailureReason("Shell is still loading.");
-                    return false;
-                }
-                if (TextUtils.isEmpty(shell.getContentViewCore().getWebContents().getUrl())) {
-                    updateFailureReason("Shell's URL is empty or null.");
-                    return false;
-                }
-                return true;
-            }
-        }, WAIT_FOR_ACTIVE_SHELL_LOADING_TIMEOUT, CriteriaHelper.DEFAULT_POLLING_INTERVAL);
+    public void waitForActiveShellToBeDoneLoading() {
+        mDelegate.waitForActiveShellToBeDoneLoading();
     }
 
     /**
@@ -161,22 +122,10 @@
      * @return A new instance of a {@link Shell}.
      * @throws ExecutionException
      */
-    protected Shell loadNewShell(final String url) throws ExecutionException {
-        Shell shell = ThreadUtils.runOnUiThreadBlocking(new Callable<Shell>() {
-            @Override
-            public Shell call() {
-                getActivity().getShellManager().launchShell(url);
-                return getActivity().getActiveShell();
-            }
-        });
-
-        assertNotNull("Unable to create shell.", shell);
-        assertEquals("Active shell unexpected.", shell, getActivity().getActiveShell());
-
-        waitForActiveShellToBeDoneLoading();
-
-        return shell;
+    public Shell loadNewShell(String url) throws ExecutionException {
+        return mDelegate.loadNewShell(url);
     }
+
     /**
      * Loads a URL in the specified content view.
      *
@@ -184,18 +133,10 @@
      * @param callbackHelperContainer The callback helper container used to monitor progress.
      * @param params The URL params to use.
      */
-    protected void loadUrl(
-            final NavigationController navigationController,
-            TestCallbackHelperContainer callbackHelperContainer,
-            final LoadUrlParams params) throws Throwable {
-        handleBlockingCallbackAction(
-                callbackHelperContainer.getOnPageFinishedHelper(),
-                new Runnable() {
-                    @Override
-                    public void run() {
-                        navigationController.loadUrl(params);
-                    }
-                });
+    public void loadUrl(NavigationController navigationController,
+            TestCallbackHelperContainer callbackHelperContainer, LoadUrlParams params)
+            throws Throwable {
+        mDelegate.loadUrl(navigationController, callbackHelperContainer, params);
     }
 
     /**
@@ -205,12 +146,9 @@
      * @param callbackHelper The callback helper that will be blocked on.
      * @param action The action to be performed on the UI thread.
      */
-    protected void handleBlockingCallbackAction(
-            CallbackHelper callbackHelper, Runnable action) throws Throwable {
-        int currentCallCount = callbackHelper.getCallCount();
-        runTestOnUiThread(action);
-        callbackHelper.waitForCallback(
-                currentCallCount, 1, WAIT_PAGE_LOADING_TIMEOUT_SECONDS, TimeUnit.SECONDS);
+    public void handleBlockingCallbackAction(CallbackHelper callbackHelper, Runnable action)
+            throws Throwable {
+        mDelegate.handleBlockingCallbackAction(callbackHelper, action);
     }
 
     // TODO(aelias): This method needs to be removed once http://crbug.com/179511 is fixed.
@@ -219,14 +157,8 @@
      * Waits till the ContentViewCore receives the expected page scale factor
      * from the compositor and asserts that this happens.
      */
-    protected void assertWaitForPageScaleFactorMatch(float expectedScale) {
-        CriteriaHelper.pollInstrumentationThread(
-                Criteria.equals(expectedScale, new Callable<Float>() {
-                    @Override
-                    public Float call() {
-                        return getContentViewCore().getScale();
-                    }
-                }));
+    public void assertWaitForPageScaleFactorMatch(float expectedScale) {
+        mDelegate.assertWaitForPageScaleFactorMatch(expectedScale);
     }
 
     /**
@@ -234,19 +166,11 @@
      * {@link ContentView}.
      */
     @SuppressWarnings("javadoc")
-    protected void replaceContainerView() throws Throwable {
-        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
-                @Override
-            public void run() {
-                ContentView cv = ContentView.createContentView(getActivity(), getContentViewCore());
-                ((ViewGroup) getContentViewCore().getContainerView().getParent()).addView(cv);
-                getContentViewCore().setContainerView(cv);
-                getContentViewCore().setContainerViewInternals(cv);
-                cv.requestFocus();
-            }
-        });
+    public void replaceContainerView() throws Throwable {
+        mDelegate.replaceContainerView();
     }
 
+    @SuppressWarnings("deprecation")
     @Override
     protected void runTest() throws Throwable {
         super.runTest();
@@ -261,16 +185,4 @@
                     + " See ContentShellTestBase#runTest.", e);
         }
     }
-
-    /**
-     * Annotation for tests that should be executed a second time after replacing
-     * the ContentViewCore's container view (see {@link #runTest()}).
-     *
-     * <p>Please note that {@link #setUp()} is only invoked once before both runs,
-     * and that any state changes produced by the first run are visible to the second run.
-     */
-    @Target(ElementType.METHOD)
-    @Retention(RetentionPolicy.RUNTIME)
-    public @interface RerunWithUpdatedContainerView {
-    }
 }
diff --git a/content/shell/android/javatests/src/org/chromium/content_shell_apk/ContentShellTestCommon.java b/content/shell/android/javatests/src/org/chromium/content_shell_apk/ContentShellTestCommon.java
new file mode 100644
index 0000000..263723f
--- /dev/null
+++ b/content/shell/android/javatests/src/org/chromium/content_shell_apk/ContentShellTestCommon.java
@@ -0,0 +1,195 @@
+// Copyright 2017 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.
+
+package org.chromium.content_shell_apk;
+
+import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout;
+
+import android.annotation.TargetApi;
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Build;
+import android.os.PowerManager;
+import android.text.TextUtils;
+import android.view.ViewGroup;
+
+import org.junit.Assert;
+
+import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.CallbackHelper;
+import org.chromium.base.test.util.UrlUtils;
+import org.chromium.content.browser.ContentView;
+import org.chromium.content.browser.ContentViewCore;
+import org.chromium.content.browser.test.util.Criteria;
+import org.chromium.content.browser.test.util.CriteriaHelper;
+import org.chromium.content.browser.test.util.TestCallbackHelperContainer;
+import org.chromium.content_public.browser.LoadUrlParams;
+import org.chromium.content_public.browser.NavigationController;
+import org.chromium.content_public.browser.WebContents;
+import org.chromium.content_shell.Shell;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Implementation of utility methods for ContentShellTestBase and ContentShellActivityTestRule to
+ * wrap around during instrumentation test JUnit3 to JUnit4 migration
+ *
+ * Please do not use this class' methods in places other than {@link ContentShellTestBase}
+ * and {@link ContentShellActivityTestRule}
+ */
+public final class ContentShellTestCommon {
+    /** The maximum time the waitForActiveShellToBeDoneLoading method will wait. */
+    private static final long WAIT_FOR_ACTIVE_SHELL_LOADING_TIMEOUT = scaleTimeout(10000);
+    static final long WAIT_PAGE_LOADING_TIMEOUT_SECONDS = scaleTimeout(15);
+
+    private final TestCommonCallback<ContentShellActivity> mCallback;
+
+    ContentShellTestCommon(TestCommonCallback<ContentShellActivity> callback) {
+        mCallback = callback;
+    }
+
+    @TargetApi(Build.VERSION_CODES.KITKAT_WATCH)
+    @SuppressWarnings("deprecation")
+    void assertScreenIsOn() {
+        PowerManager pm = (PowerManager) mCallback.getInstrumentationForTestCommon()
+                                  .getContext()
+                                  .getSystemService(Context.POWER_SERVICE);
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
+            Assert.assertTrue("Many tests will fail if the screen is not on.", pm.isInteractive());
+        } else {
+            Assert.assertTrue("Many tests will fail if the screen is not on.", pm.isScreenOn());
+        }
+    }
+
+    ContentShellActivity launchContentShellWithUrl(String url) {
+        Intent intent = new Intent(Intent.ACTION_MAIN);
+        intent.addCategory(Intent.CATEGORY_LAUNCHER);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        if (url != null) intent.setData(Uri.parse(url));
+        intent.setComponent(
+                new ComponentName(mCallback.getInstrumentationForTestCommon().getTargetContext(),
+                        ContentShellActivity.class));
+        return mCallback.launchActivityWithIntentForTestCommon(intent);
+    }
+
+    // TODO(yolandyan): This should use the url exactly without the getIsolatedTestFileUrl call.
+    void launchContentShellWithUrlSync(String url) {
+        String isolatedTestFileUrl = UrlUtils.getIsolatedTestFileUrl(url);
+        launchContentShellWithUrl(isolatedTestFileUrl);
+        Assert.assertNotNull(mCallback.getActivityForTestCommon());
+        waitForActiveShellToBeDoneLoading();
+        Assert.assertEquals(isolatedTestFileUrl, getContentViewCore().getWebContents().getUrl());
+    }
+
+    void waitForActiveShellToBeDoneLoading() {
+        // Wait for the Content Shell to be initialized.
+        CriteriaHelper.pollUiThread(new Criteria() {
+            @Override
+            public boolean isSatisfied() {
+                Shell shell = mCallback.getActivityForTestCommon().getActiveShell();
+                // There are two cases here that need to be accounted for.
+                // The first is that we've just created a Shell and it isn't
+                // loading because it has no URL set yet.  The second is that
+                // we've set a URL and it actually is loading.
+                if (shell == null) {
+                    updateFailureReason("Shell is null.");
+                    return false;
+                }
+                if (shell.isLoading()) {
+                    updateFailureReason("Shell is still loading.");
+                    return false;
+                }
+                if (TextUtils.isEmpty(shell.getContentViewCore().getWebContents().getUrl())) {
+                    updateFailureReason("Shell's URL is empty or null.");
+                    return false;
+                }
+                return true;
+            }
+        }, WAIT_FOR_ACTIVE_SHELL_LOADING_TIMEOUT, CriteriaHelper.DEFAULT_POLLING_INTERVAL);
+    }
+
+    ContentViewCore getContentViewCore() {
+        return mCallback.getActivityForTestCommon().getActiveShell().getContentViewCore();
+    }
+
+    WebContents getWebContents() {
+        return mCallback.getActivityForTestCommon().getActiveShell().getWebContents();
+    }
+
+    void loadUrl(final NavigationController navigationController,
+            TestCallbackHelperContainer callbackHelperContainer, final LoadUrlParams params)
+            throws Throwable {
+        handleBlockingCallbackAction(
+                callbackHelperContainer.getOnPageFinishedHelper(), new Runnable() {
+                    @Override
+                    public void run() {
+                        navigationController.loadUrl(params);
+                    }
+                });
+    }
+
+    Shell loadNewShell(final String url) throws ExecutionException {
+        Shell shell = ThreadUtils.runOnUiThreadBlocking(new Callable<Shell>() {
+            @Override
+            public Shell call() {
+                mCallback.getActivityForTestCommon().getShellManager().launchShell(url);
+                return mCallback.getActivityForTestCommon().getActiveShell();
+            }
+        });
+        Assert.assertNotNull("Unable to create shell.", shell);
+        Assert.assertEquals("Active shell unexpected.", shell,
+                mCallback.getActivityForTestCommon().getActiveShell());
+        waitForActiveShellToBeDoneLoading();
+        return shell;
+    }
+
+    void handleBlockingCallbackAction(CallbackHelper callbackHelper, Runnable uiThreadAction)
+            throws Throwable {
+        int currentCallCount = callbackHelper.getCallCount();
+        mCallback.runOnUiThreadForTestCommon(uiThreadAction);
+        callbackHelper.waitForCallback(
+                currentCallCount, 1, WAIT_PAGE_LOADING_TIMEOUT_SECONDS, TimeUnit.SECONDS);
+    }
+
+    void assertWaitForPageScaleFactorMatch(float expectedScale) {
+        CriteriaHelper.pollInstrumentationThread(
+                Criteria.equals(expectedScale, new Callable<Float>() {
+                    @Override
+                    public Float call() {
+                        return getContentViewCore().getScale();
+                    }
+                }));
+    }
+
+    void replaceContainerView() throws Throwable {
+        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
+            @Override
+            public void run() {
+                ContentView cv = ContentView.createContentView(
+                        mCallback.getActivityForTestCommon(), getContentViewCore());
+                ((ViewGroup) getContentViewCore().getContainerView().getParent()).addView(cv);
+                getContentViewCore().setContainerView(cv);
+                getContentViewCore().setContainerViewInternals(cv);
+                cv.requestFocus();
+            }
+        });
+    }
+
+    /**
+     * Interface used by TestRule and TestBase class to implement methods for TestCommonCallback
+     * class to use.
+     */
+    public static interface TestCommonCallback<T extends Activity> {
+        Instrumentation getInstrumentationForTestCommon();
+        T launchActivityWithIntentForTestCommon(Intent t);
+        T getActivityForTestCommon();
+        void runOnUiThreadForTestCommon(Runnable runnable) throws Throwable;
+    }
+}
diff --git a/content/shell/browser/layout_test/layout_test_devtools_frontend.cc b/content/shell/browser/layout_test/layout_test_devtools_frontend.cc
index 917a8764..ac62b4a 100644
--- a/content/shell/browser/layout_test/layout_test_devtools_frontend.cc
+++ b/content/shell/browser/layout_test/layout_test_devtools_frontend.cc
@@ -102,7 +102,7 @@
   }
 
   std::string encoded_script;
-  base::JSONWriter::Write(base::StringValue(script), &encoded_script);
+  base::JSONWriter::Write(base::Value(script), &encoded_script);
   std::string source =
       base::StringPrintf("DevToolsAPI.evaluateForTestInFrontend(%d, %s);",
                          call_id,
diff --git a/content/shell/browser/shell_devtools_frontend.cc b/content/shell/browser/shell_devtools_frontend.cc
index 74ac05da..0bab673f 100644
--- a/content/shell/browser/shell_devtools_frontend.cc
+++ b/content/shell/browser/shell_devtools_frontend.cc
@@ -80,7 +80,7 @@
     return num_bytes;
 
   base::Value* id = new base::Value(stream_id_);
-  base::StringValue* chunkValue = new base::StringValue(chunk);
+  base::Value* chunkValue = new base::Value(chunk);
 
   content::BrowserThread::PostTask(
       content::BrowserThread::UI, FROM_HERE,
diff --git a/content/shell/test_runner/mock_web_speech_recognizer.cc b/content/shell/test_runner/mock_web_speech_recognizer.cc
index 56c35ae..29ca528b 100644
--- a/content/shell/test_runner/mock_web_speech_recognizer.cc
+++ b/content/shell/test_runner/mock_web_speech_recognizer.cc
@@ -160,7 +160,7 @@
       weak_factory_(this) {}
 
 MockWebSpeechRecognizer::~MockWebSpeechRecognizer() {
-  ClearTaskQueue();
+  SetDelegate(nullptr);
 }
 
 bool MockWebSpeechRecognizer::Task::isNewContextTask() const {
@@ -169,6 +169,9 @@
 
 void MockWebSpeechRecognizer::SetDelegate(WebTestDelegate* delegate) {
   delegate_ = delegate;
+  // No delegate to forward to, clear out pending tasks.
+  if (!delegate_)
+    ClearTaskQueue();
 }
 
 void MockWebSpeechRecognizer::SetClientContext(
diff --git a/content/shell/test_runner/tracked_dictionary.cc b/content/shell/test_runner/tracked_dictionary.cc
index eaeba5fe..87550a91 100644
--- a/content/shell/test_runner/tracked_dictionary.cc
+++ b/content/shell/test_runner/tracked_dictionary.cc
@@ -45,7 +45,7 @@
 
 void TrackedDictionary::SetString(const std::string& path,
                                   const std::string& new_value) {
-  Set(path, base::MakeUnique<base::StringValue>(new_value));
+  Set(path, base::MakeUnique<base::Value>(new_value));
 }
 
 }  // namespace test_runner
diff --git a/content/shell/test_runner/web_view_test_proxy.cc b/content/shell/test_runner/web_view_test_proxy.cc
index 1404003..3fdc4561 100644
--- a/content/shell/test_runner/web_view_test_proxy.cc
+++ b/content/shell/test_runner/web_view_test_proxy.cc
@@ -32,6 +32,8 @@
 
 WebViewTestProxyBase::~WebViewTestProxyBase() {
   test_interfaces_->WindowClosed(this);
+  if (test_interfaces_->GetDelegate() == delegate_)
+    test_interfaces_->SetDelegate(nullptr);
 }
 
 void WebViewTestProxyBase::SetInterfaces(WebTestInterfaces* interfaces) {
diff --git a/content/test/gpu/generate_buildbot_json.py b/content/test/gpu/generate_buildbot_json.py
index 4d9adf88..81a77fe 100755
--- a/content/test/gpu/generate_buildbot_json.py
+++ b/content/test/gpu/generate_buildbot_json.py
@@ -601,6 +601,7 @@
       'build_config': 'Release',
       'swarming': True,
       'os_type': 'linux',
+      'instrumentation_type': 'tsan',
     },
     'Android Release (Nexus 5)': {
       'swarming_dimensions': [
@@ -689,6 +690,21 @@
       'swarming': False,
       'os_type': 'android',
     },
+    'Android Release (NVIDIA Shield)': {
+      'swarming_dimensions': [
+        {
+          # There are no PCI IDs on Android.
+          # This is a hack to get the script working.
+          'gpu': '0000:0000',
+          'os': 'Android'
+        },
+      ],
+      'build_config': 'android-chromium',
+      # This bot is a one-off and doesn't have similar slaves in the
+      # swarming pool.
+      'swarming': False,
+      'os_type': 'android',
+    },
 
     # The following "optional" testers don't actually exist on the
     # waterfall. They are present here merely to specify additional
@@ -1323,6 +1339,7 @@
     'tester_configs': [
       {
         'build_configs': ['Release', 'Release_x64'],
+        'disabled_instrumentation_types': ['tsan'],
       }
     ],
     # Don't run these tests on Android.
@@ -1384,6 +1401,7 @@
     'tester_configs': [
       {
         'predicate': Predicates.DEFAULT_PLUS_V8,
+        'disabled_instrumentation_types': ['tsan'],
       },
     ]
   },
@@ -1391,6 +1409,7 @@
     'tester_configs': [
       {
         'predicate': Predicates.DEFAULT_PLUS_V8,
+        'disabled_instrumentation_types': ['tsan'],
       },
     ]
   },
@@ -1399,6 +1418,7 @@
     'tester_configs': [
       {
         'predicate': Predicates.DEFAULT_PLUS_V8,
+        'disabled_instrumentation_types': ['tsan'],
       }
     ],
   },
@@ -1406,6 +1426,7 @@
     'tester_configs': [
       {
         'predicate': Predicates.DEFAULT_PLUS_V8,
+        'disabled_instrumentation_types': ['tsan'],
       },
     ],
   },
@@ -1422,6 +1443,7 @@
     'tester_configs': [
       {
         'predicate': Predicates.DEFAULT_PLUS_V8,
+        'disabled_instrumentation_types': ['tsan'],
       },
     ],
   },
@@ -1446,6 +1468,7 @@
     'tester_configs': [
       {
         'predicate': Predicates.DEFAULT_PLUS_V8,
+        'disabled_instrumentation_types': ['tsan'],
       },
     ],
   },
@@ -1453,6 +1476,7 @@
     'tester_configs': [
       {
         'predicate': Predicates.DEFAULT_PLUS_V8,
+        'disabled_instrumentation_types': ['tsan'],
       },
     ],
   },
@@ -1460,6 +1484,7 @@
     'tester_configs': [
       {
         'predicate': Predicates.DEFAULT_PLUS_V8,
+        'disabled_instrumentation_types': ['tsan'],
       },
     ],
   },
@@ -1467,6 +1492,7 @@
     'tester_configs': [
       {
         'predicate': Predicates.DEFAULT_PLUS_V8,
+        'disabled_instrumentation_types': ['tsan'],
       },
     ],
     'asan_args': ['--is-asan'],
@@ -1533,6 +1559,7 @@
         # Run this on the FYI waterfall and optional tryservers.
         'predicate': Predicates.FYI_AND_OPTIONAL,
         'os_types': ['linux'],
+        'disabled_instrumentation_types': ['tsan'],
       }
     ],
     'target_name': 'webgl_conformance',
@@ -1569,6 +1596,7 @@
          # the Debug bots, which is too long.
         'build_configs': ['Release', 'Release_x64'],
         'predicate': Predicates.FYI_OPTIONAL_AND_V8,
+        'disabled_instrumentation_types': ['tsan'],
       },
     ],
     'disabled_tester_configs': [
@@ -1620,6 +1648,7 @@
             'os': 'Ubuntu'
           },
         ],
+        'disabled_instrumentation_types': ['tsan'],
       },
     ],
     'target_name': 'webgl_conformance',
@@ -1751,6 +1780,11 @@
   if 'os_types' in tc:
     if not tester_config['os_type'] in tc['os_types']:
       return False
+  if 'instrumentation_type' in tester_config:
+    if 'disabled_instrumentation_types' in tc:
+      if tester_config['instrumentation_type'] in \
+            tc['disabled_instrumentation_types']:
+        return False
   if 'build_configs' in tc:
     if not tester_config['build_config'] in tc['build_configs']:
       return False
diff --git a/content/test/test_render_view_host.h b/content/test/test_render_view_host.h
index 6a9a4f58..252a22d 100644
--- a/content/test/test_render_view_host.h
+++ b/content/test/test_render_view_host.h
@@ -111,7 +111,6 @@
   bool is_showing() const { return is_showing_; }
   bool is_occluded() const { return is_occluded_; }
   bool did_swap_compositor_frame() const { return did_swap_compositor_frame_; }
-  void reset_did_swap_compositor_frame() { did_swap_compositor_frame_ = false; }
 
  protected:
   RenderWidgetHostImpl* rwh_;
diff --git a/dbus/values_util.cc b/dbus/values_util.cc
index 58b2b9e..1e035c9 100644
--- a/dbus/values_util.cc
+++ b/dbus/values_util.cc
@@ -159,13 +159,13 @@
     case Message::STRING: {
       std::string value;
       if (reader->PopString(&value))
-        result = base::MakeUnique<base::StringValue>(value);
+        result = base::MakeUnique<base::Value>(value);
       break;
     }
     case Message::OBJECT_PATH: {
       ObjectPath value;
       if (reader->PopObjectPath(&value))
-        result = base::MakeUnique<base::StringValue>(value.value());
+        result = base::MakeUnique<base::Value>(value.value());
       break;
     }
     case Message::UNIX_FD: {
diff --git a/dbus/values_util_unittest.cc b/dbus/values_util_unittest.cc
index 38d94f8..13c496b 100644
--- a/dbus/values_util_unittest.cc
+++ b/dbus/values_util_unittest.cc
@@ -100,17 +100,17 @@
   // Pop a string.
   value = PopDataAsValue(&reader);
   ASSERT_TRUE(value.get() != NULL);
-  expected_value.reset(new base::StringValue(kStringValue));
+  expected_value.reset(new base::Value(kStringValue));
   EXPECT_TRUE(value->Equals(expected_value.get()));
   // Pop an empty string.
   value = PopDataAsValue(&reader);
   ASSERT_TRUE(value.get() != NULL);
-  expected_value.reset(new base::StringValue(kEmptyStringValue));
+  expected_value.reset(new base::Value(kEmptyStringValue));
   EXPECT_TRUE(value->Equals(expected_value.get()));
   // Pop an object path.
   value = PopDataAsValue(&reader);
   ASSERT_TRUE(value.get() != NULL);
-  expected_value.reset(new base::StringValue(kObjectPathValue.value()));
+  expected_value.reset(new base::Value(kObjectPathValue.value()));
   EXPECT_TRUE(value->Equals(expected_value.get()));
 }
 
@@ -148,7 +148,7 @@
   // Pop a string.
   value = PopDataAsValue(&reader);
   ASSERT_TRUE(value.get() != NULL);
-  expected_value.reset(new base::StringValue(kStringValue));
+  expected_value.reset(new base::Value(kStringValue));
   EXPECT_TRUE(value->Equals(expected_value.get()));
 }
 
@@ -391,7 +391,7 @@
   const base::Value kBoolValue(false);
   const base::Value kIntegerValue(42);
   const base::Value kDoubleValue(4.2);
-  const base::StringValue kStringValue("string");
+  const base::Value kStringValue("string");
 
   std::unique_ptr<Response> response(Response::CreateEmpty());
   MessageWriter writer(response.get());
@@ -420,7 +420,7 @@
   const base::Value kBoolValue(false);
   const base::Value kIntegerValue(42);
   const base::Value kDoubleValue(4.2);
-  const base::StringValue kStringValue("string");
+  const base::Value kStringValue("string");
 
   std::unique_ptr<Response> response(Response::CreateEmpty());
   MessageWriter writer(response.get());
@@ -449,7 +449,7 @@
   const base::Value kBoolValue(false);
   const base::Value kIntegerValue(42);
   const base::Value kDoubleValue(4.2);
-  const base::StringValue kStringValue("string");
+  const base::Value kStringValue("string");
 
   std::unique_ptr<Response> response(Response::CreateEmpty());
   MessageWriter writer(response.get());
@@ -478,7 +478,7 @@
   const base::Value kBoolValue(false);
   const base::Value kIntegerValue(42);
   const base::Value kDoubleValue(4.2);
-  const base::StringValue kStringValue("string");
+  const base::Value kStringValue("string");
 
   std::unique_ptr<Response> response(Response::CreateEmpty());
   MessageWriter writer(response.get());
diff --git a/device/bluetooth/bluetooth_discovery_session.cc b/device/bluetooth/bluetooth_discovery_session.cc
index 8ae5b10..faf158cd 100644
--- a/device/bluetooth/bluetooth_discovery_session.cc
+++ b/device/bluetooth/bluetooth_discovery_session.cc
@@ -99,7 +99,7 @@
     std::unique_ptr<BluetoothDiscoveryFilter> discovery_filter,
     const base::Closure& callback,
     const ErrorCallback& error_callback) {
-  discovery_filter_.reset(discovery_filter.release());
+  discovery_filter_ = std::move(discovery_filter);
   // BluetoothDiscoverySession::SetDiscoveryFilter is only used from a private
   // extension API, so we don't bother histogramming its failures.
   adapter_->SetDiscoveryFilter(
diff --git a/device/bluetooth/bluez/bluetooth_adapter_bluez.cc b/device/bluetooth/bluez/bluetooth_adapter_bluez.cc
index f5f34339..77ec31bf 100644
--- a/device/bluetooth/bluez/bluetooth_adapter_bluez.cc
+++ b/device/bluetooth/bluez/bluetooth_adapter_bluez.cc
@@ -1459,7 +1459,7 @@
     return;
   }
 
-  current_filter_.reset(discovery_filter.release());
+  current_filter_ = std::move(discovery_filter);
 
   bluez::BluetoothAdapterClient::DiscoveryFilter dbus_discovery_filter;
 
diff --git a/device/bluetooth/bluez/bluetooth_service_attribute_value_bluez_unittest.cc b/device/bluetooth/bluez/bluetooth_service_attribute_value_bluez_unittest.cc
index d9d8d02..ba66a4b2 100644
--- a/device/bluetooth/bluez/bluetooth_service_attribute_value_bluez_unittest.cc
+++ b/device/bluetooth/bluez/bluetooth_service_attribute_value_bluez_unittest.cc
@@ -48,7 +48,7 @@
 
 TEST(BluetoothServiceAttributeBlueZTest, BasicValue) {
   BluetoothServiceAttributeValueBlueZ value1(
-      Type::UUID, 16, base::MakeUnique<base::StringValue>(kServiceUuid));
+      Type::UUID, 16, base::MakeUnique<base::Value>(kServiceUuid));
   BluetoothServiceAttributeValueBlueZ value2 = value1;
 
   CheckUuidValue(value2, kServiceUuid);
@@ -56,7 +56,7 @@
 
 TEST(BluetoothServiceAttributeBlueZTest, Sequence) {
   BluetoothServiceAttributeValueBlueZ value1(
-      Type::UUID, 16, base::MakeUnique<base::StringValue>(kServiceUuid));
+      Type::UUID, 16, base::MakeUnique<base::Value>(kServiceUuid));
   BluetoothServiceAttributeValueBlueZ value2(
       Type::INT, 4, base::MakeUnique<base::Value>(0x1337));
   BluetoothServiceAttributeValueBlueZ value3(
@@ -80,7 +80,7 @@
 
 TEST(BluetoothServiceAttributeBlueZTest, NestedValue) {
   BluetoothServiceAttributeValueBlueZ value1(
-      Type::UUID, 16, base::MakeUnique<base::StringValue>(kServiceUuid));
+      Type::UUID, 16, base::MakeUnique<base::Value>(kServiceUuid));
   BluetoothServiceAttributeValueBlueZ value2(
       Type::INT, 4, base::MakeUnique<base::Value>(0x1337));
   BluetoothServiceAttributeValueBlueZ value3(MakeSequence({value1, value2}));
@@ -124,7 +124,7 @@
 
 TEST(BluetoothServiceAttributeBlueZTest, CopyAssignment) {
   BluetoothServiceAttributeValueBlueZ value1(
-      Type::UUID, 16, base::MakeUnique<base::StringValue>(kServiceUuid));
+      Type::UUID, 16, base::MakeUnique<base::Value>(kServiceUuid));
   BluetoothServiceAttributeValueBlueZ value2(
       Type::INT, 4, base::MakeUnique<base::Value>(0x1337));
   BluetoothServiceAttributeValueBlueZ value3(
diff --git a/device/bluetooth/bluez/bluetooth_service_record_bluez_unittest.cc b/device/bluetooth/bluez/bluetooth_service_record_bluez_unittest.cc
index a16f67e..0c2433ce0 100644
--- a/device/bluetooth/bluez/bluetooth_service_record_bluez_unittest.cc
+++ b/device/bluetooth/bluez/bluetooth_service_record_bluez_unittest.cc
@@ -130,7 +130,7 @@
     record.AddRecordEntry(kServiceUuidAttributeId,
                           BluetoothServiceAttributeValueBlueZ(
                               BluetoothServiceAttributeValueBlueZ::UUID, 16,
-                              base::MakeUnique<base::StringValue>(uuid)));
+                              base::MakeUnique<base::Value>(uuid)));
     return record;
   }
 
diff --git a/device/bluetooth/dbus/bluetooth_device_client.cc b/device/bluetooth/dbus/bluetooth_device_client.cc
index 09b66e1..53199eb 100644
--- a/device/bluetooth/dbus/bluetooth_device_client.cc
+++ b/device/bluetooth/dbus/bluetooth_device_client.cc
@@ -87,7 +87,7 @@
       std::string str;
       if (!struct_reader->PopVariantOfString(&str))
         return nullptr;
-      value = base::MakeUnique<base::StringValue>(str);
+      value = base::MakeUnique<base::Value>(str);
       break;
     }
     case bluez::BluetoothServiceAttributeValueBlueZ::BOOL: {
diff --git a/device/bluetooth/dbus/fake_bluetooth_device_client.cc b/device/bluetooth/dbus/fake_bluetooth_device_client.cc
index 949d29da..58f694f0 100644
--- a/device/bluetooth/dbus/fake_bluetooth_device_client.cc
+++ b/device/bluetooth/dbus/fake_bluetooth_device_client.cc
@@ -114,7 +114,7 @@
   std::unique_ptr<BluetoothServiceAttributeValueBlueZ::Sequence> class_id_list =
       base::MakeUnique<BluetoothServiceAttributeValueBlueZ::Sequence>();
   class_id_list->emplace_back(BluetoothServiceAttributeValueBlueZ::UUID, 4,
-                              base::MakeUnique<base::StringValue>("1802"));
+                              base::MakeUnique<base::Value>("1802"));
   record1->AddRecordEntry(
       0x1, BluetoothServiceAttributeValueBlueZ(std::move(class_id_list)));
   records.emplace_back(*record1);
diff --git a/extensions/browser/api/app_window/app_window_api.cc b/extensions/browser/api/app_window/app_window_api.cc
index 10d91fb..56e00d5 100644
--- a/extensions/browser/api/app_window/app_window_api.cc
+++ b/extensions/browser/api/app_window/app_window_api.cc
@@ -382,7 +382,7 @@
 
   std::unique_ptr<base::DictionaryValue> result(new base::DictionaryValue);
   result->Set("frameId", new base::Value(frame_id));
-  result->Set("id", new base::StringValue(app_window->window_key()));
+  result->Set("id", new base::Value(app_window->window_key()));
   app_window->GetSerializedState(result.get());
   SetResult(std::move(result));
 
diff --git a/extensions/browser/api/cast_channel/cast_message_util.cc b/extensions/browser/api/cast_channel/cast_message_util.cc
index 7cdf1c5..5d4e9ff8 100644
--- a/extensions/browser/api/cast_channel/cast_message_util.cc
+++ b/extensions/browser/api/cast_channel/cast_message_util.cc
@@ -81,7 +81,7 @@
   switch (message_proto.payload_type()) {
   case CastMessage_PayloadType_STRING:
     if (message_proto.has_payload_utf8())
-      value.reset(new base::StringValue(message_proto.payload_utf8()));
+      value.reset(new base::Value(message_proto.payload_utf8()));
     break;
   case CastMessage_PayloadType_BINARY:
     if (message_proto.has_payload_binary())
diff --git a/extensions/browser/api/declarative/declarative_api.cc b/extensions/browser/api/declarative/declarative_api.cc
index 6fdeacc..84dbfff 100644
--- a/extensions/browser/api/declarative/declarative_api.cc
+++ b/extensions/browser/api/declarative/declarative_api.cc
@@ -41,12 +41,11 @@
 
 // Encodes |binary| as base64 and returns a new StringValue populated with the
 // encoded string.
-std::unique_ptr<base::StringValue> ConvertBinaryToBase64(
-    base::BinaryValue* binary) {
+std::unique_ptr<base::Value> ConvertBinaryToBase64(base::BinaryValue* binary) {
   std::string binary_data = std::string(binary->GetBuffer(), binary->GetSize());
   std::string data64;
   base::Base64Encode(binary_data, &data64);
-  return std::unique_ptr<base::StringValue>(new base::StringValue(data64));
+  return std::unique_ptr<base::Value>(new base::Value(data64));
 }
 
 // Parses through |args| replacing any BinaryValues with base64 encoded
diff --git a/extensions/browser/api/declarative_webrequest/webrequest_condition_attribute.cc b/extensions/browser/api/declarative_webrequest/webrequest_condition_attribute.cc
index e40c6c4..53edf36 100644
--- a/extensions/browser/api/declarative_webrequest/webrequest_condition_attribute.cc
+++ b/extensions/browser/api/declarative_webrequest/webrequest_condition_attribute.cc
@@ -35,7 +35,6 @@
 using base::CaseInsensitiveCompareASCII;
 using base::DictionaryValue;
 using base::ListValue;
-using base::StringValue;
 using base::Value;
 
 namespace helpers = extension_web_request_api_helpers;
diff --git a/extensions/browser/api/declarative_webrequest/webrequest_condition_attribute_unittest.cc b/extensions/browser/api/declarative_webrequest/webrequest_condition_attribute_unittest.cc
index 1dfaac9..0ef967fed 100644
--- a/extensions/browser/api/declarative_webrequest/webrequest_condition_attribute_unittest.cc
+++ b/extensions/browser/api/declarative_webrequest/webrequest_condition_attribute_unittest.cc
@@ -27,7 +27,6 @@
 
 using base::DictionaryValue;
 using base::ListValue;
-using base::StringValue;
 using base::Value;
 
 namespace extensions {
@@ -49,7 +48,7 @@
 
   std::string error;
   scoped_refptr<const WebRequestConditionAttribute> result;
-  base::StringValue string_value("main_frame");
+  base::Value string_value("main_frame");
   base::ListValue resource_types;
   resource_types.AppendString("main_frame");
 
diff --git a/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc b/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc
index a910b4a..6dbbc9b1 100644
--- a/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc
+++ b/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc
@@ -334,7 +334,7 @@
     return;
   }
 
-  SetResult(base::MakeUnique<base::StringValue>(base64_result));
+  SetResult(base::MakeUnique<base::Value>(base64_result));
   SendResponse(true);
 }
 
@@ -703,8 +703,8 @@
       NOTREACHED();
   }
 
-  return RespondNow(OneArgument(base::MakeUnique<base::StringValue>(
-      web_view_internal::ToString(zoom_mode))));
+  return RespondNow(OneArgument(
+      base::MakeUnique<base::Value>(web_view_internal::ToString(zoom_mode))));
 }
 
 WebViewInternalFindFunction::WebViewInternalFindFunction() {
diff --git a/extensions/browser/api/idle/idle_manager.cc b/extensions/browser/api/idle/idle_manager.cc
index 715c98a..1b1adf26 100644
--- a/extensions/browser/api/idle/idle_manager.cc
+++ b/extensions/browser/api/idle/idle_manager.cc
@@ -181,7 +181,7 @@
 }
 
 // static
-std::unique_ptr<base::StringValue> IdleManager::CreateIdleValue(
+std::unique_ptr<base::Value> IdleManager::CreateIdleValue(
     ui::IdleState idle_state) {
   const char* description;
 
@@ -193,7 +193,7 @@
     description = keys::kStateLocked;
   }
 
-  return base::MakeUnique<base::StringValue>(description);
+  return base::MakeUnique<base::Value>(description);
 }
 
 void IdleManager::SetEventDelegateForTest(
diff --git a/extensions/browser/api/idle/idle_manager.h b/extensions/browser/api/idle/idle_manager.h
index 2dd296b..e4a076b 100644
--- a/extensions/browser/api/idle/idle_manager.h
+++ b/extensions/browser/api/idle/idle_manager.h
@@ -23,7 +23,6 @@
 
 namespace base {
 class Value;
-using StringValue = Value;
 }  // namespace base
 
 namespace content {
@@ -92,8 +91,7 @@
 
   void QueryState(int threshold, const QueryStateCallback& notify);
   void SetThreshold(const std::string& extension_id, int threshold);
-  static std::unique_ptr<base::StringValue> CreateIdleValue(
-      ui::IdleState idle_state);
+  static std::unique_ptr<base::Value> CreateIdleValue(ui::IdleState idle_state);
 
   // Override default event class. Callee assumes ownership. Used for testing.
   void SetEventDelegateForTest(std::unique_ptr<EventDelegate> event_delegate);
diff --git a/extensions/browser/api/metrics_private/metrics_private_api.cc b/extensions/browser/api/metrics_private/metrics_private_api.cc
index 844a056..c1be316 100644
--- a/extensions/browser/api/metrics_private/metrics_private_api.cc
+++ b/extensions/browser/api/metrics_private/metrics_private_api.cc
@@ -52,8 +52,8 @@
   std::string name;
   EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &name));
 
-  return RespondNow(OneArgument(base::MakeUnique<base::StringValue>(
-      base::FieldTrialList::FindFullName(name))));
+  return RespondNow(OneArgument(
+      base::MakeUnique<base::Value>(base::FieldTrialList::FindFullName(name))));
 }
 
 ExtensionFunction::ResponseAction
diff --git a/extensions/browser/api/networking_private/networking_private_chromeos.cc b/extensions/browser/api/networking_private/networking_private_chromeos.cc
index 15d6816..0396e47 100644
--- a/extensions/browser/api/networking_private/networking_private_chromeos.cc
+++ b/extensions/browser/api/networking_private/networking_private_chromeos.cc
@@ -280,9 +280,9 @@
   base::DictionaryValue* dict = EnsureDictionaryValue(key, manual);
   base::DictionaryValue* host_dict =
       EnsureDictionaryValue(::onc::proxy::kHost, dict);
-  SetProxyEffectiveValue(host_dict, state,
-                         base::MakeUnique<base::StringValue>(
-                             proxy.server.host_port_pair().host()));
+  SetProxyEffectiveValue(
+      host_dict, state,
+      base::MakeUnique<base::Value>(proxy.server.host_port_pair().host()));
   uint16_t port = proxy.server.host_port_pair().port();
   base::DictionaryValue* port_dict =
       EnsureDictionaryValue(::onc::proxy::kPort, dict);
@@ -779,7 +779,7 @@
   base::DictionaryValue* proxy_type_dict =
       EnsureDictionaryValue(::onc::network_config::kType, proxy_settings);
   SetProxyEffectiveValue(proxy_type_dict, state,
-                         base::WrapUnique<base::Value>(new base::StringValue(
+                         base::WrapUnique<base::Value>(new base::Value(
                              GetProxySettingsType(config.mode))));
 
   // Update any appropriate sub dictionary based on the new type.
@@ -806,9 +806,9 @@
     case UIProxyConfig::MODE_PAC_SCRIPT: {
       base::DictionaryValue* pac =
           EnsureDictionaryValue(::onc::proxy::kPAC, proxy_settings);
-      SetProxyEffectiveValue(
-          pac, state, base::WrapUnique<base::Value>(new base::StringValue(
-                          config.automatic_proxy.pac_url.spec())));
+      SetProxyEffectiveValue(pac, state,
+                             base::WrapUnique<base::Value>(new base::Value(
+                                 config.automatic_proxy.pac_url.spec())));
       break;
     }
     case UIProxyConfig::MODE_DIRECT:
diff --git a/extensions/browser/api/runtime/runtime_api.cc b/extensions/browser/api/runtime/runtime_api.cc
index f5644c4b..bb4a1f7 100644
--- a/extensions/browser/api/runtime/runtime_api.cc
+++ b/extensions/browser/api/runtime/runtime_api.cc
@@ -155,8 +155,8 @@
 void SetUninstallURL(ExtensionPrefs* prefs,
                      const std::string& extension_id,
                      const std::string& url_string) {
-  prefs->UpdateExtensionPref(
-      extension_id, kUninstallUrl, new base::StringValue(url_string));
+  prefs->UpdateExtensionPref(extension_id, kUninstallUrl,
+                             new base::Value(url_string));
 }
 
 std::string GetUninstallURL(ExtensionPrefs* prefs,
@@ -701,11 +701,11 @@
   if (result.success) {
     std::unique_ptr<base::DictionaryValue> details(new base::DictionaryValue);
     details->SetString("version", result.version);
-    Respond(TwoArguments(base::MakeUnique<base::StringValue>(result.response),
+    Respond(TwoArguments(base::MakeUnique<base::Value>(result.response),
                          std::move(details)));
   } else {
     // HMM(kalman): Why does !success not imply Error()?
-    Respond(OneArgument(base::MakeUnique<base::StringValue>(result.response)));
+    Respond(OneArgument(base::MakeUnique<base::Value>(result.response)));
   }
 }
 
diff --git a/extensions/browser/api/storage/settings_quota_unittest.cc b/extensions/browser/api/storage/settings_quota_unittest.cc
index b2aab26..26373fe8 100644
--- a/extensions/browser/api/storage/settings_quota_unittest.cc
+++ b/extensions/browser/api/storage/settings_quota_unittest.cc
@@ -69,7 +69,7 @@
 
   // Values with different serialized sizes.
   base::Value byte_value_1_;
-  base::StringValue byte_value_16_;
+  base::Value byte_value_16_;
   base::ListValue byte_value_256_;
 
   // Quota enforcing storage area being tested.
diff --git a/extensions/browser/api/storage/settings_test_util.cc b/extensions/browser/api/storage/settings_test_util.cc
index edc4254..1b619ef6 100644
--- a/extensions/browser/api/storage/settings_test_util.cc
+++ b/extensions/browser/api/storage/settings_test_util.cc
@@ -23,7 +23,7 @@
   for (int i = 0; i < 1024; ++i) {
     kilobyte_string += "a";
   }
-  return std::unique_ptr<base::Value>(new base::StringValue(kilobyte_string));
+  return std::unique_ptr<base::Value>(new base::Value(kilobyte_string));
 }
 
 // Creates a megabyte of data.
diff --git a/extensions/browser/api/storage/storage_frontend_unittest.cc b/extensions/browser/api/storage/storage_frontend_unittest.cc
index 6f37a2e..91733d6b 100644
--- a/extensions/browser/api/storage/storage_frontend_unittest.cc
+++ b/extensions/browser/api/storage/storage_frontend_unittest.cc
@@ -103,7 +103,7 @@
   // The correctness of Get/Set/Remove/Clear is tested elsewhere so no need to
   // be too rigorous.
   {
-    base::StringValue bar("bar");
+    base::Value bar("bar");
     ValueStore::WriteResult result = storage->Set(DEFAULTS, "foo", bar);
     ASSERT_TRUE(result->status().ok());
   }
@@ -133,7 +133,7 @@
       util::GetStorage(extension, settings::LOCAL, frontend_.get());
 
   {
-    base::StringValue bar("bar");
+    base::Value bar("bar");
     ValueStore::WriteResult result = storage->Set(DEFAULTS, "foo", bar);
     ASSERT_TRUE(result->status().ok());
   }
@@ -160,7 +160,7 @@
       util::GetStorage(extension, settings::LOCAL, frontend_.get());
 
   {
-    base::StringValue bar("bar");
+    base::Value bar("bar");
     ValueStore::WriteResult result = storage->Set(DEFAULTS, "foo", bar);
     ASSERT_TRUE(result->status().ok());
     EXPECT_TRUE(base::PathExists(temp_dir_.GetPath()));
diff --git a/extensions/browser/api/system_storage/system_storage_api.cc b/extensions/browser/api/system_storage/system_storage_api.cc
index 3bd5ecfa..ebc0ae5 100644
--- a/extensions/browser/api/system_storage/system_storage_api.cc
+++ b/extensions/browser/api/system_storage/system_storage_api.cc
@@ -89,8 +89,8 @@
       result = api::system_storage::EJECT_DEVICE_RESULT_CODE_FAILURE;
   }
 
-  Respond(OneArgument(base::MakeUnique<base::StringValue>(
-      api::system_storage::ToString(result))));
+  Respond(OneArgument(
+      base::MakeUnique<base::Value>(api::system_storage::ToString(result))));
 }
 
 SystemStorageGetAvailableCapacityFunction::
diff --git a/extensions/browser/api/test/test_api.cc b/extensions/browser/api/test/test_api.cc
index 2eefdaf9..7bd4372 100644
--- a/extensions/browser/api/test/test_api.cc
+++ b/extensions/browser/api/test/test_api.cc
@@ -97,8 +97,7 @@
   // finish the function.
   if (!listener_will_respond || response_.get()) {
     if (!response_) {
-      response_ =
-          OneArgument(base::MakeUnique<base::StringValue>(std::string()));
+      response_ = OneArgument(base::MakeUnique<base::Value>(std::string()));
     }
     return RespondNow(std::move(response_));
   }
@@ -111,7 +110,7 @@
 
 void TestSendMessageFunction::Reply(const std::string& message) {
   DCHECK(!response_);
-  response_ = OneArgument(base::MakeUnique<base::StringValue>(message));
+  response_ = OneArgument(base::MakeUnique<base::Value>(message));
   if (waiting_)
     Respond(std::move(response_));
 }
@@ -155,7 +154,7 @@
   std::unique_ptr<WaitForRoundTrip::Params> params(
       WaitForRoundTrip::Params::Create(*args_));
   return RespondNow(
-      OneArgument(base::MakeUnique<base::StringValue>(params->message)));
+      OneArgument(base::MakeUnique<base::Value>(params->message)));
 }
 
 }  // namespace extensions
diff --git a/extensions/browser/api/vpn_provider/vpn_provider_api.cc b/extensions/browser/api/vpn_provider/vpn_provider_api.cc
index 5f58f32..27d9c02 100644
--- a/extensions/browser/api/vpn_provider/vpn_provider_api.cc
+++ b/extensions/browser/api/vpn_provider/vpn_provider_api.cc
@@ -163,7 +163,7 @@
 
 void VpnThreadExtensionFunction::SignalCallCompletionSuccessWithId(
     const std::string& configuration_id) {
-  Respond(OneArgument(base::MakeUnique<base::StringValue>(configuration_id)));
+  Respond(OneArgument(base::MakeUnique<base::Value>(configuration_id)));
 }
 
 void VpnThreadExtensionFunction::SignalCallCompletionSuccessWithWarning(
diff --git a/extensions/browser/api/web_request/upload_data_presenter.cc b/extensions/browser/api/web_request/upload_data_presenter.cc
index ff63010..dfe9eda0 100644
--- a/extensions/browser/api/web_request/upload_data_presenter.cc
+++ b/extensions/browser/api/web_request/upload_data_presenter.cc
@@ -19,7 +19,6 @@
 using base::BinaryValue;
 using base::DictionaryValue;
 using base::ListValue;
-using base::StringValue;
 using base::Value;
 
 namespace keys = extension_web_request_api_constants;
@@ -98,7 +97,7 @@
 void RawDataPresenter::FeedNextFile(const std::string& filename) {
   // Insert the file path instead of the contents, which may be too large.
   subtle::AppendKeyValuePair(keys::kRequestBodyRawFileKey,
-                             base::MakeUnique<base::StringValue>(filename),
+                             base::MakeUnique<base::Value>(filename),
                              list_.get());
 }
 
diff --git a/extensions/browser/api/web_request/upload_data_presenter_unittest.cc b/extensions/browser/api/web_request/upload_data_presenter_unittest.cc
index 6a2fe4f..548ad63 100644
--- a/extensions/browser/api/web_request/upload_data_presenter_unittest.cc
+++ b/extensions/browser/api/web_request/upload_data_presenter_unittest.cc
@@ -54,8 +54,7 @@
   std::unique_ptr<base::BinaryValue> expected_a(
       base::BinaryValue::CreateWithCopiedBuffer(block1, block1_size));
   ASSERT_TRUE(expected_a.get() != NULL);
-  std::unique_ptr<base::StringValue> expected_b(
-      new base::StringValue(kFilename));
+  std::unique_ptr<base::Value> expected_b(new base::Value(kFilename));
   ASSERT_TRUE(expected_b.get() != NULL);
   std::unique_ptr<base::BinaryValue> expected_c(
       base::BinaryValue::CreateWithCopiedBuffer(block2, block2_size));
diff --git a/extensions/browser/api/webcam_private/webcam_private_api_chromeos.cc b/extensions/browser/api/webcam_private/webcam_private_api_chromeos.cc
index f1526d18..fc4ad9e 100644
--- a/extensions/browser/api/webcam_private/webcam_private_api_chromeos.cc
+++ b/extensions/browser/api/webcam_private/webcam_private_api_chromeos.cc
@@ -205,7 +205,7 @@
     const std::string& webcam_id,
     bool success) {
   if (success) {
-    SetResult(base::MakeUnique<base::StringValue>(webcam_id));
+    SetResult(base::MakeUnique<base::Value>(webcam_id));
     SendResponse(true);
   } else {
     SetError(kOpenSerialWebcamError);
diff --git a/extensions/browser/event_listener_map_unittest.cc b/extensions/browser/event_listener_map_unittest.cc
index b308f18b..67de0d8 100644
--- a/extensions/browser/event_listener_map_unittest.cc
+++ b/extensions/browser/event_listener_map_unittest.cc
@@ -16,7 +16,7 @@
 
 using base::DictionaryValue;
 using base::ListValue;
-using base::StringValue;
+using base::Value;
 
 namespace extensions {
 
@@ -54,7 +54,7 @@
     std::unique_ptr<ListValue> filter_list(new ListValue);
     std::unique_ptr<DictionaryValue> filter_dict(new DictionaryValue);
 
-    filter_dict->Set("hostSuffix", new StringValue(suffix));
+    filter_dict->Set("hostSuffix", new Value(suffix));
 
     filter_list->Append(std::move(filter_dict));
     filter->Set("url", filter_list.release());
diff --git a/extensions/browser/event_router_unittest.cc b/extensions/browser/event_router_unittest.cc
index 53cb9daa..f76c6c15 100644
--- a/extensions/browser/event_router_unittest.cc
+++ b/extensions/browser/event_router_unittest.cc
@@ -31,7 +31,7 @@
 
 using base::DictionaryValue;
 using base::ListValue;
-using base::StringValue;
+using base::Value;
 
 namespace extensions {
 
@@ -124,7 +124,7 @@
   std::unique_ptr<ListValue> filter_list(new ListValue());
   std::unique_ptr<DictionaryValue> filter_dict(new DictionaryValue());
 
-  filter_dict->Set("hostSuffix", base::MakeUnique<StringValue>(suffix));
+  filter_dict->Set("hostSuffix", base::MakeUnique<Value>(suffix));
   filter_list->Append(std::move(filter_dict));
   filter->Set("url", std::move(filter_list));
 
diff --git a/extensions/browser/extension_pref_value_map_unittest.cc b/extensions/browser/extension_pref_value_map_unittest.cc
index c2f1fdd..36c2fb9 100644
--- a/extensions/browser/extension_pref_value_map_unittest.cc
+++ b/extensions/browser/extension_pref_value_map_unittest.cc
@@ -27,7 +27,7 @@
 }  // namespace
 
 static base::Value* CreateVal(const char* str) {
-  return new base::StringValue(str);
+  return new base::Value(str);
 }
 
 static base::Time CreateTime(int64_t t) {
diff --git a/extensions/browser/extension_prefs.cc b/extensions/browser/extension_prefs.cc
index ae1aa4a..eaf48f3 100644
--- a/extensions/browser/extension_prefs.cc
+++ b/extensions/browser/extension_prefs.cc
@@ -1361,8 +1361,7 @@
   const base::Time install_time = time_provider_->GetCurrentTime();
   pending_install_dict->Set(
       kPrefInstallTime,
-      new base::StringValue(
-          base::Int64ToString(install_time.ToInternalValue())));
+      new base::Value(base::Int64ToString(install_time.ToInternalValue())));
 
   // Commit the delayed install data.
   for (base::DictionaryValue::Iterator it(*pending_install_dict); !it.IsAtEnd();
@@ -1694,9 +1693,8 @@
 
 void ExtensionPrefs::SetInstallParam(const std::string& extension_id,
                                      const std::string& install_parameter) {
-  UpdateExtensionPref(extension_id,
-                      kPrefInstallParam,
-                      new base::StringValue(install_parameter));
+  UpdateExtensionPref(extension_id, kPrefInstallParam,
+                      new base::Value(install_parameter));
 }
 
 int ExtensionPrefs::GetCorruptedDisableCount() const {
@@ -1844,18 +1842,17 @@
                       new base::Value(extension->was_installed_by_default()));
   extension_dict->Set(kPrefWasInstalledByOem,
                       new base::Value(extension->was_installed_by_oem()));
-  extension_dict->Set(kPrefInstallTime,
-                      new base::StringValue(
-                          base::Int64ToString(install_time.ToInternalValue())));
+  extension_dict->Set(
+      kPrefInstallTime,
+      new base::Value(base::Int64ToString(install_time.ToInternalValue())));
   if (install_flags & kInstallFlagIsBlacklistedForMalware)
     extension_dict->Set(kPrefBlacklist, new base::Value(true));
 
   base::FilePath::StringType path = MakePathRelative(install_directory_,
                                                      extension->path());
-  extension_dict->Set(kPrefPath, new base::StringValue(path));
+  extension_dict->Set(kPrefPath, new base::Value(path));
   if (!install_parameter.empty()) {
-    extension_dict->Set(kPrefInstallParam,
-                        new base::StringValue(install_parameter));
+    extension_dict->Set(kPrefInstallParam, new base::Value(install_parameter));
   }
   // We store prefs about LOAD extensions, but don't cache their manifest
   // since it may change on disk.
diff --git a/extensions/browser/guest_view/web_view/javascript_dialog_helper.cc b/extensions/browser/guest_view/web_view/javascript_dialog_helper.cc
index e420cdc..1d48653 100644
--- a/extensions/browser/guest_view/web_view/javascript_dialog_helper.cc
+++ b/extensions/browser/guest_view/web_view/javascript_dialog_helper.cc
@@ -49,15 +49,13 @@
     const DialogClosedCallback& callback,
     bool* did_suppress_message) {
   base::DictionaryValue request_info;
-  request_info.Set(
-      webview::kDefaultPromptText,
-      new base::StringValue(base::UTF16ToUTF8(default_prompt_text)));
+  request_info.Set(webview::kDefaultPromptText,
+                   new base::Value(base::UTF16ToUTF8(default_prompt_text)));
   request_info.Set(webview::kMessageText,
-                   new base::StringValue(base::UTF16ToUTF8(message_text)));
-  request_info.Set(
-      webview::kMessageType,
-      new base::StringValue(JavaScriptDialogTypeToString(dialog_type)));
-  request_info.Set(guest_view::kUrl, new base::StringValue(origin_url.spec()));
+                   new base::Value(base::UTF16ToUTF8(message_text)));
+  request_info.Set(webview::kMessageType,
+                   new base::Value(JavaScriptDialogTypeToString(dialog_type)));
+  request_info.Set(guest_view::kUrl, new base::Value(origin_url.spec()));
   WebViewPermissionHelper* web_view_permission_helper =
       WebViewPermissionHelper::FromWebContents(web_contents);
   web_view_permission_helper->RequestPermission(
diff --git a/extensions/browser/guest_view/web_view/web_view_guest.cc b/extensions/browser/guest_view/web_view/web_view_guest.cc
index 6973ebb0..e127774 100644
--- a/extensions/browser/guest_view/web_view/web_view_guest.cc
+++ b/extensions/browser/guest_view/web_view/web_view_guest.cc
@@ -1487,16 +1487,15 @@
   request_info.SetInteger(webview::kInitialHeight, initial_bounds.height());
   request_info.SetInteger(webview::kInitialWidth, initial_bounds.width());
   request_info.Set(webview::kTargetURL,
-                   new base::StringValue(new_window_info.url.spec()));
-  request_info.Set(webview::kName, new base::StringValue(new_window_info.name));
+                   new base::Value(new_window_info.url.spec()));
+  request_info.Set(webview::kName, new base::Value(new_window_info.name));
   request_info.SetInteger(webview::kWindowID, guest->guest_instance_id());
   // We pass in partition info so that window-s created through newwindow
   // API can use it to set their partition attribute.
   request_info.Set(webview::kStoragePartitionId,
-                   new base::StringValue(storage_partition_id));
-  request_info.Set(
-      webview::kWindowOpenDisposition,
-      new base::StringValue(WindowOpenDispositionToString(disposition)));
+                   new base::Value(storage_partition_id));
+  request_info.Set(webview::kWindowOpenDisposition,
+                   new base::Value(WindowOpenDispositionToString(disposition)));
 
   web_view_permission_helper_->
       RequestPermission(WEB_VIEW_PERMISSION_TYPE_NEW_WINDOW,
diff --git a/extensions/browser/value_store/leveldb_value_store_unittest.cc b/extensions/browser/value_store/leveldb_value_store_unittest.cc
index 8498409e..4cb1151 100644
--- a/extensions/browser/value_store/leveldb_value_store_unittest.cc
+++ b/extensions/browser/value_store/leveldb_value_store_unittest.cc
@@ -75,7 +75,7 @@
   const char kValue[] = "value";
 
   // Insert a valid pair.
-  std::unique_ptr<base::Value> value(new base::StringValue(kValue));
+  std::unique_ptr<base::Value> value(new base::Value(kValue));
   ASSERT_TRUE(store()
                   ->Set(ValueStore::DEFAULTS, kNotCorruptKey, *value)
                   ->status().ok());
@@ -117,7 +117,7 @@
   const char kCorruptValue[] = "[{(.*+\"\'\\";
 
   // Insert a collection of non-corrupted pairs.
-  std::unique_ptr<base::Value> value(new base::StringValue(kValue));
+  std::unique_ptr<base::Value> value(new base::Value(kValue));
   for (size_t i = 0; i < kNotCorruptKeysSize; ++i) {
     ASSERT_TRUE(store()
                     ->Set(ValueStore::DEFAULTS, kNotCorruptKeys[i], *value)
@@ -163,7 +163,7 @@
   const char kValue[] = "value";
 
   // Generate a database.
-  std::unique_ptr<base::Value> value(new base::StringValue(kValue));
+  std::unique_ptr<base::Value> value(new base::Value(kValue));
   for (size_t i = 0; i < kNotCorruptKeysSize; ++i) {
     ASSERT_TRUE(store()
                     ->Set(ValueStore::DEFAULTS, kNotCorruptKeys[i], *value)
diff --git a/extensions/browser/value_store/value_store_change_unittest.cc b/extensions/browser/value_store/value_store_change_unittest.cc
index ef4934a7..10fd6a0 100644
--- a/extensions/browser/value_store/value_store_change_unittest.cc
+++ b/extensions/browser/value_store/value_store_change_unittest.cc
@@ -20,40 +20,39 @@
 
 TEST(ValueStoreChangeTest, NullOldValue) {
   ValueStoreChange change("key", nullptr,
-                          base::MakeUnique<base::StringValue>("value"));
+                          base::MakeUnique<base::Value>("value"));
 
   EXPECT_EQ("key", change.key());
   EXPECT_EQ(NULL, change.old_value());
   {
-    base::StringValue expected("value");
+    base::Value expected("value");
     EXPECT_TRUE(change.new_value()->Equals(&expected));
   }
 }
 
 TEST(ValueStoreChangeTest, NullNewValue) {
-  ValueStoreChange change("key", base::MakeUnique<base::StringValue>("value"),
+  ValueStoreChange change("key", base::MakeUnique<base::Value>("value"),
                           nullptr);
 
   EXPECT_EQ("key", change.key());
   {
-    base::StringValue expected("value");
+    base::Value expected("value");
     EXPECT_TRUE(change.old_value()->Equals(&expected));
   }
   EXPECT_EQ(NULL, change.new_value());
 }
 
 TEST(ValueStoreChangeTest, NonNullValues) {
-  ValueStoreChange change("key",
-                          base::MakeUnique<base::StringValue>("old_value"),
-                          base::MakeUnique<base::StringValue>("new_value"));
+  ValueStoreChange change("key", base::MakeUnique<base::Value>("old_value"),
+                          base::MakeUnique<base::Value>("new_value"));
 
   EXPECT_EQ("key", change.key());
   {
-    base::StringValue expected("old_value");
+    base::Value expected("old_value");
     EXPECT_TRUE(change.old_value()->Equals(&expected));
   }
   {
-    base::StringValue expected("new_value");
+    base::Value expected("new_value");
     EXPECT_TRUE(change.new_value()->Equals(&expected));
   }
 }
diff --git a/extensions/browser/value_store/value_store_frontend_unittest.cc b/extensions/browser/value_store/value_store_frontend_unittest.cc
index abc33a9..8a7281d 100644
--- a/extensions/browser/value_store/value_store_frontend_unittest.cc
+++ b/extensions/browser/value_store/value_store_frontend_unittest.cc
@@ -96,8 +96,7 @@
 
 TEST_F(ValueStoreFrontendTest, ChangesPersistAfterReload) {
   storage_->Set("key0", std::unique_ptr<base::Value>(new base::Value(0)));
-  storage_->Set("key1",
-                std::unique_ptr<base::Value>(new base::StringValue("new1")));
+  storage_->Set("key1", std::unique_ptr<base::Value>(new base::Value("new1")));
   storage_->Remove("key2");
 
   // Reload the DB and test our changes.
diff --git a/extensions/browser/value_store/value_store_unittest.cc b/extensions/browser/value_store/value_store_unittest.cc
index 9d332d7c..d3dfba3b 100644
--- a/extensions/browser/value_store/value_store_unittest.cc
+++ b/extensions/browser/value_store/value_store_unittest.cc
@@ -133,9 +133,9 @@
       dict123_(new base::DictionaryValue()),
       ui_thread_(BrowserThread::UI, base::MessageLoop::current()),
       file_thread_(BrowserThread::FILE, base::MessageLoop::current()) {
-  val1_.reset(new base::StringValue(key1_ + "Value"));
-  val2_.reset(new base::StringValue(key2_ + "Value"));
-  val3_.reset(new base::StringValue(key3_ + "Value"));
+  val1_.reset(new base::Value(key1_ + "Value"));
+  val2_.reset(new base::Value(key2_ + "Value"));
+  val3_.reset(new base::Value(key3_ + "Value"));
 
   list1_.push_back(key1_);
   list2_.push_back(key2_);
@@ -330,7 +330,7 @@
 // indexing into a dictionary.
 TEST_P(ValueStoreTest, DotsInKeyNames) {
   std::string dot_key("foo.bar");
-  base::StringValue dot_value("baz.qux");
+  base::Value dot_value("baz.qux");
   std::vector<std::string> dot_list;
   dot_list.push_back(dot_key);
   base::DictionaryValue dot_dict;
diff --git a/extensions/common/event_filter_unittest.cc b/extensions/common/event_filter_unittest.cc
index 6e96c991..d51e163 100644
--- a/extensions/common/event_filter_unittest.cc
+++ b/extensions/common/event_filter_unittest.cc
@@ -33,7 +33,7 @@
  protected:
   std::unique_ptr<base::Value> HostSuffixDict(const std::string& host_suffix) {
     std::unique_ptr<base::DictionaryValue> dict(new DictionaryValue());
-    dict->Set("hostSuffix", new base::StringValue(host_suffix));
+    dict->Set("hostSuffix", new base::Value(host_suffix));
     return std::unique_ptr<base::Value>(dict.release());
   }
 
diff --git a/extensions/common/extension_l10n_util.cc b/extensions/common/extension_l10n_util.cc
index bf0194a4..4422ca3 100644
--- a/extensions/common/extension_l10n_util.cc
+++ b/extensions/common/extension_l10n_util.cc
@@ -92,7 +92,7 @@
     std::string result;
     if (list->GetString(i, &result)) {
       if (messages.ReplaceMessages(&result, error))
-        list->Set(i, new base::StringValue(result));
+        list->Set(i, new base::Value(result));
       else
         ret = false;
     }
diff --git a/extensions/common/permissions/media_galleries_permission_data.cc b/extensions/common/permissions/media_galleries_permission_data.cc
index 13f7d93..330923d 100644
--- a/extensions/common/permissions/media_galleries_permission_data.cc
+++ b/extensions/common/permissions/media_galleries_permission_data.cc
@@ -24,7 +24,7 @@
 }
 
 std::unique_ptr<base::Value> MediaGalleriesPermissionData::ToValue() const {
-  return std::unique_ptr<base::Value>(new base::StringValue(permission_));
+  return std::unique_ptr<base::Value>(new base::Value(permission_));
 }
 
 bool MediaGalleriesPermissionData::FromValue(const base::Value* value) {
diff --git a/extensions/common/permissions/settings_override_permission.cc b/extensions/common/permissions/settings_override_permission.cc
index df5b073..55f6a17 100644
--- a/extensions/common/permissions/settings_override_permission.cc
+++ b/extensions/common/permissions/settings_override_permission.cc
@@ -62,7 +62,7 @@
 }
 
 std::unique_ptr<base::Value> SettingsOverrideAPIPermission::ToValue() const {
-  return base::MakeUnique<base::StringValue>(setting_value_);
+  return base::MakeUnique<base::Value>(setting_value_);
 }
 
 APIPermission* SettingsOverrideAPIPermission::Clone() const {
diff --git a/extensions/common/permissions/socket_permission_data.cc b/extensions/common/permissions/socket_permission_data.cc
index e4dbbdc..1616a10 100644
--- a/extensions/common/permissions/socket_permission_data.cc
+++ b/extensions/common/permissions/socket_permission_data.cc
@@ -103,7 +103,7 @@
 }
 
 std::unique_ptr<base::Value> SocketPermissionData::ToValue() const {
-  return std::unique_ptr<base::Value>(new base::StringValue(GetAsString()));
+  return std::unique_ptr<base::Value>(new base::Value(GetAsString()));
 }
 
 bool SocketPermissionData::FromValue(const base::Value* value) {
diff --git a/extensions/common/url_pattern_set.cc b/extensions/common/url_pattern_set.cc
index 5686092..28c8cf7 100644
--- a/extensions/common/url_pattern_set.cc
+++ b/extensions/common/url_pattern_set.cc
@@ -233,8 +233,7 @@
   std::unique_ptr<base::ListValue> value(new base::ListValue);
   for (URLPatternSet::const_iterator i = patterns_.begin();
        i != patterns_.end(); ++i)
-    value->AppendIfNotPresent(
-        base::MakeUnique<base::StringValue>(i->GetAsString()));
+    value->AppendIfNotPresent(base::MakeUnique<base::Value>(i->GetAsString()));
   return value;
 }
 
diff --git a/extensions/common/value_builder.cc b/extensions/common/value_builder.cc
index 08bb7de..7f2a177 100644
--- a/extensions/common/value_builder.cc
+++ b/extensions/common/value_builder.cc
@@ -42,15 +42,13 @@
 
 DictionaryBuilder& DictionaryBuilder::Set(const std::string& path,
                                           const std::string& in_value) {
-  dict_->SetWithoutPathExpansion(path,
-                                 base::MakeUnique<base::StringValue>(in_value));
+  dict_->SetWithoutPathExpansion(path, base::MakeUnique<base::Value>(in_value));
   return *this;
 }
 
 DictionaryBuilder& DictionaryBuilder::Set(const std::string& path,
                                           const base::string16& in_value) {
-  dict_->SetWithoutPathExpansion(path,
-                                 base::MakeUnique<base::StringValue>(in_value));
+  dict_->SetWithoutPathExpansion(path, base::MakeUnique<base::Value>(in_value));
   return *this;
 }
 
diff --git a/extensions/renderer/activity_log_converter_strategy.cc b/extensions/renderer/activity_log_converter_strategy.cc
index 1be41aa..443535f 100644
--- a/extensions/renderer/activity_log_converter_strategy.cc
+++ b/extensions/renderer/activity_log_converter_strategy.cc
@@ -40,11 +40,11 @@
 
   if (try_catch.HasCaught()) {
     return std::unique_ptr<base::Value>(
-        new base::StringValue("[JS Execution Exception]"));
+        new base::Value("[JS Execution Exception]"));
   }
 
   return std::unique_ptr<base::Value>(
-      new base::StringValue(std::string(*v8::String::Utf8Value(name))));
+      new base::Value(std::string(*v8::String::Utf8Value(name))));
 }
 
 }  // namespace
diff --git a/extensions/renderer/api_binding_bridge.cc b/extensions/renderer/api_binding_bridge.cc
index d3b5805e..6d8b2dc6 100644
--- a/extensions/renderer/api_binding_bridge.cc
+++ b/extensions/renderer/api_binding_bridge.cc
@@ -6,6 +6,7 @@
 
 #include "base/values.h"
 #include "extensions/renderer/api_binding_hooks.h"
+#include "extensions/renderer/api_event_handler.h"
 #include "extensions/renderer/api_request_handler.h"
 #include "extensions/renderer/api_signature.h"
 #include "extensions/renderer/api_type_reference_map.h"
@@ -30,6 +31,7 @@
 
 APIBindingBridge::APIBindingBridge(const APITypeReferenceMap* type_refs,
                                    APIRequestHandler* request_handler,
+                                   APIEventHandler* event_handler,
                                    APIBindingHooks* hooks,
                                    v8::Local<v8::Context> context,
                                    v8::Local<v8::Value> api_object,
@@ -38,6 +40,7 @@
                                    const binding::RunJSFunction& run_js)
     : type_refs_(type_refs),
       request_handler_(request_handler),
+      event_handler_(event_handler),
       hooks_(hooks),
       extension_id_(extension_id),
       context_type_(context_type),
@@ -64,7 +67,9 @@
     v8::Isolate* isolate) {
   return Wrappable<APIBindingBridge>::GetObjectTemplateBuilder(isolate)
       .SetMethod("registerCustomHook", &APIBindingBridge::RegisterCustomHook)
-      .SetMethod("sendRequest", &APIBindingBridge::SendRequest);
+      .SetMethod("sendRequest", &APIBindingBridge::SendRequest)
+      .SetMethod("registerEventArgumentMassager",
+                 &APIBindingBridge::RegisterEventArgumentMassager);
 }
 
 void APIBindingBridge::RegisterCustomHook(v8::Isolate* isolate,
@@ -133,4 +138,17 @@
                                  hooks_->GetCustomJSCallback(name, context));
 }
 
+void APIBindingBridge::RegisterEventArgumentMassager(
+    gin::Arguments* arguments,
+    const std::string& event_name,
+    v8::Local<v8::Function> massager) {
+  v8::Isolate* isolate = arguments->isolate();
+  v8::HandleScope handle_scope(isolate);
+  v8::Local<v8::Object> holder;
+  CHECK(arguments->GetHolder(&holder));
+  v8::Local<v8::Context> context = holder->CreationContext();
+
+  event_handler_->RegisterArgumentMassager(context, event_name, massager);
+}
+
 }  // namespace extensions
diff --git a/extensions/renderer/api_binding_bridge.h b/extensions/renderer/api_binding_bridge.h
index 3a3fe64..30dd71b 100644
--- a/extensions/renderer/api_binding_bridge.h
+++ b/extensions/renderer/api_binding_bridge.h
@@ -18,6 +18,7 @@
 
 namespace extensions {
 class APIBindingHooks;
+class APIEventHandler;
 class APIRequestHandler;
 class APITypeReferenceMap;
 
@@ -28,6 +29,7 @@
  public:
   APIBindingBridge(const APITypeReferenceMap* type_refs,
                    APIRequestHandler* request_handler,
+                   APIEventHandler* event_handler,
                    APIBindingHooks* hooks,
                    v8::Local<v8::Context> context,
                    v8::Local<v8::Value> api_object,
@@ -60,12 +62,21 @@
                    const std::string& name,
                    const std::vector<v8::Local<v8::Value>>& request_args);
 
+  // A handler to register an argument massager for a specific event.
+  // Replacement for event_bindings.registerArgumentMassager.
+  void RegisterEventArgumentMassager(gin::Arguments* arguments,
+                                     const std::string& event_name,
+                                     v8::Local<v8::Function> massager);
+
   // Type references. Guaranteed to outlive this object.
   const APITypeReferenceMap* type_refs_;
 
   // The request handler. Guaranteed to outlive this object.
   APIRequestHandler* request_handler_;
 
+  // The event handler. Guaranteed to outlive this object.
+  APIEventHandler* event_handler_;
+
   // The hooks associated with this API. Guaranteed to outlive this object.
   APIBindingHooks* hooks_;
 
diff --git a/extensions/renderer/api_bindings_system.h b/extensions/renderer/api_bindings_system.h
index 5b78708d..2af8601 100644
--- a/extensions/renderer/api_bindings_system.h
+++ b/extensions/renderer/api_bindings_system.h
@@ -85,6 +85,7 @@
                           const CustomTypeHandler& function);
 
   APIRequestHandler* request_handler() { return &request_handler_; }
+  APIEventHandler* event_handler() { return &event_handler_; }
   APITypeReferenceMap* type_reference_map() { return &type_reference_map_; }
 
  private:
diff --git a/extensions/renderer/api_event_handler.cc b/extensions/renderer/api_event_handler.cc
index 2391607..d05e9e4 100644
--- a/extensions/renderer/api_event_handler.cc
+++ b/extensions/renderer/api_event_handler.cc
@@ -33,7 +33,7 @@
     // v8 objects. This helps us avoid cycles in v8 where an event listener
     // could hold a reference to the event, which in turn holds the reference
     // to the listener.
-    for (const auto& pair : event_data) {
+    for (const auto& pair : emitters) {
       EventEmitter* emitter = nullptr;
       gin::Converter<EventEmitter*>::FromV8(
           isolate, pair.second.Get(isolate), &emitter);
@@ -47,9 +47,59 @@
   v8::Isolate* isolate;
 
   // A map from event name -> event emitter.
-  std::map<std::string, v8::Global<v8::Object>> event_data;
+  std::map<std::string, v8::Global<v8::Object>> emitters;
+
+  // A map from event name -> argument massager.
+  std::map<std::string, v8::Global<v8::Function>> massagers;
 };
 
+APIEventPerContextData* GetContextData(v8::Local<v8::Context> context,
+                                       bool should_create) {
+  gin::PerContextData* per_context_data = gin::PerContextData::From(context);
+  if (!per_context_data)
+    return nullptr;
+  auto* data = static_cast<APIEventPerContextData*>(
+      per_context_data->GetUserData(kExtensionAPIEventPerContextKey));
+
+  if (!data && should_create) {
+    auto api_data =
+        base::MakeUnique<APIEventPerContextData>(context->GetIsolate());
+    data = api_data.get();
+    per_context_data->SetUserData(kExtensionAPIEventPerContextKey,
+                                  api_data.release());
+  }
+
+  return data;
+}
+
+void DispatchEvent(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  v8::Isolate* isolate = info.GetIsolate();
+  v8::HandleScope handle_scope(isolate);
+  if (info.Length() != 1 || !info[0]->IsArray()) {
+    NOTREACHED();
+    return;
+  }
+
+  v8::Local<v8::Context> context = isolate->GetCurrentContext();
+  APIEventPerContextData* data = GetContextData(context, false);
+  DCHECK(data);
+  std::string event_name = gin::V8ToString(info.Data());
+  auto iter = data->emitters.find(event_name);
+  if (iter == data->emitters.end())
+    return;
+  v8::Global<v8::Object>& v8_emitter = iter->second;
+
+  std::vector<v8::Local<v8::Value>> args;
+  CHECK(gin::Converter<std::vector<v8::Local<v8::Value>>>::FromV8(
+      isolate, info[0], &args));
+
+  EventEmitter* emitter = nullptr;
+  gin::Converter<EventEmitter*>::FromV8(isolate, v8_emitter.Get(isolate),
+                                        &emitter);
+  CHECK(emitter);
+  emitter->Fire(context, &args);
+}
+
 }  // namespace
 
 APIEventHandler::APIEventHandler(
@@ -67,19 +117,8 @@
   // context directly.
   v8::Context::Scope context_scope(context);
 
-  gin::PerContextData* per_context_data = gin::PerContextData::From(context);
-  DCHECK(per_context_data);
-  APIEventPerContextData* data = static_cast<APIEventPerContextData*>(
-      per_context_data->GetUserData(kExtensionAPIEventPerContextKey));
-  if (!data) {
-    auto api_data =
-        base::MakeUnique<APIEventPerContextData>(context->GetIsolate());
-    data = api_data.get();
-    per_context_data->SetUserData(kExtensionAPIEventPerContextKey,
-                                  api_data.release());
-  }
-
-  DCHECK(data->event_data.find(event_name) == data->event_data.end());
+  APIEventPerContextData* data = GetContextData(context, true);
+  DCHECK(data->emitters.find(event_name) == data->emitters.end());
 
   gin::Handle<EventEmitter> emitter_handle = gin::CreateHandle(
       context->GetIsolate(),
@@ -89,7 +128,7 @@
   CHECK(emitter_value->IsObject());
   v8::Local<v8::Object> emitter_object =
       v8::Local<v8::Object>::Cast(emitter_value);
-  data->event_data[event_name] =
+  data->emitters[event_name] =
       v8::Global<v8::Object>(context->GetIsolate(), emitter_object);
 
   return emitter_object;
@@ -98,46 +137,75 @@
 void APIEventHandler::FireEventInContext(const std::string& event_name,
                                          v8::Local<v8::Context> context,
                                          const base::ListValue& args) {
-  gin::PerContextData* per_context_data = gin::PerContextData::From(context);
-  DCHECK(per_context_data);
-  APIEventPerContextData* data = static_cast<APIEventPerContextData*>(
-      per_context_data->GetUserData(kExtensionAPIEventPerContextKey));
+  APIEventPerContextData* data = GetContextData(context, false);
   if (!data)
     return;
 
-  auto iter = data->event_data.find(event_name);
-  if (iter == data->event_data.end())
+  auto emitter_iter = data->emitters.find(event_name);
+  if (emitter_iter == data->emitters.end())
+    return;
+
+  EventEmitter* emitter = nullptr;
+  gin::Converter<EventEmitter*>::FromV8(
+      context->GetIsolate(), emitter_iter->second.Get(context->GetIsolate()),
+      &emitter);
+  CHECK(emitter);
+
+  if (emitter->listeners()->empty())
     return;
 
   // Note: since we only convert the arguments once, if a listener modifies an
   // object (including an array), other listeners will see that modification.
   // TODO(devlin): This is how it's always been, but should it be?
-  std::vector<v8::Local<v8::Value>> v8_args;
-  v8_args.reserve(args.GetSize());
   std::unique_ptr<content::V8ValueConverter> converter(
       content::V8ValueConverter::create());
-  for (const auto& arg : args)
-    v8_args.push_back(converter->ToV8Value(arg.get(), context));
 
-  EventEmitter* emitter = nullptr;
-  gin::Converter<EventEmitter*>::FromV8(
-      context->GetIsolate(), iter->second.Get(context->GetIsolate()), &emitter);
-  CHECK(emitter);
+  auto massager_iter = data->massagers.find(event_name);
+  if (massager_iter == data->massagers.end()) {
+    std::vector<v8::Local<v8::Value>> v8_args;
+    v8_args.reserve(args.GetSize());
+    for (const auto& arg : args)
+      v8_args.push_back(converter->ToV8Value(arg.get(), context));
+    emitter->Fire(context, &v8_args);
+  } else {
+    v8::Isolate* isolate = context->GetIsolate();
+    v8::HandleScope handle_scope(isolate);
+    v8::Local<v8::Function> massager = massager_iter->second.Get(isolate);
+    v8::Local<v8::Value> v8_args = converter->ToV8Value(&args, context);
+    DCHECK(!v8_args.IsEmpty());
+    DCHECK(v8_args->IsArray());
 
-  emitter->Fire(context, &v8_args);
+    // Curry in the native dispatch function. Some argument massagers take
+    // extra liberties and call this asynchronously, so we can't just have the
+    // massager return a modified array of arguments.
+    // We don't store this in a template because the Data (event name) is
+    // different for each instance. Luckily, this is called during dispatching
+    // an event, rather than e.g. at initialization time.
+    v8::Local<v8::Function> dispatch_event = v8::Function::New(
+        isolate, &DispatchEvent, gin::StringToSymbol(isolate, event_name));
+
+    v8::Local<v8::Value> massager_args[] = {v8_args, dispatch_event};
+    call_js_.Run(massager, context, arraysize(massager_args), massager_args);
+  }
+}
+
+void APIEventHandler::RegisterArgumentMassager(
+    v8::Local<v8::Context> context,
+    const std::string& event_name,
+    v8::Local<v8::Function> massager) {
+  APIEventPerContextData* data = GetContextData(context, true);
+  DCHECK(data->massagers.find(event_name) == data->massagers.end());
+  data->massagers[event_name].Reset(context->GetIsolate(), massager);
 }
 
 size_t APIEventHandler::GetNumEventListenersForTesting(
     const std::string& event_name,
     v8::Local<v8::Context> context) {
-  gin::PerContextData* per_context_data = gin::PerContextData::From(context);
-  DCHECK(per_context_data);
-  APIEventPerContextData* data = static_cast<APIEventPerContextData*>(
-      per_context_data->GetUserData(kExtensionAPIEventPerContextKey));
+  APIEventPerContextData* data = GetContextData(context, false);
   DCHECK(data);
 
-  auto iter = data->event_data.find(event_name);
-  DCHECK(iter != data->event_data.end());
+  auto iter = data->emitters.find(event_name);
+  DCHECK(iter != data->emitters.end());
   EventEmitter* emitter = nullptr;
   gin::Converter<EventEmitter*>::FromV8(
       context->GetIsolate(), iter->second.Get(context->GetIsolate()), &emitter);
diff --git a/extensions/renderer/api_event_handler.h b/extensions/renderer/api_event_handler.h
index fbf9b42a..36046c8 100644
--- a/extensions/renderer/api_event_handler.h
+++ b/extensions/renderer/api_event_handler.h
@@ -44,6 +44,15 @@
                           v8::Local<v8::Context> context,
                           const base::ListValue& arguments);
 
+  // Registers a |function| to serve as an "argument massager" for the given
+  // |event_name|, mutating the original arguments.
+  // The function is called with two arguments: the array of original arguments
+  // being dispatched to the event, and the function to dispatch the event to
+  // listeners.
+  void RegisterArgumentMassager(v8::Local<v8::Context> context,
+                                const std::string& event_name,
+                                v8::Local<v8::Function> function);
+
   // Returns the EventListeners for a given |event_name| and |context|.
   size_t GetNumEventListenersForTesting(const std::string& event_name,
                                         v8::Local<v8::Context> context);
diff --git a/extensions/renderer/api_event_handler_unittest.cc b/extensions/renderer/api_event_handler_unittest.cc
index e4d39d2..3846ecc 100644
--- a/extensions/renderer/api_event_handler_unittest.cc
+++ b/extensions/renderer/api_event_handler_unittest.cc
@@ -11,6 +11,7 @@
 #include "base/values.h"
 #include "extensions/renderer/api_binding_test.h"
 #include "extensions/renderer/api_binding_test_util.h"
+#include "gin/arguments.h"
 #include "gin/converter.h"
 #include "gin/public/context_holder.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -707,4 +708,156 @@
             handler.GetNumEventListenersForTesting(kEventName1, context_b));
 }
 
+// Test registering an argument massager for a given event.
+TEST_F(APIEventHandlerTest, TestArgumentMassagers) {
+  v8::HandleScope handle_scope(isolate());
+  v8::Local<v8::Context> context = ContextLocal();
+
+  const char kEventName[] = "alpha";
+  APIEventHandler handler(base::Bind(&RunFunctionOnGlobalAndIgnoreResult),
+                          base::Bind(&DoNothingOnEventListenersChanged));
+  v8::Local<v8::Object> event =
+      handler.CreateEventInstance(kEventName, context);
+  ASSERT_FALSE(event.IsEmpty());
+
+  const char kArgumentMassager[] =
+      "(function(originalArgs, dispatch) {\n"
+      "  this.originalArgs = originalArgs;\n"
+      "  dispatch(['primary', 'secondary']);\n"
+      "});";
+  v8::Local<v8::Function> massager =
+      FunctionFromString(context, kArgumentMassager);
+  handler.RegisterArgumentMassager(context, "alpha", massager);
+
+  const char kListenerFunction[] =
+      "(function() { this.eventArgs = Array.from(arguments); })";
+  v8::Local<v8::Function> listener_function =
+      FunctionFromString(context, kListenerFunction);
+  ASSERT_FALSE(listener_function.IsEmpty());
+
+  {
+    const char kAddListenerFunction[] =
+        "(function(event, listener) { event.addListener(listener); })";
+    v8::Local<v8::Function> add_listener_function =
+        FunctionFromString(context, kAddListenerFunction);
+    v8::Local<v8::Value> argv[] = {event, listener_function};
+    RunFunction(add_listener_function, context, arraysize(argv), argv);
+  }
+
+  const char kArguments[] = "['first','second']";
+  std::unique_ptr<base::ListValue> event_args = ListValueFromString(kArguments);
+  ASSERT_TRUE(event_args);
+  handler.FireEventInContext(kEventName, context, *event_args);
+
+  EXPECT_EQ(
+      "[\"first\",\"second\"]",
+      GetStringPropertyFromObject(context->Global(), context, "originalArgs"));
+  EXPECT_EQ(
+      "[\"primary\",\"secondary\"]",
+      GetStringPropertyFromObject(context->Global(), context, "eventArgs"));
+}
+
+// Test registering an argument massager for a given event and dispatching
+// asynchronously.
+TEST_F(APIEventHandlerTest, TestArgumentMassagersAsyncDispatch) {
+  v8::HandleScope handle_scope(isolate());
+  v8::Local<v8::Context> context = ContextLocal();
+
+  const char kEventName[] = "alpha";
+  APIEventHandler handler(base::Bind(&RunFunctionOnGlobalAndIgnoreResult),
+                          base::Bind(&DoNothingOnEventListenersChanged));
+  v8::Local<v8::Object> event =
+      handler.CreateEventInstance(kEventName, context);
+  ASSERT_FALSE(event.IsEmpty());
+
+  const char kArgumentMassager[] =
+      "(function(originalArgs, dispatch) {\n"
+      "  this.originalArgs = originalArgs;\n"
+      "  this.dispatch = dispatch;\n"
+      "});";
+  v8::Local<v8::Function> massager =
+      FunctionFromString(context, kArgumentMassager);
+  handler.RegisterArgumentMassager(context, "alpha", massager);
+
+  const char kListenerFunction[] =
+      "(function() { this.eventArgs = Array.from(arguments); })";
+  v8::Local<v8::Function> listener_function =
+      FunctionFromString(context, kListenerFunction);
+  ASSERT_FALSE(listener_function.IsEmpty());
+
+  {
+    const char kAddListenerFunction[] =
+        "(function(event, listener) { event.addListener(listener); })";
+    v8::Local<v8::Function> add_listener_function =
+        FunctionFromString(context, kAddListenerFunction);
+    v8::Local<v8::Value> argv[] = {event, listener_function};
+    RunFunction(add_listener_function, context, arraysize(argv), argv);
+  }
+
+  const char kArguments[] = "['first','second']";
+  std::unique_ptr<base::ListValue> event_args = ListValueFromString(kArguments);
+  ASSERT_TRUE(event_args);
+  handler.FireEventInContext(kEventName, context, *event_args);
+
+  // The massager should have been triggered, but since it doesn't call
+  // dispatch(), the listener shouldn't have been notified.
+  EXPECT_EQ(
+      "[\"first\",\"second\"]",
+      GetStringPropertyFromObject(context->Global(), context, "originalArgs"));
+  EXPECT_EQ("undefined", GetStringPropertyFromObject(context->Global(), context,
+                                                     "eventArgs"));
+
+  // Dispatch the event.
+  v8::Local<v8::Value> dispatch_value =
+      GetPropertyFromObject(context->Global(), context, "dispatch");
+  ASSERT_FALSE(dispatch_value.IsEmpty());
+  ASSERT_TRUE(dispatch_value->IsFunction());
+  v8::Local<v8::Value> dispatch_args[] = {
+      V8ValueFromScriptSource(context, "['primary', 'secondary']"),
+  };
+  RunFunction(dispatch_value.As<v8::Function>(), context,
+              arraysize(dispatch_args), dispatch_args);
+
+  EXPECT_EQ(
+      "[\"primary\",\"secondary\"]",
+      GetStringPropertyFromObject(context->Global(), context, "eventArgs"));
+}
+
+// Test registering an argument massager and never dispatching.
+TEST_F(APIEventHandlerTest, TestArgumentMassagersNeverDispatch) {
+  v8::HandleScope handle_scope(isolate());
+  v8::Local<v8::Context> context = ContextLocal();
+
+  const char kEventName[] = "alpha";
+  APIEventHandler handler(base::Bind(&RunFunctionOnGlobalAndIgnoreResult),
+                          base::Bind(&DoNothingOnEventListenersChanged));
+  v8::Local<v8::Object> event =
+      handler.CreateEventInstance(kEventName, context);
+  ASSERT_FALSE(event.IsEmpty());
+
+  // A massager that never dispatches.
+  const char kArgumentMassager[] = "(function(originalArgs, dispatch) {})";
+  v8::Local<v8::Function> massager =
+      FunctionFromString(context, kArgumentMassager);
+  handler.RegisterArgumentMassager(context, "alpha", massager);
+
+  const char kListenerFunction[] = "(function() {})";
+  v8::Local<v8::Function> listener_function =
+      FunctionFromString(context, kListenerFunction);
+  ASSERT_FALSE(listener_function.IsEmpty());
+
+  const char kAddListenerFunction[] =
+      "(function(event, listener) { event.addListener(listener); })";
+  v8::Local<v8::Function> add_listener_function =
+      FunctionFromString(context, kAddListenerFunction);
+  v8::Local<v8::Value> argv[] = {event, listener_function};
+  RunFunction(add_listener_function, context, arraysize(argv), argv);
+
+  handler.FireEventInContext(kEventName, context, base::ListValue());
+
+  // Nothing should blow up. (We tested in the previous test that the event
+  // isn't notified without calling dispatch, so all there is to test here is
+  // that we don't crash.)
+}
+
 }  // namespace extensions
diff --git a/extensions/renderer/argument_spec.cc b/extensions/renderer/argument_spec.cc
index c71e0e70..c46d320 100644
--- a/extensions/renderer/argument_spec.cc
+++ b/extensions/renderer/argument_spec.cc
@@ -228,9 +228,9 @@
       if (!enum_values_.empty() && enum_values_.count(s) == 0)
         return false;
       if (out_value) {
-        // TODO(devlin): If base::StringValue ever takes a std::string&&, we
+        // TODO(devlin): If base::Value ever takes a std::string&&, we
         // could use std::move to construct.
-        *out_value = base::MakeUnique<base::StringValue>(s);
+        *out_value = base::MakeUnique<base::Value>(s);
       }
       return true;
     }
diff --git a/extensions/renderer/native_extension_bindings_system.cc b/extensions/renderer/native_extension_bindings_system.cc
index 908d3c2..505f98e0 100644
--- a/extensions/renderer/native_extension_bindings_system.cc
+++ b/extensions/renderer/native_extension_bindings_system.cc
@@ -186,7 +186,8 @@
   gin::Handle<APIBindingBridge> bridge_handle = gin::CreateHandle(
       context->GetIsolate(),
       new APIBindingBridge(bindings_system->type_reference_map(),
-                           bindings_system->request_handler(), hooks, context,
+                           bindings_system->request_handler(),
+                           bindings_system->event_handler(), hooks, context,
                            binding_object, script_context->GetExtensionID(),
                            script_context->GetContextTypeDescription(),
                            base::Bind(&CallJsFunction)));
diff --git a/extensions/shell/browser/api/identity/identity_api.cc b/extensions/shell/browser/api/identity/identity_api.cc
index b2b057c..c1eccfd 100644
--- a/extensions/shell/browser/api/identity/identity_api.cc
+++ b/extensions/shell/browser/api/identity/identity_api.cc
@@ -127,7 +127,7 @@
 void IdentityGetAuthTokenFunction::OnMintTokenSuccess(
     const std::string& access_token,
     int time_to_live) {
-  Respond(OneArgument(base::MakeUnique<base::StringValue>(access_token)));
+  Respond(OneArgument(base::MakeUnique<base::Value>(access_token)));
   Release();  // Balanced in Run().
 }
 
diff --git a/extensions/test/extension_test_notification_observer.cc b/extensions/test/extension_test_notification_observer.cc
index 0e4d75d0c..8c79ac54 100644
--- a/extensions/test/extension_test_notification_observer.cc
+++ b/extensions/test/extension_test_notification_observer.cc
@@ -141,6 +141,9 @@
 void ExtensionTestNotificationObserver::Wait() {
   observer_->Wait();
 
+  // TODO(https://crbug.com/695073): Find out why tests fail without it.
+  content::RunAllPendingInMessageLoop();
+
   registrar_.RemoveAll();
   observer_.reset();
 }
@@ -187,16 +190,15 @@
     return;
   condition_ = condition;
 
-  scoped_refptr<content::MessageLoopRunner> runner(
-      new content::MessageLoopRunner);
-  quit_closure_ = runner->QuitClosure();
+  base::RunLoop run_loop;
+  quit_closure_ = run_loop.QuitClosure();
 
   std::unique_ptr<base::CallbackList<void()>::Subscription> subscription;
   if (notification_set) {
     subscription = notification_set->callback_list().Add(base::Bind(
         &ExtensionTestNotificationObserver::MaybeQuit, base::Unretained(this)));
   }
-  runner->Run();
+  run_loop.Run();
 
   condition_.Reset();
   quit_closure_.Reset();
diff --git a/gpu/ipc/service/gpu_command_buffer_stub.cc b/gpu/ipc/service/gpu_command_buffer_stub.cc
index ffa0a3c..bfa53ed 100644
--- a/gpu/ipc/service/gpu_command_buffer_stub.cc
+++ b/gpu/ipc/service/gpu_command_buffer_stub.cc
@@ -1093,12 +1093,10 @@
   DCHECK(waiting_for_sync_point_);
   TRACE_EVENT_ASYNC_END1("gpu", "WaitSyncTokenCompleted", this,
                          "GpuCommandBufferStub", this);
+  // Don't call PullTextureUpdates here because we can't MakeCurrent if we're
+  // executing commands on another context. The WaitSyncToken command will run
+  // again and call PullTextureUpdates once this command buffer gets scheduled.
   waiting_for_sync_point_ = false;
-
-  gles2::MailboxManager* mailbox_manager = context_group_->mailbox_manager();
-  if (mailbox_manager->UsesSync() && MakeCurrent())
-    mailbox_manager->PullTextureUpdates(sync_token);
-
   executor_->SetScheduled(true);
   channel_->OnStreamRescheduled(stream_id_, true);
 }
diff --git a/headless/lib/browser/devtools_api/domain_type_conversions_h.template b/headless/lib/browser/devtools_api/domain_type_conversions_h.template
index f14b423..15796eb 100644
--- a/headless/lib/browser/devtools_api/domain_type_conversions_h.template
+++ b/headless/lib/browser/devtools_api/domain_type_conversions_h.template
@@ -40,7 +40,7 @@
   switch (value) {
     {% for literal in type.enum %}
     case {{namespace}}::{{type.id}}::{{literal | sanitize_literal | dash_to_camelcase | camelcase_to_hacker_style | upper }}:
-      return base::WrapUnique(new base::StringValue("{{literal}}"));
+      return base::WrapUnique(new base::Value("{{literal}}"));
     {% endfor %}
   };
   NOTREACHED();
diff --git a/headless/public/internal/value_conversions.h b/headless/public/internal/value_conversions.h
index 948c94f..5622fb84 100644
--- a/headless/public/internal/value_conversions.h
+++ b/headless/public/internal/value_conversions.h
@@ -47,7 +47,7 @@
 
 template <typename T>
 std::unique_ptr<base::Value> ToValueImpl(const std::string& value, T*) {
-  return base::MakeUnique<base::StringValue>(value);
+  return base::MakeUnique<base::Value>(value);
 }
 
 template <typename T>
diff --git a/ios/chrome/browser/browser_state/BUILD.gn b/ios/chrome/browser/browser_state/BUILD.gn
index 94c58d8..6fcca06 100644
--- a/ios/chrome/browser/browser_state/BUILD.gn
+++ b/ios/chrome/browser/browser_state/BUILD.gn
@@ -14,6 +14,7 @@
     "//base",
     "//components/prefs",
     "//components/sync_preferences",
+    "//ios/chrome/browser/net:net_types",
     "//ios/chrome/browser/tabs",
     "//ios/web",
     "//net",
diff --git a/ios/chrome/browser/browser_state/chrome_browser_state.mm b/ios/chrome/browser/browser_state/chrome_browser_state.mm
index 5976860..c916d68 100644
--- a/ios/chrome/browser/browser_state/chrome_browser_state.mm
+++ b/ios/chrome/browser/browser_state/chrome_browser_state.mm
@@ -12,11 +12,11 @@
 #include "components/prefs/json_pref_store.h"
 #include "components/sync_preferences/pref_service_syncable.h"
 #include "ios/chrome/browser/chrome_url_constants.h"
-#include "ios/chrome/browser/net/ios_chrome_url_request_context_getter.h"
 #include "ios/web/public/web_state/web_state.h"
 #include "ios/web/public/web_thread.h"
 #include "ios/web/public/webui/web_ui_ios.h"
 #include "ios/web/webui/url_data_manager_ios_backend.h"
+#include "net/url_request/url_request_context_getter.h"
 #include "net/url_request/url_request_interceptor.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
diff --git a/ios/chrome/browser/content_suggestions/content_suggestions_coordinator.mm b/ios/chrome/browser/content_suggestions/content_suggestions_coordinator.mm
index 5104b68..e0cf332 100644
--- a/ios/chrome/browser/content_suggestions/content_suggestions_coordinator.mm
+++ b/ios/chrome/browser/content_suggestions/content_suggestions_coordinator.mm
@@ -6,9 +6,12 @@
 
 #include "base/mac/scoped_nsobject.h"
 #include "base/strings/sys_string_conversions.h"
+#include "components/ntp_snippets/content_suggestions_service.h"
+#include "components/ntp_snippets/remote/remote_suggestions_scheduler.h"
 #import "ios/chrome/browser/content_suggestions/content_suggestions_mediator.h"
 #include "ios/chrome/browser/ntp_snippets/ios_chrome_content_suggestions_service_factory.h"
 #import "ios/chrome/browser/ui/alert_coordinator/action_sheet_coordinator.h"
+#import "ios/chrome/browser/ui/content_suggestions/content_suggestion_identifier.h"
 #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_article_item.h"
 #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_commands.h"
 #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.h"
@@ -22,16 +25,21 @@
 #error "This file requires ARC support."
 #endif
 
-@interface ContentSuggestionsCoordinator ()<ContentSuggestionsCommands> {
-  ContentSuggestionsMediator* _contentSuggestionsMediator;
-}
+@interface ContentSuggestionsCoordinator ()<ContentSuggestionsCommands>
 
 @property(nonatomic, strong) AlertCoordinator* alertCoordinator;
 @property(nonatomic, strong) UINavigationController* navigationController;
 @property(nonatomic, strong)
     ContentSuggestionsViewController* suggestionsViewController;
+@property(nonatomic, strong)
+    ContentSuggestionsMediator* contentSuggestionsMediator;
 
+// Opens the |URL| in a new tab |incognito| or not.
 - (void)openNewTabWithURL:(const GURL&)URL incognito:(BOOL)incognito;
+// Dismisses the |article|, removing it from the content service, and dismisses
+// the item at |indexPath| in the view controller.
+- (void)dismissArticle:(ContentSuggestionsArticleItem*)article
+           atIndexPath:(NSIndexPath*)indexPath;
 
 @end
 
@@ -43,6 +51,7 @@
 @synthesize suggestionsViewController = _suggestionsViewController;
 @synthesize URLLoader = _URLLoader;
 @synthesize visible = _visible;
+@synthesize contentSuggestionsMediator = _contentSuggestionsMediator;
 
 - (void)start {
   if (self.visible || !self.browserState) {
@@ -53,13 +62,17 @@
 
   _visible = YES;
 
-  _contentSuggestionsMediator = [[ContentSuggestionsMediator alloc]
-      initWithContentService:IOSChromeContentSuggestionsServiceFactory::
-                                 GetForBrowserState(self.browserState)];
+  ntp_snippets::ContentSuggestionsService* contentSuggestionsService =
+      IOSChromeContentSuggestionsServiceFactory::GetForBrowserState(
+          self.browserState);
+  contentSuggestionsService->remote_suggestions_scheduler()->OnNTPOpened();
+
+  self.contentSuggestionsMediator = [[ContentSuggestionsMediator alloc]
+      initWithContentService:contentSuggestionsService];
 
   self.suggestionsViewController = [[ContentSuggestionsViewController alloc]
       initWithStyle:CollectionViewControllerStyleDefault
-         dataSource:_contentSuggestionsMediator];
+         dataSource:self.contentSuggestionsMediator];
 
   self.suggestionsViewController.suggestionCommandHandler = self;
   _navigationController = [[UINavigationController alloc]
@@ -82,6 +95,7 @@
       dismissViewControllerAnimated:YES
                          completion:nil];
   self.navigationController = nil;
+  self.contentSuggestionsMediator = nil;
   _visible = NO;
 }
 
@@ -108,7 +122,8 @@
 }
 
 - (void)displayContextMenuForArticle:(ContentSuggestionsArticleItem*)articleItem
-                             atPoint:(CGPoint)touchLocation {
+                             atPoint:(CGPoint)touchLocation
+                         atIndexPath:(NSIndexPath*)indexPath {
   NSString* urlString = base::SysUTF8ToNSString(articleItem.articleURL.spec());
   self.alertCoordinator = [[ActionSheetCoordinator alloc]
       initWithBaseViewController:self.navigationController
@@ -120,6 +135,7 @@
 
   __weak ContentSuggestionsCoordinator* weakSelf = self;
   GURL articleURL = articleItem.articleURL;
+  __weak ContentSuggestionsArticleItem* weakArticle = articleItem;
 
   NSString* openInNewTabTitle =
       l10n_util::GetNSString(IDS_IOS_CONTENT_CONTEXT_OPENLINKNEWTAB);
@@ -146,7 +162,8 @@
   [self.alertCoordinator addItemWithTitle:deleteTitle
                                    action:^{
                                      // TODO(crbug.com/691979): Add metrics.
-                                     [weakSelf removeEntry];
+                                     [weakSelf dismissArticle:weakArticle
+                                                  atIndexPath:indexPath];
                                    }
                                     style:UIAlertActionStyleDefault];
 
@@ -173,8 +190,15 @@
   [self stop];
 }
 
-- (void)removeEntry {
+- (void)dismissArticle:(ContentSuggestionsArticleItem*)article
+           atIndexPath:(NSIndexPath*)indexPath {
+  if (!article)
+    return;
+
   // TODO(crbug.com/691979): Add metrics.
+  [self.contentSuggestionsMediator
+      dismissSuggestion:article.suggestionIdentifier];
+  [self.suggestionsViewController dismissEntryAtIndexPath:indexPath];
 }
 
 @end
diff --git a/ios/chrome/browser/content_suggestions/content_suggestions_mediator.h b/ios/chrome/browser/content_suggestions/content_suggestions_mediator.h
index f53553a..11394aa 100644
--- a/ios/chrome/browser/content_suggestions/content_suggestions_mediator.h
+++ b/ios/chrome/browser/content_suggestions/content_suggestions_mediator.h
@@ -14,6 +14,8 @@
 class ContentSuggestionsService;
 }
 
+@class ContentSuggestionIdentifier;
+
 // Mediator for ContentSuggestions. Makes the interface between a
 // ntp_snippets::ContentSuggestionsService and the Objective-C services using
 // its data.
@@ -25,6 +27,10 @@
     NS_DESIGNATED_INITIALIZER;
 - (instancetype)init NS_UNAVAILABLE;
 
+// Dismisses the suggestion from the content suggestions service. It doesn't
+// change the UI.
+- (void)dismissSuggestion:(ContentSuggestionIdentifier*)suggestionIdentifier;
+
 @end
 
 #endif  // IOS_CHROME_BROWSER_CONTENT_SUGGESTIONS_CONTENT_SUGGESTIONS_MEDIATOR_H_
diff --git a/ios/chrome/browser/content_suggestions/content_suggestions_mediator.mm b/ios/chrome/browser/content_suggestions/content_suggestions_mediator.mm
index 55e62e62..52b7c7c 100644
--- a/ios/chrome/browser/content_suggestions/content_suggestions_mediator.mm
+++ b/ios/chrome/browser/content_suggestions/content_suggestions_mediator.mm
@@ -133,6 +133,8 @@
 @synthesize dataSink = _dataSink;
 @synthesize sectionInformationByCategory = _sectionInformationByCategory;
 
+#pragma mark - Public
+
 - (instancetype)initWithContentService:
     (ntp_snippets::ContentSuggestionsService*)contentService {
   self = [super init];
@@ -145,6 +147,16 @@
   return self;
 }
 
+- (void)dismissSuggestion:(ContentSuggestionIdentifier*)suggestionIdentifier {
+  ContentSuggestionsCategoryWrapper* categoryWrapper =
+      [self categoryWrapperForSectionInfo:suggestionIdentifier.sectionInfo];
+  ntp_snippets::ContentSuggestion::ID suggestion_id =
+      ntp_snippets::ContentSuggestion::ID([categoryWrapper category],
+                                          suggestionIdentifier.IDInSection);
+
+  self.contentService->DismissSuggestion(suggestion_id);
+}
+
 #pragma mark - ContentSuggestionsDataSource
 
 - (NSArray<ContentSuggestion*>*)allSuggestions {
diff --git a/ios/chrome/browser/native_app_launcher/BUILD.gn b/ios/chrome/browser/native_app_launcher/BUILD.gn
index f873d674d..b312559 100644
--- a/ios/chrome/browser/native_app_launcher/BUILD.gn
+++ b/ios/chrome/browser/native_app_launcher/BUILD.gn
@@ -92,6 +92,7 @@
     "//base/test:test_support",
     "//components/infobars/core",
     "//ios/chrome/browser",
+    "//ios/chrome/browser/infobars:infobars",
     "//ios/chrome/browser/web:test_support",
     "//ios/chrome/test:test_support",
     "//ios/public/provider/chrome/browser",
diff --git a/ios/chrome/browser/native_app_launcher/DEPS b/ios/chrome/browser/native_app_launcher/DEPS
index eb9956d..1c40ab5f 100644
--- a/ios/chrome/browser/native_app_launcher/DEPS
+++ b/ios/chrome/browser/native_app_launcher/DEPS
@@ -5,7 +5,4 @@
     "+ios/web/navigation/navigation_manager_impl.h",
     "+ios/web/web_state/web_state_impl.h",
   ],
-  "^native_app_navigation_controller\.mm$": [
-    "+ios/web/web_state/ui/crw_web_controller.h",
-  ],
 }
diff --git a/ios/chrome/browser/native_app_launcher/native_app_navigation_controller.h b/ios/chrome/browser/native_app_launcher/native_app_navigation_controller.h
index a343b9e..3beb9c6 100644
--- a/ios/chrome/browser/native_app_launcher/native_app_navigation_controller.h
+++ b/ios/chrome/browser/native_app_launcher/native_app_navigation_controller.h
@@ -7,9 +7,6 @@
 
 #import <Foundation/Foundation.h>
 
-#import "ios/chrome/browser/native_app_launcher/native_app_navigation_controller_protocol.h"
-#import "ios/web/public/web_state/crw_web_controller_observer.h"
-
 @class Tab;
 
 namespace net {
@@ -23,8 +20,7 @@
 // NativeAppNavigationController brings up a GAL Infobar if the webpage directs
 // it to do so and there are no other circumstances that would suppress its
 // display.
-@interface NativeAppNavigationController
-    : NSObject<CRWWebControllerObserver, NativeAppNavigationControllerProtocol>
+@interface NativeAppNavigationController : NSObject
 
 // Designated initializer. The use of |tab| will be phased out in the future
 // when all the information needed can be fulfilled by |webState|. Use this
diff --git a/ios/chrome/browser/native_app_launcher/native_app_navigation_controller.mm b/ios/chrome/browser/native_app_launcher/native_app_navigation_controller.mm
index 0db2759..3e6a784 100644
--- a/ios/chrome/browser/native_app_launcher/native_app_navigation_controller.mm
+++ b/ios/chrome/browser/native_app_launcher/native_app_navigation_controller.mm
@@ -15,6 +15,7 @@
 #include "ios/chrome/browser/infobars/infobar_manager_impl.h"
 #import "ios/chrome/browser/installation_notifier.h"
 #include "ios/chrome/browser/native_app_launcher/native_app_infobar_delegate.h"
+#import "ios/chrome/browser/native_app_launcher/native_app_navigation_controller_protocol.h"
 #include "ios/chrome/browser/native_app_launcher/native_app_navigation_util.h"
 #import "ios/chrome/browser/open_url_util.h"
 #import "ios/chrome/browser/tabs/tab.h"
@@ -23,8 +24,8 @@
 #import "ios/public/provider/chrome/browser/native_app_launcher/native_app_types.h"
 #import "ios/public/provider/chrome/browser/native_app_launcher/native_app_whitelist_manager.h"
 #include "ios/web/public/web_state/web_state.h"
+#import "ios/web/public/web_state/web_state_observer_bridge.h"
 #include "ios/web/public/web_thread.h"
-#import "ios/web/web_state/ui/crw_web_controller.h"
 #import "net/base/mac/url_conversions.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
@@ -33,7 +34,9 @@
 
 using base::UserMetricsAction;
 
-@interface NativeAppNavigationController ()
+@interface NativeAppNavigationController ()<
+    CRWWebStateObserver,
+    NativeAppNavigationControllerProtocol>
 // Shows a native app infobar by looking at the page's URL and by checking
 // wheter that infobar should be bypassed or not.
 - (void)showInfoBarIfNecessary;
@@ -60,6 +63,8 @@
   id<NativeAppMetadata> _metadata;
   // A set of appIds encoded as NSStrings.
   NSMutableSet* _appsPossiblyBeingInstalled;
+  // Allows this class to subscribe for CRWWebStateObserver callbacks.
+  std::unique_ptr<web::WebStateObserverBridge> _webStateObserver;
 }
 
 // Designated initializer. Use this instead of -init.
@@ -78,6 +83,8 @@
     DCHECK(!tab || [tab webState] == webState);
     _tab = tab;
     _appsPossiblyBeingInstalled = [[NSMutableSet alloc] init];
+    _webStateObserver =
+        base::MakeUnique<web::WebStateObserverBridge>(webState, self);
   }
   return self;
 }
@@ -159,8 +166,7 @@
   }
 }
 
-#pragma mark -
-#pragma mark NativeAppNavigationControllerProtocol methods
+#pragma mark - NativeAppNavigationControllerProtocol methods
 
 - (NSString*)appId {
   return [_metadata appId];
@@ -206,18 +212,20 @@
   [_metadata updateWithUserAction:userAction];
 }
 
-#pragma mark -
-#pragma mark CRWWebControllerObserver methods
+#pragma mark - CRWWebStateObserver methods
 
-- (void)pageLoaded:(CRWWebController*)webController {
-  if (![_tab isPrerenderTab])
+- (void)webState:(web::WebState*)webState didLoadPageWithSuccess:(BOOL)success {
+  if (success && ![_tab isPrerenderTab])
     [self showInfoBarIfNecessary];
 }
 
-- (void)webControllerWillClose:(CRWWebController*)webController {
-  [webController removeObserver:self];
+- (void)webStateDestroyed:(web::WebState*)webState {
+  _webState = nullptr;
+  _webStateObserver.reset();
 }
 
+#pragma mark - Private methods
+
 - (void)appDidInstall:(NSNotification*)notification {
   [self removeAppFromNotification:notification];
   [self showInfoBarIfNecessary];
diff --git a/ios/chrome/browser/native_app_launcher/native_app_navigation_controller_unittest.mm b/ios/chrome/browser/native_app_launcher/native_app_navigation_controller_unittest.mm
index 695085c4..aa23143 100644
--- a/ios/chrome/browser/native_app_launcher/native_app_navigation_controller_unittest.mm
+++ b/ios/chrome/browser/native_app_launcher/native_app_navigation_controller_unittest.mm
@@ -8,6 +8,8 @@
 #include "base/mac/scoped_nsobject.h"
 #include "base/memory/ptr_util.h"
 #include "base/metrics/user_metrics.h"
+#include "base/strings/utf_string_conversions.h"
+#include "ios/chrome/browser/infobars/infobar_manager_impl.h"
 #import "ios/chrome/browser/installation_notifier.h"
 #include "ios/chrome/browser/native_app_launcher/native_app_infobar_delegate.h"
 #import "ios/chrome/browser/native_app_launcher/native_app_navigation_controller.h"
@@ -16,6 +18,7 @@
 #import "ios/public/provider/chrome/browser/native_app_launcher/fake_native_app_metadata.h"
 #import "ios/public/provider/chrome/browser/native_app_launcher/fake_native_app_whitelist_manager.h"
 #include "ios/public/provider/chrome/browser/test_chrome_browser_provider.h"
+#import "testing/gtest_mac.h"
 
 @interface NativeAppNavigationController (Testing)
 - (void)recordInfobarDisplayedOfType:(NativeAppControllerType)type
@@ -117,6 +120,43 @@
   ExpectHandlerCalledAndReset(1);
 }
 
+// Tests presenting NativeAppInfoBar after page is loaded.
+TEST_F(NativeAppNavigationControllerTest, NativeAppInfoBar) {
+  SetExpectedActionName("MobileGALInstallInfoBarDirectNavigation");
+  InfoBarManagerImpl::CreateForWebState(web_state());
+
+  // Set up fake metadata.
+  FakeNativeAppWhitelistManager* fakeManager =
+      [[[FakeNativeAppWhitelistManager alloc] init] autorelease];
+  IOSChromeScopedTestingChromeBrowserProvider provider(
+      base::MakeUnique<FakeChromeBrowserProvider>(fakeManager));
+  FakeNativeAppMetadata* metadata =
+      [[[FakeNativeAppMetadata alloc] init] autorelease];
+  fakeManager.metadata = metadata;
+  metadata.appName = @"App";
+  metadata.appId = @"App-ID";
+
+  // Load the page to trigger infobar presentation.
+  LoadHtml(@"<html><body></body></html>", GURL("http://test.com"));
+
+  // Verify that infobar was presented
+  auto* infobar_manager = InfoBarManagerImpl::FromWebState(web_state());
+  ASSERT_EQ(1U, infobar_manager->infobar_count());
+  infobars::InfoBar* infobar = infobar_manager->infobar_at(0);
+  auto* delegate = infobar->delegate()->AsNativeAppInfoBarDelegate();
+  ASSERT_TRUE(delegate);
+
+  // Verify infobar appearance.
+  EXPECT_EQ("Open this page in the App app?",
+            base::UTF16ToUTF8(delegate->GetInstallText()));
+  EXPECT_EQ("Open this page in the App app?",
+            base::UTF16ToUTF8(delegate->GetLaunchText()));
+  EXPECT_EQ("Open in App", base::UTF16ToUTF8(delegate->GetOpenPolicyText()));
+  EXPECT_EQ("Just once", base::UTF16ToUTF8(delegate->GetOpenOnceText()));
+  EXPECT_EQ("Always", base::UTF16ToUTF8(delegate->GetOpenAlwaysText()));
+  EXPECT_NSEQ(@"App-ID", delegate->GetAppId());
+}
+
 TEST_F(NativeAppNavigationControllerTest,
        TestRemovingAppFromListAfterInstallation) {
   NSString* const kMapsAppName = @"Maps";
diff --git a/ios/chrome/browser/net/BUILD.gn b/ios/chrome/browser/net/BUILD.gn
index 2d147eb..c581c598 100644
--- a/ios/chrome/browser/net/BUILD.gn
+++ b/ios/chrome/browser/net/BUILD.gn
@@ -21,7 +21,6 @@
     "ios_chrome_network_delegate.h",
     "ios_chrome_url_request_context_getter.cc",
     "ios_chrome_url_request_context_getter.h",
-    "net_types.h",
     "proxy_service_factory.cc",
     "proxy_service_factory.h",
     "retryable_url_fetcher.h",
@@ -44,10 +43,21 @@
     "//net:extras",
     "//url",
   ]
-  allow_circular_includes_from = [
-    "//ios/chrome/browser",
-    "//ios/chrome/browser/browser_state",
+  public_deps = [
+    ":net_types",
   ]
+  allow_circular_includes_from = [ "//ios/chrome/browser" ]
+}
+
+source_set("net_types") {
+  sources = [
+    "net_types.h",
+  ]
+  deps = [
+    "//base",
+    "//net",
+  ]
+  configs += [ "//build/config/compiler:enable_arc" ]
 }
 
 source_set("unit_tests") {
diff --git a/ios/chrome/browser/tabs/tab.mm b/ios/chrome/browser/tabs/tab.mm
index 5b58935..7d91c95 100644
--- a/ios/chrome/browser/tabs/tab.mm
+++ b/ios/chrome/browser/tabs/tab.mm
@@ -2199,7 +2199,6 @@
           initWithWebState:self.webState
       requestContextGetter:browserState_->GetRequestContext()
                        tab:self]);
-  [self.webController addObserver:nativeAppNavigationController_];
   DCHECK(nativeAppNavigationController_);
 }
 
diff --git a/ios/chrome/browser/ui/DEPS b/ios/chrome/browser/ui/DEPS
index fa03c9a..0a1586ac 100644
--- a/ios/chrome/browser/ui/DEPS
+++ b/ios/chrome/browser/ui/DEPS
@@ -8,7 +8,6 @@
   # TODO(crbug.com/620489): Remove these exceptions.
   "^browser_view_controller\.mm$": [
     "+ios/web/navigation/crw_session_controller.h",
-    "+ios/web/navigation/crw_session_entry.h",
     "+ios/web/navigation/navigation_manager_impl.h",
     "+ios/web/web_state/ui/crw_web_controller.h",
   ],
diff --git a/ios/chrome/browser/ui/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view_controller.mm
index 6e441ea..c97d780 100644
--- a/ios/chrome/browser/ui/browser_view_controller.mm
+++ b/ios/chrome/browser/ui/browser_view_controller.mm
@@ -172,7 +172,6 @@
 #include "ios/public/provider/chrome/browser/voice/voice_search_controller_delegate.h"
 #include "ios/public/provider/chrome/browser/voice/voice_search_provider.h"
 #import "ios/web/navigation/crw_session_controller.h"
-#import "ios/web/navigation/crw_session_entry.h"
 #include "ios/web/navigation/navigation_manager_impl.h"
 #include "ios/web/public/active_state_manager.h"
 #include "ios/web/public/navigation_item.h"
@@ -1918,11 +1917,10 @@
 
   // Hide the toolbar if displaying phone NTP.
   if (!IsIPadIdiom()) {
-    CRWSessionEntry* entry =
-        [[tab navigationManagerImpl]->GetSessionController() currentEntry];
+    web::NavigationItem* item = [tab navigationManager]->GetVisibleItem();
     BOOL hideToolbar = NO;
-    if (entry) {
-      GURL url = [entry navigationItem]->GetURL();
+    if (item) {
+      GURL url = item->GetURL();
       BOOL isNTP = url.GetOrigin() == GURL(kChromeUINewTabURL);
       hideToolbar = isNTP && !_isOffTheRecord &&
                     ![_toolbarController isOmniboxFirstResponder] &&
@@ -3380,7 +3378,7 @@
   CRWSessionController* sc =
       [tab navigationManagerImpl]->GetSessionController();
   [_toolbarController showTabHistoryPopupInView:[self view]
-                             withSessionEntries:[sc backwardEntries]
+                                      withItems:[sc backwardItems]
                                  forBackHistory:YES];
 }
 
@@ -3397,14 +3395,14 @@
   CRWSessionController* sc =
       [tab navigationManagerImpl]->GetSessionController();
   [_toolbarController showTabHistoryPopupInView:[self view]
-                             withSessionEntries:[sc forwardEntries]
+                                      withItems:[sc forwardItems]
                                  forBackHistory:NO];
 }
 
 - (void)navigateToSelectedEntry:(id)sender {
   DCHECK([sender isKindOfClass:[TabHistoryCell class]]);
   TabHistoryCell* selectedCell = (TabHistoryCell*)sender;
-  [[_model currentTab] goToItem:selectedCell.entry.navigationItem];
+  [[_model currentTab] goToItem:selectedCell.item];
   [_toolbarController dismissTabHistoryPopup];
 }
 
@@ -4816,13 +4814,6 @@
   return [_model currentTab].usesDesktopUserAgent;
 }
 
-- (CRWSessionEntry*)currentSessionEntry {
-  Tab* tab = [_model currentTab];
-  if (![tab navigationManager])
-    return nil;
-  return [[tab navigationManagerImpl]->GetSessionController() currentEntry];
-}
-
 #pragma mark - BookmarkBridgeMethods
 
 // If an added or removed bookmark is the same as the current url, update the
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_article_item.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_article_item.mm
index 2ee2912..ecc4581 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_article_item.mm
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_article_item.mm
@@ -56,16 +56,16 @@
     _subtitle = [subtitle copy];
     _articleURL = url;
     _delegate = delegate;
+    _image = [self emptyImageBackground];
   }
   return self;
 }
 
 - (void)configureCell:(ContentSuggestionsArticleCell*)cell {
   [super configureCell:cell];
-  if (!self.image && !self.imageFetched) {
+  if (!self.imageFetched) {
     self.imageFetched = YES;
-    // Fetch the image. During the fetch the cell's image should still be set to
-    // nil.
+    // Fetch the image. During the fetch the cell's image should still be set.
     [self.delegate loadImageForArticleItem:self];
   }
   cell.titleLabel.text = self.title;
@@ -74,6 +74,21 @@
   [cell setPublisherName:self.publisher date:self.publishDate];
 }
 
+#pragma mark - Private
+
+- (UIImage*)emptyImageBackground {
+  // TODO(crbug.com/698171): Remove this function once we have real background
+  // image.
+  UIColor* color = [UIColor lightGrayColor];
+  CGRect rect = CGRectMake(0, 0, 1, 1);
+  UIGraphicsBeginImageContext(rect.size);
+  [color setFill];
+  UIRectFill(rect);
+  UIImage* image = UIGraphicsGetImageFromCurrentImageContext();
+  UIGraphicsEndImageContext();
+  return image;
+}
+
 @end
 
 #pragma mark - ContentSuggestionsArticleCell
@@ -156,9 +171,9 @@
   CGFloat parentWidth = CGRectGetWidth(self.contentView.bounds);
 
   self.titleLabel.preferredMaxLayoutWidth =
-      parentWidth - self.imageView.bounds.size.width - 3 * kStandardSpacing;
+      parentWidth - kImageSize - 3 * kStandardSpacing;
   self.subtitleLabel.preferredMaxLayoutWidth =
-      parentWidth - self.imageView.bounds.size.width - 3 * kStandardSpacing;
+      parentWidth - kImageSize - 3 * kStandardSpacing;
 
   // Re-layout with the new preferred width to allow the label to adjust its
   // height.
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_article_item_unittest.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_article_item_unittest.mm
index b8c0003..f0b5063 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_article_item_unittest.mm
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_article_item_unittest.mm
@@ -34,47 +34,18 @@
   ContentSuggestionsArticleCell* cell = [[[item cellClass] alloc] init];
   ASSERT_EQ([ContentSuggestionsArticleCell class], [cell class]);
   ASSERT_EQ(url, item.articleURL);
-  ASSERT_EQ(nil, item.image);
+  ASSERT_NE(nil, item.image);
 
   // Action.
   [item configureCell:cell];
 
   // Tests.
-  EXPECT_EQ(nil, cell.imageView.image);
+  EXPECT_EQ(item.image, cell.imageView.image);
   EXPECT_EQ(title, cell.titleLabel.text);
   EXPECT_EQ(subtitle, cell.subtitleLabel.text);
   EXPECT_OCMOCK_VERIFY(delegateMock);
 }
 
-// Tests that configureCell: set all the fields of the cell with an image and
-// does not call the delegate.
-TEST(ContentSuggestionsArticleItemTest, CellIsConfiguredWithImage) {
-  // Setup.
-  NSString* title = @"testTitle";
-  NSString* subtitle = @"testSubtitle";
-  UIImage* image = [[UIImage alloc] init];
-  GURL url = GURL("http://chromium.org");
-  id delegateMock =
-      OCMStrictProtocolMock(@protocol(ContentSuggestionsArticleItemDelegate));
-  ContentSuggestionsArticleItem* item =
-      [[ContentSuggestionsArticleItem alloc] initWithType:0
-                                                    title:title
-                                                 subtitle:subtitle
-                                                 delegate:delegateMock
-                                                      url:url];
-  item.image = image;
-  ContentSuggestionsArticleCell* cell = [[[item cellClass] alloc] init];
-
-  // Action.
-  [item configureCell:cell];
-
-  // Tests.
-  EXPECT_EQ(image, cell.imageView.image);
-  EXPECT_EQ(title, cell.titleLabel.text);
-  EXPECT_EQ(subtitle, cell.subtitleLabel.text);
-  EXPECT_EQ(image, cell.imageView.image);
-}
-
 // Tests that configureCell: does not call the delegate if it fetched the image
 // once.
 TEST(ContentSuggestionsArticleItemTest, DontFetchImageIsImageIsBeingFetched) {
@@ -93,7 +64,7 @@
 
   OCMExpect([niceDelegateMock loadImageForArticleItem:item]);
   ContentSuggestionsArticleCell* cell = [[[item cellClass] alloc] init];
-  ASSERT_EQ(nil, item.image);
+  ASSERT_NE(nil, item.image);
   [item configureCell:cell];
   ASSERT_OCMOCK_VERIFY(niceDelegateMock);
 
@@ -105,7 +76,7 @@
   [item configureCell:cell];
 
   // Tests.
-  EXPECT_EQ(nil, cell.imageView.image);
+  EXPECT_EQ(item.image, cell.imageView.image);
   EXPECT_EQ(title, cell.titleLabel.text);
   EXPECT_EQ(subtitle, cell.subtitleLabel.text);
 }
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_commands.h b/ios/chrome/browser/ui/content_suggestions/content_suggestions_commands.h
index 7c11505..b874e51 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_commands.h
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_commands.h
@@ -21,7 +21,8 @@
 - (void)openURL:(const GURL&)URL;
 // Displays a context menu for opening the |articleItem|.
 - (void)displayContextMenuForArticle:(ContentSuggestionsArticleItem*)articleItem
-                             atPoint:(CGPoint)touchLocation;
+                             atPoint:(CGPoint)touchLocation
+                         atIndexPath:(NSIndexPath*)indexPath;
 
 @end
 
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.h b/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.h
index e25bdb9..997f569 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.h
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.h
@@ -30,6 +30,9 @@
 @property(nonatomic, weak) id<ContentSuggestionsCommands>
     suggestionCommandHandler;
 
+// Removes the entry at |indexPath|, from the collection and its model.
+- (void)dismissEntryAtIndexPath:(NSIndexPath*)indexPath;
+
 @end
 
 #endif  // IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CONTENT_SUGGESTIONS_VIEW_CONTROLLER_H_
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm
index 3fb509f..3754aa9f 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm
@@ -41,6 +41,8 @@
 @synthesize suggestionCommandHandler = _suggestionCommandHandler;
 @synthesize collectionUpdater = _collectionUpdater;
 
+#pragma mark - Public
+
 - (instancetype)initWithStyle:(CollectionViewControllerStyle)style
                    dataSource:(id<ContentSuggestionsDataSource>)dataSource {
   self = [super initWithStyle:style];
@@ -51,6 +53,20 @@
   return self;
 }
 
+- (void)dismissEntryAtIndexPath:(NSIndexPath*)indexPath {
+  if (!indexPath || ![self.collectionViewModel hasItemAtIndexPath:indexPath]) {
+    return;
+  }
+
+  [self.collectionView performBatchUpdates:^{
+    [self collectionView:self.collectionView
+        willDeleteItemsAtIndexPaths:@[ indexPath ]];
+
+    [self.collectionView deleteItemsAtIndexPaths:@[ indexPath ]];
+  }
+                                completion:nil];
+}
+
 #pragma mark - UIViewController
 
 - (void)viewDidLoad {
@@ -197,8 +213,10 @@
   ContentSuggestionsArticleItem* articleItem =
       base::mac::ObjCCastStrict<ContentSuggestionsArticleItem>(touchedItem);
 
-  [self.suggestionCommandHandler displayContextMenuForArticle:articleItem
-                                                      atPoint:touchLocation];
+  [self.suggestionCommandHandler
+      displayContextMenuForArticle:articleItem
+                           atPoint:touchLocation
+                       atIndexPath:touchedItemIndexPath];
 }
 
 @end
diff --git a/ios/chrome/browser/ui/history/BUILD.gn b/ios/chrome/browser/ui/history/BUILD.gn
index 8926439..74da394 100644
--- a/ios/chrome/browser/ui/history/BUILD.gn
+++ b/ios/chrome/browser/ui/history/BUILD.gn
@@ -210,6 +210,7 @@
     "//components/browsing_data/core",
     "//components/prefs",
     "//components/strings",
+    "//components/url_formatter:url_formatter",
     "//ios/chrome/app/strings",
     "//ios/chrome/browser",
     "//ios/chrome/browser/browser_state",
diff --git a/ios/chrome/browser/ui/history/DEPS b/ios/chrome/browser/ui/history/DEPS
deleted file mode 100644
index cb80df7..0000000
--- a/ios/chrome/browser/ui/history/DEPS
+++ /dev/null
@@ -1,15 +0,0 @@
-specific_include_rules = {
-  # TODO(crbug.com/620907): Remove these exceptions.
-  "^tab_history_cell\.mm$": [
-    "+ios/web/navigation/crw_session_entry.h",
-  ],
-  "tab_history_popup_controller.mm": [
-    "+ios/web/navigation/crw_session_entry.h",
-  ],
-  "tab_history_popup_controller_unittest.mm": [
-    "+ios/web/navigation/crw_session_entry.h",
-  ],
-  "tab_history_view_controller.mm": [
-    "+ios/web/navigation/crw_session_entry.h",
-  ],
-}
diff --git a/ios/chrome/browser/ui/history/tab_history_cell.h b/ios/chrome/browser/ui/history/tab_history_cell.h
index 745a9d5d..590e037f 100644
--- a/ios/chrome/browser/ui/history/tab_history_cell.h
+++ b/ios/chrome/browser/ui/history/tab_history_cell.h
@@ -7,18 +7,20 @@
 
 #import <UIKit/UIKit.h>
 
-@class CRWSessionEntry;
+namespace web {
+class NavigationItem;
+}
 
 // Table cell used in TabHistoryViewController.
 @interface TabHistoryCell : UICollectionViewCell
-@property(strong, nonatomic) CRWSessionEntry* entry;
-@property(weak, nonatomic, readonly) UILabel* titleLabel;
+@property(assign, nonatomic) const web::NavigationItem* item;
+@property(strong, nonatomic, readonly) UILabel* titleLabel;
 @end
 
 // Header for a section of TabHistoryCells.
 @interface TabHistorySectionHeader : UICollectionReusableView
-@property(weak, nonatomic, readonly) UIImageView* iconView;
-@property(weak, nonatomic, readonly) UIView* lineView;
+@property(strong, nonatomic, readonly) UIImageView* iconView;
+@property(strong, nonatomic, readonly) UIView* lineView;
 @end
 
 // Footer for a section of TabHistoryCells.
diff --git a/ios/chrome/browser/ui/history/tab_history_cell.mm b/ios/chrome/browser/ui/history/tab_history_cell.mm
index 2d34024..b2d708a 100644
--- a/ios/chrome/browser/ui/history/tab_history_cell.mm
+++ b/ios/chrome/browser/ui/history/tab_history_cell.mm
@@ -8,7 +8,6 @@
 #include "ios/chrome/browser/ui/ui_util.h"
 #import "ios/chrome/browser/ui/uikit_ui_util.h"
 #import "ios/third_party/material_roboto_font_loader_ios/src/src/MaterialRobotoFontLoader.h"
-#import "ios/web/navigation/crw_session_entry.h"
 #include "ios/web/public/navigation_item.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
@@ -42,10 +41,10 @@
 }
 }
 
-@implementation TabHistoryCell {
-  CRWSessionEntry* _entry;
-  UILabel* _titleLabel;
-}
+@implementation TabHistoryCell
+
+@synthesize item = _item;
+@synthesize titleLabel = _titleLabel;
 
 - (instancetype)initWithFrame:(CGRect)frame {
   self = [super initWithFrame:frame];
@@ -73,59 +72,34 @@
 
 - (void)layoutSubviews {
   [super layoutSubviews];
-
-  CGRect bounds = [[self contentView] bounds];
-  CGRect frame = AlignRectOriginAndSizeToPixels(bounds);
-  [_titleLabel setFrame:frame];
+  self.titleLabel.frame =
+      AlignRectOriginAndSizeToPixels(self.contentView.bounds);
 }
 
-- (CRWSessionEntry*)entry {
-  return _entry;
-}
+#pragma mark Accessors
 
-- (void)setEntry:(CRWSessionEntry*)entry {
-  _entry = entry;
+- (void)setItem:(const web::NavigationItem*)item {
+  _item = item;
 
-  NSString* title = nil;
-  web::NavigationItem* navigationItem = [_entry navigationItem];
-  if (navigationItem) {
-    // TODO(rohitrao): Can this use GetTitleForDisplay() instead?
-    if (navigationItem->GetTitle().empty())
-      title = base::SysUTF8ToNSString(navigationItem->GetURL().spec());
-    else
-      title = base::SysUTF16ToNSString(navigationItem->GetTitle());
-  }
-
-  [_titleLabel setText:title];
-  [self setAccessibilityLabel:title];
+  self.titleLabel.text =
+      _item ? base::SysUTF16ToNSString(_item->GetTitleForDisplay()) : nil;
+  [self setAccessibilityLabel:self.titleLabel.text];
   [self setNeedsLayout];
 }
 
-- (UILabel*)titleLabel {
-  return _titleLabel;
-}
+#pragma mark UICollectionViewCell
 
 - (void)prepareForReuse {
   [super prepareForReuse];
-  _entry = nil;
-  [_titleLabel setText:nil];
-  [self setAccessibilityLabel:nil];
+  self.item = nullptr;
 }
 
 @end
 
-@implementation TabHistorySectionHeader {
-  UIImageView* _iconView;
-  UIView* _lineView;
-}
+@implementation TabHistorySectionHeader
 
-- (UIImageView*)iconView {
-  return _iconView;
-}
-
-- (UIView*)lineView {
-  return _lineView;
-}
+@synthesize iconView = _iconView;
+@synthesize lineView = _lineView;
 
 - (instancetype)initWithFrame:(CGRect)frame {
   self = [super initWithFrame:frame];
@@ -134,17 +108,17 @@
     _iconView = [[UIImageView alloc] initWithFrame:iconFrame];
     [self addSubview:_iconView];
 
-    UIColor* lineColor = UIColorFromRGB(kHeaderLineRGB);
-
     _lineView = [[UIView alloc] initWithFrame:CGRectZero];
-    [[_lineView layer] setCornerRadius:HeaderLineRadius()];
-    [_lineView setBackgroundColor:lineColor];
+    _lineView.layer.cornerRadius = HeaderLineRadius();
+    _lineView.backgroundColor = UIColorFromRGB(kHeaderLineRGB);
     [self addSubview:_lineView];
   }
 
   return self;
 }
 
+#pragma mark UIView
+
 - (void)layoutSubviews {
   [super layoutSubviews];
 
@@ -153,7 +127,7 @@
 
   CGRect iconViewFrame = AlignRectToPixel(bounds);
   iconViewFrame.size = CGSizeMake(kSiteIconViewWidth, kSiteIconViewWidth);
-  [_iconView setFrame:iconViewFrame];
+  self.iconView.frame = iconViewFrame;
 
   CGFloat iconViewMaxY = CGRectGetMaxY(iconViewFrame);
   CGFloat height =
@@ -167,8 +141,7 @@
   lineViewFrame.size.width = HeaderLineWidth();
   lineViewFrame.size.height = height;
   lineViewFrame = AlignRectOriginAndSizeToPixels(lineViewFrame);
-
-  [_lineView setFrame:lineViewFrame];
+  self.lineView.frame = lineViewFrame;
 }
 
 @end
@@ -178,7 +151,7 @@
 - (instancetype)initWithFrame:(CGRect)frame {
   self = [super initWithFrame:frame];
   if (self)
-    [self setBackgroundColor:UIColorFromRGB(kFooterRGB)];
+    self.backgroundColor = UIColorFromRGB(kFooterRGB);
 
   return self;
 }
diff --git a/ios/chrome/browser/ui/history/tab_history_popup_controller.h b/ios/chrome/browser/ui/history/tab_history_popup_controller.h
index 293447f..8cd8a6294 100644
--- a/ios/chrome/browser/ui/history/tab_history_popup_controller.h
+++ b/ios/chrome/browser/ui/history/tab_history_popup_controller.h
@@ -7,20 +7,19 @@
 
 #import "ios/chrome/browser/ui/popup_menu/popup_menu_controller.h"
 
-@class TabHistoryViewController;
+#include "ios/web/public/navigation_item_list.h"
 
 // The view controller for the tab history menu that appears when the user long
 // presses the back or forward button.
 @interface TabHistoryPopupController : PopupMenuController
 
-// Initializes the popup to display |entries| with the given |origin| that is
+// Initializes the popup to display |items| with the given |origin| that is
 // relevant to the |parent|'s coordinate system.
 // |entries| is an array of CRWSessionEntries.
-// TODO(crbug.com/546355): Convert this class to use an array of
-//    NavigationEntries
 - (id)initWithOrigin:(CGPoint)origin
           parentView:(UIView*)parent
-             entries:(NSArray*)entries;
+               items:(const web::NavigationItemList&)items
+    NS_DESIGNATED_INITIALIZER;
 
 @end
 
diff --git a/ios/chrome/browser/ui/history/tab_history_popup_controller.mm b/ios/chrome/browser/ui/history/tab_history_popup_controller.mm
index 832de03..5c6c124 100644
--- a/ios/chrome/browser/ui/history/tab_history_popup_controller.mm
+++ b/ios/chrome/browser/ui/history/tab_history_popup_controller.mm
@@ -15,20 +15,22 @@
 #include "ios/chrome/browser/ui/ui_util.h"
 #import "ios/chrome/common/material_timing.h"
 #import "ios/third_party/material_roboto_font_loader_ios/src/src/MaterialRobotoFontLoader.h"
-#import "ios/web/navigation/crw_session_entry.h"
 #include "ios/web/public/navigation_item.h"
 #import "ui/gfx/ios/NSString+CrStringDrawing.h"
 #include "ui/gfx/ios/uikit_util.h"
+#include "url/gurl.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
 #endif
 
 namespace {
-static const CGFloat kTabHistoryMinWidth = 250.0;
-static const CGFloat kTabHistoryMaxWidthLandscapePhone = 350.0;
+const CGFloat kTabHistoryMinWidth = 250.0;
+const CGFloat kTabHistoryMaxWidthLandscapePhone = 350.0;
 // x coordinate for the textLabel in a default table cell with an image.
-static const CGFloat kCellTextXCoordinate = 60.0;
+const CGFloat kCellTextXCoordinate = 60.0;
+// The corner radius for the popover container view.
+const CGFloat kPopoverCornerRadius = 2.0;
 // Inset for the shadows of the contained views.
 NS_INLINE UIEdgeInsets TabHistoryPopupMenuInsets() {
   return UIEdgeInsetsMakeDirected(9, 11, 12, 11);
@@ -41,91 +43,90 @@
 static const CGFloat kHeightPercentage = 0.85;
 }  // anonymous namespace
 
-@interface TabHistoryPopupController () {
-  // TableViewController for the table displaying tab history entries.
-  TabHistoryViewController* tabHistoryTableViewController_;
+@interface TabHistoryPopupController ()
 
-  // Container view of the history entries table.
-  UIView* tabHistoryTableViewContainer_;
-}
-
-// Determines the width for the popup depending on the device, orientation, and
-// CRWSessionEntrys to display.
-- (CGFloat)calculatePopupWidth:(NSArray*)entries;
-
+// The UITableViewController displaying Tab history items.
 @property(nonatomic, strong)
     TabHistoryViewController* tabHistoryTableViewController;
+// The container view that displays |tabHistoryTableViewController|.
 @property(nonatomic, strong) UIView* tabHistoryTableViewContainer;
 
+// Determines the width for the popup depending on the device, orientation, and
+// number of NavigationItems to display.
++ (CGFloat)popupWidthForItems:(const web::NavigationItemList)items;
+
 @end
 
 @implementation TabHistoryPopupController
 
-@synthesize tabHistoryTableViewController = tabHistoryTableViewController_;
-@synthesize tabHistoryTableViewContainer = tabHistoryTableViewContainer_;
+@synthesize tabHistoryTableViewController = _tabHistoryTableViewController;
+@synthesize tabHistoryTableViewContainer = _tabHistoryTableViewContainer;
 
 - (id)initWithOrigin:(CGPoint)origin
           parentView:(UIView*)parent
-             entries:(NSArray*)entries {
+               items:(const web::NavigationItemList&)items {
   DCHECK(parent);
-  self = [super initWithParentView:parent];
-  if (self) {
-    tabHistoryTableViewController_ = [[TabHistoryViewController alloc] init];
-    [tabHistoryTableViewController_ setSessionEntries:entries];
+  if ((self = [super initWithParentView:parent])) {
+    // Create the table view controller.
+    _tabHistoryTableViewController =
+        [[TabHistoryViewController alloc] initWithItems:items];
 
-    UICollectionView* collectionView =
-        [tabHistoryTableViewController_ collectionView];
-    [collectionView setAccessibilityIdentifier:@"Tab History"];
+    // Set up the container view.
+    _tabHistoryTableViewContainer = [[UIView alloc] initWithFrame:CGRectZero];
+    _tabHistoryTableViewContainer.layer.cornerRadius = kPopoverCornerRadius;
+    _tabHistoryTableViewContainer.layer.masksToBounds = YES;
+    [_tabHistoryTableViewContainer
+        addSubview:_tabHistoryTableViewController.view];
 
-    tabHistoryTableViewContainer_ = [[UIView alloc] initWithFrame:CGRectZero];
-    [tabHistoryTableViewContainer_ layer].cornerRadius = 2;
-    [tabHistoryTableViewContainer_ layer].masksToBounds = YES;
-    [tabHistoryTableViewContainer_ addSubview:collectionView];
-
+    // Calculate the optimal popup size.
     LayoutOffset originOffset =
         kHistoryPopupLeadingOffset - TabHistoryPopupMenuInsets().left;
     CGPoint newOrigin = CGPointLayoutOffset(origin, originOffset);
     newOrigin.y += kHistoryPopupYOffset;
-
     CGFloat availableHeight =
         (CGRectGetHeight([parent bounds]) - origin.y) * kHeightPercentage;
     CGFloat optimalHeight =
-        [tabHistoryTableViewController_ optimalHeight:availableHeight];
-    CGFloat popupWidth = [self calculatePopupWidth:entries];
+        [_tabHistoryTableViewController optimalHeight:availableHeight];
+    CGFloat popupWidth = [[self class] popupWidthForItems:items];
     [self setOptimalSize:CGSizeMake(popupWidth, optimalHeight)
                 atOrigin:newOrigin];
-
-    CGRect bounds = [[self popupContainer] bounds];
-    CGRect frame = UIEdgeInsetsInsetRect(bounds, TabHistoryPopupMenuInsets());
-
-    [tabHistoryTableViewContainer_ setFrame:frame];
-    [collectionView setFrame:[tabHistoryTableViewContainer_ bounds]];
-
-    [[self popupContainer] addSubview:tabHistoryTableViewContainer_];
-    CGRect containerFrame = [[self popupContainer] frame];
-    CGPoint destination = CGPointMake(CGRectGetLeadingEdge(containerFrame),
-                                      CGRectGetMinY(containerFrame));
-    [self fadeInPopupFromSource:origin toDestination:destination];
   }
   return self;
 }
 
+- (void)dealloc {
+  [_tabHistoryTableViewContainer removeFromSuperview];
+}
+
+#pragma mark - PopupMenuController
+
 - (void)fadeInPopupFromSource:(CGPoint)source
                 toDestination:(CGPoint)destination {
-  [tabHistoryTableViewContainer_ setAlpha:0];
+  // Add the container view to the popup view and resize.
+  if (!_tabHistoryTableViewContainer.superview)
+    [self.popupContainer addSubview:_tabHistoryTableViewContainer];
+  _tabHistoryTableViewContainer.frame = UIEdgeInsetsInsetRect(
+      self.popupContainer.bounds, TabHistoryPopupMenuInsets());
+  _tabHistoryTableViewController.view.frame =
+      _tabHistoryTableViewContainer.bounds;
+
+  // Set up the animation.
+  [_tabHistoryTableViewContainer setAlpha:0];
   [UIView animateWithDuration:ios::material::kDuration1
                    animations:^{
-                     [tabHistoryTableViewContainer_ setAlpha:1];
+                     [_tabHistoryTableViewContainer setAlpha:1];
                    }];
   [super fadeInPopupFromSource:source toDestination:destination];
 }
 
 - (void)dismissAnimatedWithCompletion:(void (^)(void))completion {
-  [tabHistoryTableViewContainer_ setAlpha:0];
+  [_tabHistoryTableViewContainer setAlpha:0];
   [super dismissAnimatedWithCompletion:completion];
 }
 
-- (CGFloat)calculatePopupWidth:(NSArray*)entries {
+#pragma mark -
+
++ (CGFloat)popupWidthForItems:(const web::NavigationItemList)items {
   CGFloat maxWidth;
 
   // Determine the maximum width for the device and orientation.
@@ -145,8 +146,7 @@
   // Increase the width to fit the text to display but don't exceed maxWidth.
   CGFloat cellWidth = kTabHistoryMinWidth;
   UIFont* font = [[MDFRobotoFontLoader sharedInstance] regularFontOfSize:16];
-  for (CRWSessionEntry* sessionEntry in entries) {
-    web::NavigationItem* item = sessionEntry.navigationItem;
+  for (web::NavigationItem* item : items) {
     // TODO(rohitrao): Can this be replaced with GetTitleForDisplay()?
     NSString* cellText = item->GetTitle().empty()
                              ? base::SysUTF8ToNSString(item->GetURL().spec())
@@ -155,7 +155,7 @@
                            kCellTextXCoordinate;
 
     // If contentWidth is larger than maxWidth, return maxWidth instead of
-    // checking the rest of the entries.
+    // checking the rest of the items.
     if (contentWidth > maxWidth)
       return maxWidth;
     if (contentWidth > cellWidth)
@@ -164,8 +164,4 @@
   return cellWidth;
 }
 
-- (void)dealloc {
-  [tabHistoryTableViewContainer_ removeFromSuperview];
-}
-
 @end
diff --git a/ios/chrome/browser/ui/history/tab_history_popup_controller_egtest.mm b/ios/chrome/browser/ui/history/tab_history_popup_controller_egtest.mm
index 1881fe80..5ed4e78 100644
--- a/ios/chrome/browser/ui/history/tab_history_popup_controller_egtest.mm
+++ b/ios/chrome/browser/ui/history/tab_history_popup_controller_egtest.mm
@@ -11,6 +11,7 @@
 #import "ios/chrome/test/earl_grey/chrome_test_case.h"
 #import "ios/web/public/test/http_server.h"
 #import "ios/web/public/test/http_server_util.h"
+#include "ios/web/public/test/url_test_util.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
@@ -31,10 +32,10 @@
   const GURL URL3 = web::test::HttpServer::MakeUrl("http://page3");
   const GURL URL4 = web::test::HttpServer::MakeUrl("http://page4");
   NSString* entry0 = @"New Tab";
-  NSString* entry1 = base::SysUTF8ToNSString(URL1.spec());
-  NSString* entry2 = base::SysUTF8ToNSString(URL2.spec());
-  NSString* entry3 = base::SysUTF8ToNSString(URL3.spec());
-  NSString* entry4 = base::SysUTF8ToNSString(URL4.spec());
+  NSString* entry1 = base::SysUTF16ToNSString(web::GetDisplayTitleForUrl(URL1));
+  NSString* entry2 = base::SysUTF16ToNSString(web::GetDisplayTitleForUrl(URL2));
+  NSString* entry3 = base::SysUTF16ToNSString(web::GetDisplayTitleForUrl(URL3));
+  NSString* entry4 = base::SysUTF16ToNSString(web::GetDisplayTitleForUrl(URL4));
 
   // Create map of canned responses and set up the test HTML server.
   std::map<GURL, std::string> responses;
diff --git a/ios/chrome/browser/ui/history/tab_history_popup_controller_unittest.mm b/ios/chrome/browser/ui/history/tab_history_popup_controller_unittest.mm
index 3782087..6f1e9e7 100644
--- a/ios/chrome/browser/ui/history/tab_history_popup_controller_unittest.mm
+++ b/ios/chrome/browser/ui/history/tab_history_popup_controller_unittest.mm
@@ -11,7 +11,6 @@
 #include "components/sessions/core/session_types.h"
 #import "ios/chrome/browser/ui/history/tab_history_view_controller.h"
 #include "ios/chrome/browser/ui/ui_util.h"
-#import "ios/web/navigation/crw_session_entry.h"
 #include "ios/web/public/navigation_item.h"
 #include "ios/web/public/referrer.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -20,7 +19,7 @@
 #include "ui/gfx/ios/uikit_util.h"
 
 @interface TabHistoryPopupController (Testing)
-- (CGFloat)calculatePopupWidth:(NSArray*)entries;
++ (CGFloat)popupWidthForItems:(const web::NavigationItemList)items;
 @property(nonatomic, retain)
     TabHistoryViewController* tabHistoryTableViewController;
 @end
@@ -32,36 +31,26 @@
 class TabHistoryPopupControllerTest : public PlatformTest {
  protected:
   void SetUp() override {
+    web::Referrer referrer(GURL("http://www.example.com"),
+                           web::ReferrerPolicyDefault);
+    items_.push_back(web::NavigationItem::Create());
+    items_.back()->SetURL(GURL("http://www.example.com/0"));
+    items_.back()->SetReferrer(referrer);
+    items_.push_back(web::NavigationItem::Create());
+    items_.back()->SetURL(GURL("http://www.example.com/1"));
+    items_.back()->SetReferrer(referrer);
+    items_.push_back(web::NavigationItem::Create());
+    items_.back()->SetURL(GURL("http://www.example.com/0"));
+    items_.back()->SetReferrer(referrer);
+
     parent_.reset([[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds]);
     popup_.reset([[TabHistoryPopupController alloc]
         initWithOrigin:CGPointZero
             parentView:parent_
-               entries:testEntriesArray()]);
+                 items:web::CreateRawNavigationItemList(items_)]);
   }
-  void TearDown() override {
-    parent_.reset();
-    popup_.reset();
-  }
-  NSArray* testEntriesArray() {
-    web::Referrer referrer(GURL("http://www.example.com"),
-                           web::ReferrerPolicyDefault);
-    std::unique_ptr<web::NavigationItem> item0 = web::NavigationItem::Create();
-    item0->SetURL(GURL("http://www.example.com/0"));
-    item0->SetReferrer(referrer);
-    CRWSessionEntry* entry0 =
-        [[CRWSessionEntry alloc] initWithNavigationItem:std::move(item0)];
-    std::unique_ptr<web::NavigationItem> item1 = web::NavigationItem::Create();
-    item1->SetURL(GURL("http://www.example.com/1"));
-    item1->SetReferrer(referrer);
-    CRWSessionEntry* entry1 =
-        [[CRWSessionEntry alloc] initWithNavigationItem:std::move(item1)];
-    std::unique_ptr<web::NavigationItem> item2 = web::NavigationItem::Create();
-    item2->SetURL(GURL("http://www.example.com/2"));
-    item2->SetReferrer(referrer);
-    CRWSessionEntry* entry2 =
-        [[CRWSessionEntry alloc] initWithNavigationItem:std::move(item2)];
-    return [NSArray arrayWithObjects:entry0, entry1, entry2, nil];
-  }
+
+  web::ScopedNavigationItemList items_;
   base::scoped_nsobject<UIView> parent_;
   base::scoped_nsobject<TabHistoryPopupController> popup_;
 };
@@ -81,30 +70,6 @@
 }
 
 TEST_F(TabHistoryPopupControllerTest, TestCalculatePopupWidth) {
-  web::Referrer referrer(GURL("http://www.example.com"),
-                         web::ReferrerPolicyDefault);
-  std::unique_ptr<web::NavigationItem> itemShort =
-      web::NavigationItem::Create();
-  itemShort->SetURL(GURL("http://foo.com/"));
-  itemShort->SetReferrer(referrer);
-  CRWSessionEntry* entryShort =
-      [[CRWSessionEntry alloc] initWithNavigationItem:std::move(itemShort)];
-  std::unique_ptr<web::NavigationItem> itemMedium =
-      web::NavigationItem::Create();
-  itemMedium->SetURL(GURL("http://www.example.com/mediumurl"));
-  itemMedium->SetReferrer(referrer);
-  CRWSessionEntry* entryMedium =
-      [[CRWSessionEntry alloc] initWithNavigationItem:std::move(itemMedium)];
-  std::string longURL =
-      "http://www.example.com/this/is/areally/long/url/that/"
-      "is/larger/than/the/maximum/table/width/so/its/text/will/get/cut/off/and/"
-      "the/max/width/is/used/";
-  std::unique_ptr<web::NavigationItem> itemLong = web::NavigationItem::Create();
-  itemLong->SetURL(GURL(longURL));
-  itemLong->SetReferrer(referrer);
-  CRWSessionEntry* entryLong =
-      [[CRWSessionEntry alloc] initWithNavigationItem:std::move(itemLong)];
-
   CGFloat minWidth = kTabHistoryMinWidth;
   CGFloat maxWidth = kTabHistoryMinWidth;
   if (!IsIPadIdiom()) {
@@ -117,19 +82,37 @@
         [UIApplication sharedApplication].keyWindow.frame.size.width * .85);
   }
 
-  CGFloat width =
-      [popup_ calculatePopupWidth:[NSArray arrayWithObjects:entryShort, nil]];
+  // Add an item with a short URL and verify that the minimum width is returned.
+  web::ScopedNavigationItemList items;
+  web::Referrer referrer(GURL("http://www.example.com"),
+                         web::ReferrerPolicyDefault);
+  items.push_back(web::NavigationItem::Create());
+  items.back()->SetURL(GURL("http://foo.com/"));
+  items.back()->SetReferrer(referrer);
+  web::NavigationItemList raw_items = web::CreateRawNavigationItemList(items);
+  CGFloat width = [TabHistoryPopupController popupWidthForItems:raw_items];
   EXPECT_EQ(minWidth, width);
 
-  width =
-      [popup_ calculatePopupWidth:[NSArray arrayWithObjects:entryShort,
-                                                            entryMedium, nil]];
+  // Add an item with a medium URL and verify that the returned width is between
+  // the minimum and maximum.
+  items.push_back(web::NavigationItem::Create());
+  items.back()->SetURL(GURL("http://www.example.com/mediumurl"));
+  items.back()->SetReferrer(referrer);
+  raw_items.push_back(items.back().get());
+  width = [TabHistoryPopupController popupWidthForItems:raw_items];
   EXPECT_GE(width, minWidth);
   EXPECT_LE(width, maxWidth);
 
-  width = [popup_
-      calculatePopupWidth:[NSArray arrayWithObjects:entryShort, entryLong,
-                                                    entryMedium, nil]];
+  // Add an item with a long URL and verify that the maximum width is returned.
+  std::string long_url =
+      "http://www.example.com/this/is/areally/long/url/that/"
+      "is/larger/than/the/maximum/table/width/so/its/text/will/get/cut/off/and/"
+      "the/max/width/is/used/";
+  items.push_back(web::NavigationItem::Create());
+  items.back()->SetURL(GURL(long_url));
+  items.back()->SetReferrer(referrer);
+  raw_items.push_back(items.back().get());
+  width = [TabHistoryPopupController popupWidthForItems:raw_items];
   EXPECT_EQ(maxWidth, width);
 }
 
diff --git a/ios/chrome/browser/ui/history/tab_history_view_controller.h b/ios/chrome/browser/ui/history/tab_history_view_controller.h
index cc7877e..5343bc2 100644
--- a/ios/chrome/browser/ui/history/tab_history_view_controller.h
+++ b/ios/chrome/browser/ui/history/tab_history_view_controller.h
@@ -7,12 +7,21 @@
 
 #import <UIKit/UIKit.h>
 
-// View controller for displaying a list of CRWSessionEntry objects in a table.
+#include "ios/web/public/navigation_item_list.h"
+
+// View controller for displaying a list of NavigationItems in a table.
 @interface TabHistoryViewController : UICollectionViewController
 
-// TODO(crbug.com/546355): Convert this class to use an array of
-//    NavigationEntries.
-@property(nonatomic, strong) NSArray* sessionEntries;
+// Designated initializer that takes a NavigationItemList.
+- (instancetype)initWithItems:(const web::NavigationItemList&)items
+    NS_DESIGNATED_INITIALIZER;
+
+// TabHistoryViewControllers must be initialized with |-initWithItems:|.
+- (instancetype)initWithCoder:(NSCoder*)aDecoder NS_UNAVAILABLE;
+- (instancetype)initWithCollectionViewLayout:(UICollectionViewLayout*)layout
+    NS_UNAVAILABLE;
+- (instancetype)initWithNibName:(NSString*)nibNameOrNil
+                         bundle:(NSBundle*)nibBundleOrNil NS_UNAVAILABLE;
 
 // Returns the optimal height needed to display the session entries.
 // The height returned is usually less than the |suggestedHeight| unless
diff --git a/ios/chrome/browser/ui/history/tab_history_view_controller.mm b/ios/chrome/browser/ui/history/tab_history_view_controller.mm
index 954ea175..c66487c 100644
--- a/ios/chrome/browser/ui/history/tab_history_view_controller.mm
+++ b/ios/chrome/browser/ui/history/tab_history_view_controller.mm
@@ -12,7 +12,6 @@
 #import "ios/chrome/browser/ui/history/tab_history_cell.h"
 #include "ios/chrome/browser/ui/rtl_geometry.h"
 #import "ios/third_party/material_components_ios/src/components/Ink/src/MaterialInk.h"
-#import "ios/web/navigation/crw_session_entry.h"
 #include "ios/web/public/favicon_status.h"
 #include "ios/web/public/navigation_item.h"
 #include "ui/gfx/image/image.h"
@@ -26,10 +25,13 @@
 // Visible percentage of the last visible row on the Tools menu if the
 // Tools menu is scrollable.
 const CGFloat kLastRowVisiblePercentage = 0.6;
+// The collection view's a11y ID.
+// TODO(crbug.com/697648): Decide better a11y behavior for this feature.
+NSString* const kCollectionViewIdentifier = @"Tab History";
 // Reuse identifier for cells.
-NSString* cellIdentifier = @"TabHistoryCell";
-NSString* footerIdentifier = @"Footer";
-NSString* headerIdentifier = @"Header";
+NSString* const kCellIdentifier = @"TabHistoryCell";
+NSString* const kFooterIdentifier = @"Footer";
+NSString* const kHeaderIdentifier = @"Header";
 // Height of rows.
 const CGFloat kCellHeight = 48.0;
 // Fraction height for partially visible row.
@@ -71,6 +73,36 @@
   return 1.0 / [[UIScreen mainScreen] scale];
 }
 
+// Returns a vector of of NavigationItemLists where the NavigationItems in
+// |items| are separated by host.
+NS_INLINE std::vector<web::NavigationItemList> PartitionItemsByHost(
+    const web::NavigationItemList& items) {
+  std::vector<web::NavigationItemList> partitionedItems;
+  // Used to store the previous host when partitioning NavigationItems.
+  std::string previousHost;
+  // The NavigationItemList containing NavigationItems with the same host.
+  web::NavigationItemList itemsWithSameHostname;
+  // Separate the items in |items| by host.
+  for (web::NavigationItem* item : items) {
+    std::string currentHost = item->GetURL().host();
+    if (previousHost.empty())
+      previousHost = currentHost;
+    // TODO: This should use some sort of Top Level Domain matching instead of
+    // explicit host match so that images.googe.com matches shopping.google.com.
+    if (previousHost == currentHost) {
+      itemsWithSameHostname.push_back(item);
+    } else {
+      partitionedItems.push_back(itemsWithSameHostname);
+      itemsWithSameHostname = web::NavigationItemList(1, item);
+      previousHost = currentHost;
+    }
+  }
+  // Add the last list contiaining the same host.
+  if (!itemsWithSameHostname.empty())
+    partitionedItems.push_back(itemsWithSameHostname);
+  return partitionedItems;
+}
+
 }  // namespace
 
 @interface TabHistoryViewControllerLayout : UICollectionViewLayout
@@ -219,15 +251,50 @@
 
 @interface TabHistoryViewController ()<MDCInkTouchControllerDelegate> {
   MDCInkTouchController* _inkTouchController;
-  NSArray* _partitionedEntries;
-  NSArray* _sessionEntries;
+  // A vector of NavigationItemLists where the NavigationItems are separated
+  // by hostname.
+  std::vector<web::NavigationItemList> _partitionedItems;
 }
+
+// Returns the NavigationItem corresponding with |indexPath|.
+- (const web::NavigationItem*)itemAtIndexPath:(NSIndexPath*)indexPath;
+
+// Removes all NavigationItem pointers from this class.  Tapping a cell that
+// triggers a navigation may delete NavigationItems, so NavigationItem
+// references should be reset to avoid use-after-free errors.
+- (void)clearNavigationItems;
+
 @end
 
 @implementation TabHistoryViewController
 
-- (NSArray*)sessionEntries {
-  return _sessionEntries;
+- (instancetype)initWithItems:(const web::NavigationItemList&)items {
+  TabHistoryViewControllerLayout* layout =
+      [[TabHistoryViewControllerLayout alloc] init];
+  if ((self = [super initWithCollectionViewLayout:layout])) {
+    // Populate |_partitionedItems|.
+    _partitionedItems = PartitionItemsByHost(items);
+
+    // Set up the UICollectionView.
+    UICollectionView* collectionView = [self collectionView];
+    collectionView.accessibilityIdentifier = kCollectionViewIdentifier;
+    collectionView.backgroundColor = [UIColor whiteColor];
+    [collectionView registerClass:[TabHistoryCell class]
+        forCellWithReuseIdentifier:kCellIdentifier];
+    [collectionView registerClass:[TabHistorySectionHeader class]
+        forSupplementaryViewOfKind:UICollectionElementKindSectionHeader
+               withReuseIdentifier:kHeaderIdentifier];
+    [collectionView registerClass:[TabHistorySectionFooter class]
+        forSupplementaryViewOfKind:UICollectionElementKindSectionFooter
+               withReuseIdentifier:kFooterIdentifier];
+
+    // Set up the ink controller.
+    _inkTouchController =
+        [[MDCInkTouchController alloc] initWithView:collectionView];
+    [_inkTouchController setDelegate:self];
+    [_inkTouchController addInkView];
+  }
+  return self;
 }
 
 #pragma mark Public Methods
@@ -236,9 +303,8 @@
   DCHECK(suggestedHeight >= kCellHeight);
   CGFloat optimalHeight = 0;
 
-  for (NSArray* sectionArray in _partitionedEntries) {
-    NSUInteger sectionItemCount = [sectionArray count];
-    for (NSUInteger i = 0; i < sectionItemCount; ++i) {
+  for (web::NavigationItemList& itemsWithSameHost : _partitionedItems) {
+    for (size_t count = 0; count < itemsWithSameHost.size(); ++count) {
       CGFloat proposedHeight = optimalHeight + kCellHeight;
 
       if (proposedHeight > suggestedHeight) {
@@ -263,153 +329,67 @@
   return optimalHeight;
 }
 
-- (instancetype)init {
-  TabHistoryViewControllerLayout* layout =
-      [[TabHistoryViewControllerLayout alloc] init];
-
-  return [self initWithCollectionViewLayout:layout];
-}
-
-- (instancetype)initWithCollectionViewLayout:(UICollectionViewLayout*)layout {
-  self = [super initWithCollectionViewLayout:layout];
-  if (self) {
-    UICollectionView* collectionView = [self collectionView];
-    [collectionView setBackgroundColor:[UIColor whiteColor]];
-
-    [collectionView registerClass:[TabHistoryCell class]
-        forCellWithReuseIdentifier:cellIdentifier];
-
-    [collectionView registerClass:[TabHistorySectionHeader class]
-        forSupplementaryViewOfKind:UICollectionElementKindSectionHeader
-               withReuseIdentifier:headerIdentifier];
-
-    [collectionView registerClass:[TabHistorySectionFooter class]
-        forSupplementaryViewOfKind:UICollectionElementKindSectionFooter
-               withReuseIdentifier:footerIdentifier];
-
-    _inkTouchController =
-        [[MDCInkTouchController alloc] initWithView:collectionView];
-    [_inkTouchController setDelegate:self];
-    [_inkTouchController addInkView];
-  }
-
-  return self;
-}
-
 #pragma mark UICollectionViewDelegate
 
 - (void)collectionView:(UICollectionView*)collectionView
     didSelectItemAtIndexPath:(NSIndexPath*)indexPath {
-  UICollectionViewCell* cell =
-      [collectionView cellForItemAtIndexPath:indexPath];
+  TabHistoryCell* cell = base::mac::ObjCCastStrict<TabHistoryCell>(
+      [collectionView cellForItemAtIndexPath:indexPath]);
   [collectionView chromeExecuteCommand:cell];
+  [self clearNavigationItems];
 }
 
 #pragma mark UICollectionViewDataSource
 
-- (CRWSessionEntry*)entryForIndexPath:(NSIndexPath*)indexPath {
-  NSInteger section = [indexPath section];
-  NSInteger item = [indexPath item];
-
-  DCHECK(section < (NSInteger)[_partitionedEntries count]);
-  DCHECK(item < (NSInteger)[[_partitionedEntries objectAtIndex:section] count]);
-  NSArray* sectionedArray = [_partitionedEntries objectAtIndex:section];
-
-  return [sectionedArray objectAtIndex:item];
-}
-
 - (NSInteger)collectionView:(UICollectionView*)collectionView
      numberOfItemsInSection:(NSInteger)section {
-  DCHECK(section < (NSInteger)[_partitionedEntries count]);
-  return [[_partitionedEntries objectAtIndex:section] count];
+  size_t sectionIdx = static_cast<size_t>(section);
+  DCHECK_LT(sectionIdx, _partitionedItems.size());
+  return _partitionedItems[sectionIdx].size();
 }
 
 - (UICollectionViewCell*)collectionView:(UICollectionView*)collectionView
                  cellForItemAtIndexPath:(NSIndexPath*)indexPath {
   TabHistoryCell* cell =
-      [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier
+      [collectionView dequeueReusableCellWithReuseIdentifier:kCellIdentifier
                                                 forIndexPath:indexPath];
-
-  [cell setEntry:[self entryForIndexPath:indexPath]];
-  [cell setTag:IDC_BACK_FORWARD_IN_TAB_HISTORY];
-
+  cell.item = [self itemAtIndexPath:indexPath];
+  cell.tag = IDC_BACK_FORWARD_IN_TAB_HISTORY;
   return cell;
 }
 
 - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView*)view {
-  return [_partitionedEntries count];
+  return _partitionedItems.size();
 }
 
 - (UICollectionReusableView*)collectionView:(UICollectionView*)view
           viewForSupplementaryElementOfKind:(NSString*)kind
                                 atIndexPath:(NSIndexPath*)indexPath {
+  // Return a footer cell if requested.
   if ([kind isEqualToString:UICollectionElementKindSectionFooter]) {
     return [view dequeueReusableSupplementaryViewOfKind:kind
-                                    withReuseIdentifier:footerIdentifier
+                                    withReuseIdentifier:kFooterIdentifier
                                            forIndexPath:indexPath];
   }
-
   DCHECK([kind isEqualToString:UICollectionElementKindSectionHeader]);
-  CRWSessionEntry* sessionEntry = [self entryForIndexPath:indexPath];
-  web::NavigationItem* navigationItem = [sessionEntry navigationItem];
 
+  // Dequeue a header cell and populate its favicon image.
   TabHistorySectionHeader* header =
       [view dequeueReusableSupplementaryViewOfKind:kind
-                               withReuseIdentifier:headerIdentifier
+                               withReuseIdentifier:kHeaderIdentifier
                                       forIndexPath:indexPath];
-
   UIImage* iconImage = nil;
-  const gfx::Image& image = navigationItem->GetFavicon().image;
+  const gfx::Image& image =
+      [self itemAtIndexPath:indexPath]->GetFavicon().image;
   if (!image.IsEmpty())
     iconImage = image.ToUIImage();
   else
     iconImage = [UIImage imageNamed:@"default_favicon"];
-
   [[header iconView] setImage:iconImage];
 
   return header;
 }
 
-- (void)setSessionEntries:(NSArray*)sessionEntries {
-  _sessionEntries = sessionEntries;
-
-  std::string previousHost;
-
-  NSMutableArray* sectionArray = [NSMutableArray array];
-  NSMutableArray* partitionedEntries = [NSMutableArray array];
-
-  NSInteger numberOfEntries = [_sessionEntries count];
-  for (NSInteger index = 0; index < numberOfEntries; ++index) {
-    CRWSessionEntry* sessionEntry = [_sessionEntries objectAtIndex:index];
-    web::NavigationItem* navigationItem = [sessionEntry navigationItem];
-
-    std::string currentHost;
-    if (navigationItem)
-      currentHost = navigationItem->GetURL().host();
-
-    if (previousHost.empty())
-      previousHost = currentHost;
-
-    // TODO: This should use some sort of Top Level Domain matching instead of
-    // explicit host match so that images.googe.com matches shopping.google.com.
-    if (previousHost == currentHost) {
-      [sectionArray addObject:sessionEntry];
-    } else {
-      [partitionedEntries addObject:sectionArray];
-      sectionArray = [NSMutableArray arrayWithObject:sessionEntry];
-      previousHost = currentHost;
-    }
-  }
-
-  if ([sectionArray count])
-    [partitionedEntries addObject:sectionArray];
-
-  if (![partitionedEntries count])
-    partitionedEntries = nil;
-
-  _partitionedEntries = partitionedEntries;
-}
-
 #pragma mark MDCInkTouchControllerDelegate
 
 - (BOOL)inkTouchController:(MDCInkTouchController*)inkTouchController
@@ -431,4 +411,22 @@
   return YES;
 }
 
+#pragma mark -
+
+- (const web::NavigationItem*)itemAtIndexPath:(NSIndexPath*)indexPath {
+  size_t section = static_cast<size_t>([indexPath section]);
+  size_t item = static_cast<size_t>([indexPath item]);
+  DCHECK_LT(section, _partitionedItems.size());
+  DCHECK_LT(item, _partitionedItems[section].size());
+  return _partitionedItems[section][item];
+}
+
+- (void)clearNavigationItems {
+  _partitionedItems.clear();
+  for (UICollectionViewCell* cell in self.collectionView.visibleCells) {
+    TabHistoryCell* historyCell = base::mac::ObjCCast<TabHistoryCell>(cell);
+    historyCell.item = nullptr;
+  }
+}
+
 @end
diff --git a/ios/chrome/browser/ui/preload_controller_delegate.h b/ios/chrome/browser/ui/preload_controller_delegate.h
index e23302e903..46e08c56 100644
--- a/ios/chrome/browser/ui/preload_controller_delegate.h
+++ b/ios/chrome/browser/ui/preload_controller_delegate.h
@@ -7,16 +7,11 @@
 
 #import <UIKit/UIKit.h>
 
-@class CRWSessionEntry;
-
 // A protocol implemented by a delegate of PreloadController
 @protocol PreloadControllerDelegate
 
 // Should preload controller request a desktop site.
 - (BOOL)shouldUseDesktopUserAgent;
-// Return the current sessionEntry from the delegate.
-// TODO(crbug.com/546348): See if this can return a NavigationItem instead.
-- (CRWSessionEntry*)currentSessionEntry;
 @end
 
 #endif  // IOS_CHROME_BROWSER_UI_PRELOAD_CONTROLLER_DELEGATE_H_
diff --git a/ios/chrome/browser/ui/reader_mode/reader_mode_checker.mm b/ios/chrome/browser/ui/reader_mode/reader_mode_checker.mm
index d2ccabaa..8c207d6 100644
--- a/ios/chrome/browser/ui/reader_mode/reader_mode_checker.mm
+++ b/ios/chrome/browser/ui/reader_mode/reader_mode_checker.mm
@@ -118,7 +118,7 @@
         }
         const dom_distiller::DistillablePageDetector* detector =
             dom_distiller::DistillablePageDetector::GetDefault();
-        const base::StringValue value(base::SysNSStringToUTF8(result));
+        const base::Value value(base::SysNSStringToUTF8(result));
         std::vector<double> features(
             dom_distiller::CalculateDerivedFeaturesFromJSON(&value));
         if (detector->Classify(features)) {
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_collection_view_item.mm b/ios/chrome/browser/ui/reading_list/reading_list_collection_view_item.mm
index 46931b3..9618ce4 100644
--- a/ios/chrome/browser/ui/reading_list/reading_list_collection_view_item.mm
+++ b/ios/chrome/browser/ui/reading_list/reading_list_collection_view_item.mm
@@ -24,6 +24,9 @@
 
 // Distillation indicator constants.
 const CGFloat kDistillationIndicatorSize = 18;
+
+// Margin for the elements displayed in the cell.
+const CGFloat kMargin = 16;
 }  // namespace
 
 #pragma mark - ReadingListCell Private interface
@@ -191,37 +194,45 @@
     _textLabel = [[UILabel alloc] init];
     _textLabel.font = [fontLoader mediumFontOfSize:16];
     _textLabel.textColor = [[MDCPalette greyPalette] tint900];
+    _textLabel.translatesAutoresizingMaskIntoConstraints = NO;
 
     _detailTextLabel = [[UILabel alloc] init];
     _detailTextLabel.font = [fontLoader mediumFontOfSize:14];
     _detailTextLabel.textColor = [[MDCPalette greyPalette] tint500];
+    _detailTextLabel.translatesAutoresizingMaskIntoConstraints = NO;
 
     _faviconView = [[FaviconViewNew alloc] init];
     CGFloat fontSize = floorf(faviconSize / 2);
     [_faviconView setFont:[fontLoader regularFontOfSize:fontSize]];
+    _faviconView.translatesAutoresizingMaskIntoConstraints = NO;
 
     _downloadIndicator = [[UIImageView alloc] init];
     [_downloadIndicator setTranslatesAutoresizingMaskIntoConstraints:NO];
     [_faviconView addSubview:_downloadIndicator];
 
-    UIStackView* labelsStack = [[UIStackView alloc]
-        initWithArrangedSubviews:@[ _textLabel, _detailTextLabel ]];
-    labelsStack.axis = UILayoutConstraintAxisVertical;
+    [self.contentView addSubview:_textLabel];
+    [self.contentView addSubview:_detailTextLabel];
+    [self.contentView addSubview:_faviconView];
 
-    UIStackView* stackView = [[UIStackView alloc]
-        initWithArrangedSubviews:@[ _faviconView, labelsStack ]];
-    [self.contentView addSubview:stackView];
-    stackView.layoutMarginsRelativeArrangement = YES;
-    stackView.layoutMargins = UIEdgeInsetsMake(16, 16, 16, 16);
-    stackView.alignment = UIStackViewAlignmentCenter;
-    stackView.spacing = 16;
+    ApplyVisualConstraintsWithMetrics(
+        @[
+          @"V:|-(margin)-[title][text]-(margin)-|",
+          @"H:|-(margin)-[favicon]-(margin)-[title]-(>=margin)-|",
+          @"H:[favicon]-(margin)-[text]-(>=margin)-|"
+        ],
+        @{
+          @"title" : _textLabel,
+          @"text" : _detailTextLabel,
+          @"favicon" : _faviconView
+        },
+        @{ @"margin" : @(kMargin) });
 
-    stackView.translatesAutoresizingMaskIntoConstraints = NO;
-    AddSameSizeConstraint(self.contentView, stackView);
     [NSLayoutConstraint activateConstraints:@[
       // Favicons are always the same size.
       [_faviconView.widthAnchor constraintEqualToConstant:faviconSize],
       [_faviconView.heightAnchor constraintEqualToConstant:faviconSize],
+      [_faviconView.centerYAnchor
+          constraintEqualToAnchor:self.contentView.centerYAnchor],
       // Place the download indicator in the bottom right corner of the favicon.
       [[_downloadIndicator centerXAnchor]
           constraintEqualToAnchor:_faviconView.trailingAnchor],
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_empty_collection_background.mm b/ios/chrome/browser/ui/reading_list/reading_list_empty_collection_background.mm
index 360521e9..d3eaca49 100644
--- a/ios/chrome/browser/ui/reading_list/reading_list_empty_collection_background.mm
+++ b/ios/chrome/browser/ui/reading_list/reading_list_empty_collection_background.mm
@@ -108,7 +108,9 @@
     NSString* accessibilityInstructionString = @":";
 
     // Add the images inside the string.
-    if (IsCompact()) {
+    if (IsCompact() || !IsIPadIdiom()) {
+      // TODO(crbug.com/698726): When the share icon is displayed in the toolbar
+      // for landscape iPhone 6+, remove !IsIPadIdiom().
       // If the device has a compact display the share menu is accessed from the
       // toolbar menu. If it is expanded, the share menu is directly accessible.
       [self attachIconNamed:kToolbarMenuIcon
diff --git a/ios/chrome/browser/ui/settings/BUILD.gn b/ios/chrome/browser/ui/settings/BUILD.gn
index 74e62dd6..389ea9d 100644
--- a/ios/chrome/browser/ui/settings/BUILD.gn
+++ b/ios/chrome/browser/ui/settings/BUILD.gn
@@ -37,6 +37,7 @@
     "autofill_credit_card_edit_collection_view_controller.mm",
     "autofill_edit_accessory_view.h",
     "autofill_edit_accessory_view.mm",
+    "autofill_edit_collection_view_controller+protected.h",
     "autofill_edit_collection_view_controller.h",
     "autofill_edit_collection_view_controller.mm",
     "autofill_profile_edit_collection_view_controller.h",
diff --git a/ios/chrome/browser/ui/settings/autofill_credit_card_edit_collection_view_controller.mm b/ios/chrome/browser/ui/settings/autofill_credit_card_edit_collection_view_controller.mm
index a7ed56c..3c4ad8a 100644
--- a/ios/chrome/browser/ui/settings/autofill_credit_card_edit_collection_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/autofill_credit_card_edit_collection_view_controller.mm
@@ -11,6 +11,7 @@
 #include "base/mac/scoped_block.h"
 #import "base/mac/scoped_nsobject.h"
 #include "base/strings/sys_string_conversions.h"
+#include "components/autofill/core/browser/autofill_data_util.h"
 #include "components/autofill/core/browser/credit_card.h"
 #include "components/autofill/core/browser/field_types.h"
 #include "components/autofill/core/browser/payments/payments_service_url.h"
@@ -22,6 +23,7 @@
 #import "ios/chrome/browser/ui/commands/UIKit+ChromeExecuteCommand.h"
 #include "ios/chrome/browser/ui/commands/ios_command_ids.h"
 #import "ios/chrome/browser/ui/commands/open_url_command.h"
+#import "ios/chrome/browser/ui/settings/autofill_edit_collection_view_controller+protected.h"
 #import "ios/chrome/browser/ui/settings/cells/autofill_edit_item.h"
 #import "ios/chrome/browser/ui/settings/cells/copied_to_chrome_item.h"
 #import "ios/chrome/browser/ui/uikit_ui_util.h"
@@ -35,6 +37,8 @@
 NSString* const kAutofillCreditCardEditCollectionViewId =
     @"kAutofillCreditCardEditCollectionViewId";
 
+const CGFloat kCardTypeIconDimension = 30.0;
+
 typedef NS_ENUM(NSInteger, SectionIdentifier) {
   SectionIdentifierFields = kSectionIdentifierEnumZero,
   SectionIdentifierCopiedToChrome,
@@ -156,6 +160,7 @@
           : base::SysUTF16ToNSString(_creditCard.LastFourDigits());
   cardNumberitem.textFieldEnabled = isEditing;
   cardNumberitem.autofillType = autofill::CREDIT_CARD_NUMBER;
+  [self setCardTypeIconForItem:cardNumberitem];
   [model addItem:cardNumberitem
       toSectionWithIdentifier:SectionIdentifierFields];
 
@@ -193,6 +198,26 @@
   }
 }
 
+#pragma mark - UITextFieldDelegate
+
+- (void)textFieldDidEndEditing:(UITextField*)textField {
+  NSIndexPath* cellPath = [self indexPathForCurrentTextField];
+  DCHECK(cellPath);
+  NSIndexPath* itemPath = [NSIndexPath indexPathForItem:[cellPath row]
+                                              inSection:[cellPath section]];
+  AutofillEditItem* item = base::mac::ObjCCastStrict<AutofillEditItem>(
+      [self.collectionViewModel itemAtIndexPath:itemPath]);
+
+  if (item.autofillType == autofill::CREDIT_CARD_NUMBER)
+    [self setCardTypeIconForItem:item];
+
+  // Update the cell.
+  [self reconfigureCellsForItems:@[ item ]
+         inSectionWithIdentifier:SectionIdentifierFields];
+
+  [super textFieldDidEndEditing:textField];
+}
+
 #pragma mark - MDCCollectionViewEditingDelegate
 
 - (BOOL)collectionViewAllowsEditing:(UICollectionView*)collectionView {
@@ -270,4 +295,22 @@
   [self reloadData];
 }
 
+#pragma mark - Helper Methods
+
+- (void)setCardTypeIconForItem:(AutofillEditItem*)item {
+  const char* cardType = autofill::CreditCard::GetCreditCardType(
+      base::SysNSStringToUTF16(item.textFieldValue));
+  if (cardType != autofill::kGenericCard) {
+    int resourceID =
+        autofill::data_util::GetPaymentRequestData(cardType).icon_resource_id;
+    // Resize and set the card type icon.
+    CGFloat dimension = kCardTypeIconDimension;
+    item.cardTypeIcon =
+        ResizeImage(NativeImage(resourceID), CGSizeMake(dimension, dimension),
+                    ProjectionMode::kAspectFillNoClipping);
+  } else {
+    item.cardTypeIcon = nil;
+  }
+}
+
 @end
diff --git a/ios/chrome/browser/ui/settings/autofill_edit_collection_view_controller+protected.h b/ios/chrome/browser/ui/settings/autofill_edit_collection_view_controller+protected.h
new file mode 100644
index 0000000..89b8ed83
--- /dev/null
+++ b/ios/chrome/browser/ui/settings/autofill_edit_collection_view_controller+protected.h
@@ -0,0 +1,18 @@
+// Copyright 2017 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 IOS_CHROME_BROWSER_UI_SETTINGS_AUTOFILL_EDIT_COLLECTION_VIEW_CONTROLLER_PROTECTED_H_
+#define IOS_CHROME_BROWSER_UI_SETTINGS_AUTOFILL_EDIT_COLLECTION_VIEW_CONTROLLER_PROTECTED_H_
+
+#import "ios/chrome/browser/ui/settings/autofill_edit_collection_view_controller.h"
+
+// The collection view for an Autofill edit entry menu.
+@interface AutofillEditCollectionViewController (Protected)
+
+// Returns the indexPath for the currently focused text field when in edit mode.
+- (NSIndexPath*)indexPathForCurrentTextField;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_UI_SETTINGS_AUTOFILL_EDIT_COLLECTION_VIEW_CONTROLLER_PROTECTED_H_
diff --git a/ios/chrome/browser/ui/settings/autofill_edit_collection_view_controller.mm b/ios/chrome/browser/ui/settings/autofill_edit_collection_view_controller.mm
index f0f4faa..bc485697 100644
--- a/ios/chrome/browser/ui/settings/autofill_edit_collection_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/autofill_edit_collection_view_controller.mm
@@ -8,6 +8,7 @@
 #import "base/mac/foundation_util.h"
 #import "base/mac/scoped_nsobject.h"
 #import "ios/chrome/browser/ui/settings/autofill_edit_accessory_view.h"
+#import "ios/chrome/browser/ui/settings/autofill_edit_collection_view_controller+protected.h"
 #import "ios/chrome/browser/ui/settings/cells/autofill_edit_item.h"
 #import "ios/third_party/material_components_ios/src/components/CollectionCells/src/MaterialCollectionCells.h"
 
@@ -128,6 +129,20 @@
 
 #pragma mark - AutofillEditAccessoryDelegate
 
+- (void)nextPressed {
+  [self moveToAnotherCellWithOffset:1];
+}
+
+- (void)previousPressed {
+  [self moveToAnotherCellWithOffset:-1];
+}
+
+- (void)closePressed {
+  [[_currentEditingCell textField] resignFirstResponder];
+}
+
+#pragma mark - Helper methods
+
 - (NSIndexPath*)indexPathForCurrentTextField {
   DCHECK(_currentEditingCell);
   return [[self collectionView] indexPathForCell:_currentEditingCell];
@@ -149,18 +164,6 @@
   }
 }
 
-- (void)nextPressed {
-  [self moveToAnotherCellWithOffset:1];
-}
-
-- (void)previousPressed {
-  [self moveToAnotherCellWithOffset:-1];
-}
-
-- (void)closePressed {
-  [[_currentEditingCell textField] resignFirstResponder];
-}
-
 - (void)updateAccessoryViewButtonState {
   NSIndexPath* currentPath = [self indexPathForCurrentTextField];
   NSIndexPath* nextPath =
diff --git a/ios/chrome/browser/ui/settings/block_popups_collection_view_controller.mm b/ios/chrome/browser/ui/settings/block_popups_collection_view_controller.mm
index 39638f8..03f4656 100644
--- a/ios/chrome/browser/ui/settings/block_popups_collection_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/block_popups_collection_view_controller.mm
@@ -296,7 +296,7 @@
     if (entries[i].secondary_pattern == ContentSettingsPattern::Wildcard() &&
         entries[i].setting == CONTENT_SETTING_ALLOW) {
       _exceptions.Append(
-          new base::StringValue(entries[i].primary_pattern.ToString()));
+          new base::Value(entries[i].primary_pattern.ToString()));
     } else {
       LOG(ERROR) << "Secondary content settings patterns are not "
                  << "supported by the content settings UI";
diff --git a/ios/chrome/browser/ui/settings/cells/autofill_edit_item.h b/ios/chrome/browser/ui/settings/cells/autofill_edit_item.h
index 2c44f4c..dd8ca2e7 100644
--- a/ios/chrome/browser/ui/settings/cells/autofill_edit_item.h
+++ b/ios/chrome/browser/ui/settings/cells/autofill_edit_item.h
@@ -21,6 +21,9 @@
 // The value of the text field.
 @property(nonatomic, copy) NSString* textFieldValue;
 
+// An image corresponding to the type of the credit card, if any.
+@property(nonatomic, copy) UIImage* cardTypeIcon;
+
 // The field type this item is describing.
 @property(nonatomic, assign) autofill::ServerFieldType autofillType;
 
@@ -40,6 +43,9 @@
 // |textFieldValue|.
 @property(nonatomic, readonly, strong) UITextField* textField;
 
+// UIImageView containing the credit card type icon.
+@property(nonatomic, readonly, strong) UIImageView* cardTypeIconView;
+
 @end
 
 #endif  // IOS_CHROME_BROWSER_UI_SETTINGS_CELLS_AUTOFILL_EDIT_ITEM_H_
diff --git a/ios/chrome/browser/ui/settings/cells/autofill_edit_item.mm b/ios/chrome/browser/ui/settings/cells/autofill_edit_item.mm
index 0c17215..1db8055 100644
--- a/ios/chrome/browser/ui/settings/cells/autofill_edit_item.mm
+++ b/ios/chrome/browser/ui/settings/cells/autofill_edit_item.mm
@@ -28,6 +28,7 @@
 
 @synthesize textFieldName = _textFieldName;
 @synthesize textFieldValue = _textFieldValue;
+@synthesize cardTypeIcon = _cardTypeIcon;
 @synthesize textFieldEnabled = _textFieldEnabled;
 @synthesize autofillType = _autofillType;
 
@@ -56,6 +57,7 @@
   [cell.textField addTarget:self
                      action:@selector(textFieldChanged:)
            forControlEvents:UIControlEventEditingChanged];
+  cell.cardTypeIconView.image = self.cardTypeIcon;
 }
 
 #pragma mark - Actions
@@ -66,10 +68,15 @@
 
 @end
 
-@implementation AutofillEditCell
+@implementation AutofillEditCell {
+  NSLayoutConstraint* _iconHeightConstraint;
+  NSLayoutConstraint* _iconWidthConstraint;
+  NSLayoutConstraint* _textFieldTrailingConstraint;
+}
 
 @synthesize textField = _textField;
 @synthesize textLabel = _textLabel;
+@synthesize cardTypeIconView = _cardTypeIconView;
 
 - (instancetype)initWithFrame:(CGRect)frame {
   self = [super initWithFrame:frame];
@@ -101,6 +108,24 @@
     _textField.textAlignment =
         UseRTLLayout() ? NSTextAlignmentLeft : NSTextAlignmentRight;
 
+    // Card type icon.
+    _cardTypeIconView = [[UIImageView alloc] initWithFrame:CGRectZero];
+    _cardTypeIconView.layer.borderColor =
+        [UIColor colorWithWhite:0.9 alpha:1.0].CGColor;
+    _cardTypeIconView.layer.borderWidth = 1.0;
+    _cardTypeIconView.translatesAutoresizingMaskIntoConstraints = NO;
+    [contentView addSubview:_cardTypeIconView];
+
+    // Set up the icons size constraints. They are activated here and updated in
+    // layoutSubviews.
+    _iconHeightConstraint =
+        [_cardTypeIconView.heightAnchor constraintEqualToConstant:0];
+    _iconWidthConstraint =
+        [_cardTypeIconView.widthAnchor constraintEqualToConstant:0];
+
+    _textFieldTrailingConstraint = [_textField.trailingAnchor
+        constraintEqualToAnchor:_cardTypeIconView.leadingAnchor];
+
     // Set up the constraints.
     [NSLayoutConstraint activateConstraints:@[
       [_textLabel.leadingAnchor
@@ -110,14 +135,19 @@
                                            constant:kVerticalPadding],
       [_textLabel.bottomAnchor constraintEqualToAnchor:contentView.bottomAnchor
                                               constant:-kVerticalPadding],
-      [_textField.trailingAnchor
-          constraintEqualToAnchor:contentView.trailingAnchor
-                         constant:-kHorizontalPadding],
+      _textFieldTrailingConstraint,
       [_textField.firstBaselineAnchor
           constraintEqualToAnchor:_textLabel.firstBaselineAnchor],
       [_textField.leadingAnchor
           constraintEqualToAnchor:_textLabel.trailingAnchor
                          constant:kLabelAndFieldGap],
+      [_cardTypeIconView.trailingAnchor
+          constraintEqualToAnchor:contentView.trailingAnchor
+                         constant:-kHorizontalPadding],
+      [_cardTypeIconView.centerYAnchor
+          constraintEqualToAnchor:contentView.centerYAnchor],
+      _iconHeightConstraint,
+      _iconWidthConstraint,
     ]];
     [_textField setContentHuggingPriority:UILayoutPriorityDefaultLow
                                   forAxis:UILayoutConstraintAxisHorizontal];
@@ -125,6 +155,27 @@
   return self;
 }
 
+#pragma mark - UIView
+
+- (void)layoutSubviews {
+  if (self.cardTypeIconView.image) {
+    _textFieldTrailingConstraint.constant = -kLabelAndFieldGap;
+
+    // Set the size constraints of the icon view to the dimensions of the image.
+    _iconHeightConstraint.constant = self.cardTypeIconView.image.size.height;
+    _iconWidthConstraint.constant = self.cardTypeIconView.image.size.width;
+  } else {
+    _textFieldTrailingConstraint.constant = 0;
+
+    _iconHeightConstraint.constant = 0;
+    _iconWidthConstraint.constant = 0;
+  }
+
+  [super layoutSubviews];
+}
+
+#pragma mark - UICollectionReusableView
+
 - (void)prepareForReuse {
   [super prepareForReuse];
   self.textLabel.text = nil;
@@ -138,6 +189,7 @@
   [self.textField removeTarget:nil
                         action:nil
               forControlEvents:UIControlEventAllEvents];
+  self.cardTypeIconView.image = nil;
 }
 
 #pragma mark - Accessibility
diff --git a/ios/chrome/browser/ui/settings/material_cell_catalog_view_controller.mm b/ios/chrome/browser/ui/settings/material_cell_catalog_view_controller.mm
index dba5948..c475920 100644
--- a/ios/chrome/browser/ui/settings/material_cell_catalog_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/material_cell_catalog_view_controller.mm
@@ -7,6 +7,8 @@
 #import <UIKit/UIKit.h>
 
 #import "base/mac/foundation_util.h"
+#include "components/autofill/core/browser/autofill_data_util.h"
+#include "components/autofill/core/browser/credit_card.h"
 #include "components/grit/components_scaled_resources.h"
 #import "ios/chrome/browser/payments/cells/autofill_profile_item.h"
 #import "ios/chrome/browser/payments/cells/payments_text_item.h"
@@ -25,6 +27,7 @@
 #import "ios/chrome/browser/ui/settings/cells/account_control_item.h"
 #import "ios/chrome/browser/ui/settings/cells/account_signin_item.h"
 #import "ios/chrome/browser/ui/settings/cells/autofill_data_item.h"
+#import "ios/chrome/browser/ui/settings/cells/autofill_edit_item.h"
 #import "ios/chrome/browser/ui/settings/cells/native_app_item.h"
 #import "ios/chrome/browser/ui/settings/cells/sync_switch_item.h"
 #import "ios/chrome/browser/ui/settings/cells/text_and_error_item.h"
@@ -208,6 +211,10 @@
       toSectionWithIdentifier:SectionIdentifierAutofill];
   [model addItem:[self autofillItemWithAllText]
       toSectionWithIdentifier:SectionIdentifierAutofill];
+  [model addItem:[self autofillEditItem]
+      toSectionWithIdentifier:SectionIdentifierAutofill];
+  [model addItem:[self autofillEditItemWithIcon]
+      toSectionWithIdentifier:SectionIdentifierAutofill];
   [model addItem:[self cvcItem]
       toSectionWithIdentifier:SectionIdentifierAutofill];
   [model addItem:[self cvcItemWithDate]
@@ -533,6 +540,30 @@
   return item;
 }
 
+- (CollectionViewItem*)autofillEditItem {
+  AutofillEditItem* item = [[[AutofillEditItem alloc]
+      initWithType:ItemTypeAutofillDynamicHeight] autorelease];
+  item.textFieldName = @"Credit Number";
+  item.textFieldValue = @"4111111111111111";
+  item.textFieldEnabled = YES;
+  return item;
+}
+
+- (CollectionViewItem*)autofillEditItemWithIcon {
+  AutofillEditItem* item = [[[AutofillEditItem alloc]
+      initWithType:ItemTypeAutofillDynamicHeight] autorelease];
+  item.textFieldName = @"Credit Number";
+  item.textFieldValue = @"4111111111111111";
+  item.textFieldEnabled = YES;
+  int resourceID =
+      autofill::data_util::GetPaymentRequestData(autofill::kVisaCard)
+          .icon_resource_id;
+  item.cardTypeIcon =
+      ResizeImage(NativeImage(resourceID), CGSizeMake(30.0, 30.0),
+                  ProjectionMode::kAspectFillNoClipping);
+  return item;
+}
+
 - (CollectionViewItem*)cvcItem {
   CVCItem* item =
       [[[CVCItem alloc] initWithType:ItemTypeAutofillCVC] autorelease];
diff --git a/ios/chrome/browser/ui/static_content/static_html_view_controller.mm b/ios/chrome/browser/ui/static_content/static_html_view_controller.mm
index 750820d4..1b3b069 100644
--- a/ios/chrome/browser/ui/static_content/static_html_view_controller.mm
+++ b/ios/chrome/browser/ui/static_content/static_html_view_controller.mm
@@ -207,7 +207,7 @@
   decisionHandler(
       [self
           shouldStartLoadWithRequest:navigationAction.request
-                       fromMainFrame:[navigationAction.sourceFrame isMainFrame]]
+                       fromMainFrame:[navigationAction.targetFrame isMainFrame]]
           ? WKNavigationActionPolicyAllow
           : WKNavigationActionPolicyCancel);
 }
diff --git a/ios/chrome/browser/ui/toolbar/web_toolbar_controller.h b/ios/chrome/browser/ui/toolbar/web_toolbar_controller.h
index 16732f5..66febd2 100644
--- a/ios/chrome/browser/ui/toolbar/web_toolbar_controller.h
+++ b/ios/chrome/browser/ui/toolbar/web_toolbar_controller.h
@@ -12,6 +12,7 @@
 #include "ios/chrome/browser/ui/qr_scanner/qr_scanner_view_controller.h"
 #import "ios/chrome/browser/ui/toolbar/toolbar_controller.h"
 #include "ios/public/provider/chrome/browser/voice/voice_search_controller_delegate.h"
+#include "ios/web/public/navigation_item_list.h"
 
 @protocol PreloadProvider;
 @class Tab;
@@ -150,7 +151,7 @@
 
 // Shows the tab history popup inside |view|.
 - (void)showTabHistoryPopupInView:(UIView*)view
-               withSessionEntries:(NSArray*)sessionEntries
+                        withItems:(const web::NavigationItemList&)items
                    forBackHistory:(BOOL)isBackHistory;
 
 // Dismisses the tab history popup.
diff --git a/ios/chrome/browser/ui/toolbar/web_toolbar_controller.mm b/ios/chrome/browser/ui/toolbar/web_toolbar_controller.mm
index 498ce10..ee215e35 100644
--- a/ios/chrome/browser/ui/toolbar/web_toolbar_controller.mm
+++ b/ios/chrome/browser/ui/toolbar/web_toolbar_controller.mm
@@ -805,7 +805,7 @@
 }
 
 - (void)showTabHistoryPopupInView:(UIView*)view
-               withSessionEntries:(NSArray*)sessionEntries
+                        withItems:(const web::NavigationItemList&)items
                    forBackHistory:(BOOL)isBackHistory {
   if (_tabHistoryPopupController)
     return;
@@ -826,9 +826,15 @@
   _tabHistoryPopupController.reset([[TabHistoryPopupController alloc]
       initWithOrigin:convertedOrigin
           parentView:view
-             entries:sessionEntries]);
+               items:items]);
   [_tabHistoryPopupController setDelegate:self];
 
+  // Fade in the popup and notify observers.
+  CGRect containerFrame = [[_tabHistoryPopupController popupContainer] frame];
+  CGPoint destination = CGPointMake(CGRectGetLeadingEdge(containerFrame),
+                                    CGRectGetMinY(containerFrame));
+  [_tabHistoryPopupController fadeInPopupFromSource:convertedOrigin
+                                      toDestination:destination];
   [[NSNotificationCenter defaultCenter]
       postNotificationName:kTabHistoryPopupWillShowNotification
                     object:nil];
diff --git a/ios/chrome/browser/ui/webui/crashes_ui.cc b/ios/chrome/browser/ui/webui/crashes_ui.cc
index 088588f7..37ae935c 100644
--- a/ios/chrome/browser/ui/webui/crashes_ui.cc
+++ b/ios/chrome/browser/ui/webui/crashes_ui.cc
@@ -124,9 +124,9 @@
   base::Value enabled(crash_reporting_enabled);
   base::Value dynamic_backend(false);
   base::Value manual_uploads(false);
-  base::StringValue version(version_info::GetVersionNumber());
-  base::StringValue os_string(base::SysInfo::OperatingSystemName() + " " +
-                              base::SysInfo::OperatingSystemVersion());
+  base::Value version(version_info::GetVersionNumber());
+  base::Value os_string(base::SysInfo::OperatingSystemName() + " " +
+                        base::SysInfo::OperatingSystemVersion());
 
   std::vector<const base::Value*> args;
   args.push_back(&enabled);
diff --git a/ios/chrome/browser/ui/webui/sync_internals/sync_internals_message_handler.cc b/ios/chrome/browser/ui/webui/sync_internals/sync_internals_message_handler.cc
index 8ee1b614..4a136416 100644
--- a/ios/chrome/browser/ui/webui/sync_internals/sync_internals_message_handler.cc
+++ b/ios/chrome/browser/ui/webui/sync_internals/sync_internals_message_handler.cc
@@ -125,13 +125,12 @@
   ModelTypeSet protocol_types = syncer::ProtocolTypes();
   for (ModelTypeSet::Iterator it = protocol_types.First(); it.Good();
        it.Inc()) {
-    type_list->Append(new base::StringValue(ModelTypeToString(it.Get())));
+    type_list->Append(new base::Value(ModelTypeToString(it.Get())));
   }
   event_details.Set(syncer::sync_ui_util::kTypes, type_list.release());
   web_ui()->CallJavascriptFunction(
       syncer::sync_ui_util::kDispatchEvent,
-      base::StringValue(syncer::sync_ui_util::kOnReceivedListOfTypes),
-      event_details);
+      base::Value(syncer::sync_ui_util::kOnReceivedListOfTypes), event_details);
 }
 
 void SyncInternalsMessageHandler::HandleGetAllNodes(
@@ -167,7 +166,7 @@
       syncer::ProtocolEvent::ToValue(event));
   web_ui()->CallJavascriptFunction(
       syncer::sync_ui_util::kDispatchEvent,
-      base::StringValue(syncer::sync_ui_util::kOnProtocolEvent), *value);
+      base::Value(syncer::sync_ui_util::kOnProtocolEvent), *value);
 }
 
 void SyncInternalsMessageHandler::OnCommitCountersUpdated(
@@ -198,7 +197,7 @@
   details->Set(syncer::sync_ui_util::kCounters, value.release());
   web_ui()->CallJavascriptFunction(
       syncer::sync_ui_util::kDispatchEvent,
-      base::StringValue(syncer::sync_ui_util::kOnCountersUpdated), *details);
+      base::Value(syncer::sync_ui_util::kOnCountersUpdated), *details);
 }
 
 void SyncInternalsMessageHandler::HandleJsEvent(const std::string& name,
@@ -206,7 +205,7 @@
   DVLOG(1) << "Handling event: " << name << " with details "
            << details.ToString();
   web_ui()->CallJavascriptFunction(syncer::sync_ui_util::kDispatchEvent,
-                                   base::StringValue(name), details.Get());
+                                   base::Value(name), details.Get());
 }
 
 void SyncInternalsMessageHandler::SendAboutInfo() {
@@ -220,7 +219,7 @@
           sync_service, signin_manager, GetChannel());
   web_ui()->CallJavascriptFunction(
       syncer::sync_ui_util::kDispatchEvent,
-      base::StringValue(syncer::sync_ui_util::kOnAboutInfoUpdated), *value);
+      base::Value(syncer::sync_ui_util::kOnAboutInfoUpdated), *value);
 }
 
 // Gets the SyncService of the underlying original profile. May return null.
diff --git a/ios/chrome/browser/web/forms_egtest.mm b/ios/chrome/browser/web/forms_egtest.mm
index afa9c5b..2c598cf 100644
--- a/ios/chrome/browser/web/forms_egtest.mm
+++ b/ios/chrome/browser/web/forms_egtest.mm
@@ -22,6 +22,7 @@
 #import "ios/web/public/test/http_server.h"
 #import "ios/web/public/test/http_server_util.h"
 #include "ios/web/public/test/response_providers/data_response_provider.h"
+#include "ios/web/public/test/url_test_util.h"
 
 namespace {
 
@@ -276,8 +277,9 @@
   [self openBackHistory];
   [self waitForTabHistoryView];
 
-  id<GREYMatcher> historyItem = grey_text(base::SysUTF8ToNSString(
-      TestResponseProvider::GetPrintFormDataUrl().spec()));
+  GURL history_url = TestResponseProvider::GetPrintFormDataUrl();
+  id<GREYMatcher> historyItem = grey_text(
+      base::SysUTF16ToNSString(web::GetDisplayTitleForUrl(history_url)));
   [[EarlGrey selectElementWithMatcher:historyItem] performAction:grey_tap()];
 
   [ChromeEarlGrey waitForPageToFinishLoading];
diff --git a/ios/chrome/browser/web/visible_url_egtest.mm b/ios/chrome/browser/web/visible_url_egtest.mm
index 54f46b05..f14423f 100644
--- a/ios/chrome/browser/web/visible_url_egtest.mm
+++ b/ios/chrome/browser/web/visible_url_egtest.mm
@@ -18,6 +18,7 @@
 #import "ios/web/public/test/http_server.h"
 #include "ios/web/public/test/http_server_util.h"
 #include "ios/web/public/test/response_providers/html_response_provider.h"
+#include "ios/web/public/test/url_test_util.h"
 #include "url/gurl.h"
 
 using chrome_test_util::WebViewContainingText;
@@ -237,8 +238,9 @@
   // though URL1 is a pending URL.
   [[EarlGrey selectElementWithMatcher:chrome_test_util::BackButton()]
       performAction:grey_longPress()];
-  NSString* URL1Spec = base::SysUTF8ToNSString(_testURL1.spec());
-  [[EarlGrey selectElementWithMatcher:grey_text(URL1Spec)]
+  NSString* URL1Title =
+      base::SysUTF16ToNSString(web::GetDisplayTitleForUrl(_testURL1));
+  [[EarlGrey selectElementWithMatcher:grey_text(URL1Title)]
       performAction:grey_tap()];
   GREYAssert([self waitForServerToReceiveRequestWithURL:_testURL1],
              @"Last request URL: %@", self.lastRequestURLSpec);
diff --git a/ios/web/BUILD.gn b/ios/web/BUILD.gn
index 0f8e5334..150fdef 100644
--- a/ios/web/BUILD.gn
+++ b/ios/web/BUILD.gn
@@ -451,6 +451,7 @@
     "public/test/test_redirect_observer.mm",
     "public/test/test_web_thread.h",
     "public/test/test_web_thread_bundle.h",
+    "public/test/url_test_util.h",
     "public/test/web_js_test.h",
     "public/test/web_test.h",
     "public/test/web_test.mm",
@@ -465,6 +466,7 @@
     "test/test_url_constants.h",
     "test/test_web_thread.cc",
     "test/test_web_thread_bundle.cc",
+    "test/url_test_util.mm",
     "test/web_int_test.h",
     "test/web_int_test.mm",
     "test/web_test_suite.mm",
diff --git a/ios/web/navigation/navigation_item_impl.h b/ios/web/navigation/navigation_item_impl.h
index a47f1fa..7601f2d 100644
--- a/ios/web/navigation/navigation_item_impl.h
+++ b/ios/web/navigation/navigation_item_impl.h
@@ -119,6 +119,10 @@
   // non-persisted state, as documented on the members below.
   void ResetForCommit();
 
+  // Returns the title string to be used for a page with |url| if that page
+  // doesn't specify a title.
+  static base::string16 GetDisplayTitleForURL(const GURL& url);
+
  private:
   // The NavigationManItemStorageBuilder functions require access to
   // private variables of NavigationItemImpl.
diff --git a/ios/web/navigation/navigation_item_impl.mm b/ios/web/navigation/navigation_item_impl.mm
index 7e682a9d..6cf8acae 100644
--- a/ios/web/navigation/navigation_item_impl.mm
+++ b/ios/web/navigation/navigation_item_impl.mm
@@ -155,23 +155,8 @@
   if (!cached_display_title_.empty())
     return cached_display_title_;
 
-  // Use the virtual URL first if any, and fall back on using the real URL.
-  base::string16 title;
-  if (!virtual_url_.is_empty()) {
-    title = url_formatter::FormatUrl(virtual_url_);
-  } else if (!url_.is_empty()) {
-    title = url_formatter::FormatUrl(url_);
-  }
-
-  // For file:// URLs use the filename as the title, not the full path.
-  if (url_.SchemeIsFile()) {
-    base::string16::size_type slashpos = title.rfind('/');
-    if (slashpos != base::string16::npos)
-      title = title.substr(slashpos + 1);
-  }
-
-  const size_t kMaxTitleChars = 4 * 1024;
-  gfx::ElideString(title, kMaxTitleChars, &cached_display_title_);
+  cached_display_title_ =
+      NavigationItemImpl::GetDisplayTitleForURL(GetVirtualURL());
   return cached_display_title_;
 }
 
@@ -312,4 +297,23 @@
   SetNavigationInitiationType(web::NavigationInitiationType::NONE);
 }
 
+// static
+base::string16 NavigationItemImpl::GetDisplayTitleForURL(const GURL& url) {
+  if (url.is_empty())
+    return base::string16();
+
+  base::string16 title = url_formatter::FormatUrl(url);
+
+  // For file:// URLs use the filename as the title, not the full path.
+  if (url.SchemeIsFile()) {
+    base::string16::size_type slashpos = title.rfind('/');
+    if (slashpos != base::string16::npos)
+      title = title.substr(slashpos + 1);
+  }
+
+  const size_t kMaxTitleChars = 4 * 1024;
+  gfx::ElideString(title, kMaxTitleChars, &title);
+  return title;
+}
+
 }  // namespace web
diff --git a/ios/web/public/test/url_test_util.h b/ios/web/public/test/url_test_util.h
new file mode 100644
index 0000000..ac159c6
--- /dev/null
+++ b/ios/web/public/test/url_test_util.h
@@ -0,0 +1,20 @@
+// Copyright 2017 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 IOS_WEB_PUBLIC_TEST_URL_TEST_UTIL_H_
+#define IOS_WEB_PUBLIC_TEST_URL_TEST_UTIL_H_
+
+#include "base/strings/string16.h"
+
+class GURL;
+
+namespace web {
+
+// Returns a formatted version of |url| that would be used as the fallback title
+// for a page with that URL.
+base::string16 GetDisplayTitleForUrl(const GURL& url);
+
+}  // namespace web
+
+#endif  // IOS_WEB_PUBLIC_TEST_URL_TEST_UTIL_H_
diff --git a/ios/web/test/url_test_util.mm b/ios/web/test/url_test_util.mm
new file mode 100644
index 0000000..bfb9ed5
--- /dev/null
+++ b/ios/web/test/url_test_util.mm
@@ -0,0 +1,15 @@
+// Copyright 2017 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 "ios/web/public/test/url_test_util.h"
+
+#import "ios/web/navigation/navigation_item_impl.h"
+
+namespace web {
+
+base::string16 GetDisplayTitleForUrl(const GURL& url) {
+  return NavigationItemImpl::GetDisplayTitleForURL(url);
+}
+
+}  // namespace web
diff --git a/ios/web/web_state/ui/web_view_js_utils.mm b/ios/web/web_state/ui/web_view_js_utils.mm
index 50e4f42..b7aade32 100644
--- a/ios/web/web_state/ui/web_view_js_utils.mm
+++ b/ios/web/web_state/ui/web_view_js_utils.mm
@@ -32,7 +32,7 @@
 
   CFTypeID result_type = CFGetTypeID(wk_result);
   if (result_type == CFStringGetTypeID()) {
-    result.reset(new base::StringValue(base::SysNSStringToUTF16(wk_result)));
+    result.reset(new base::Value(base::SysNSStringToUTF16(wk_result)));
     DCHECK(result->IsType(base::Value::Type::STRING));
   } else if (result_type == CFNumberGetTypeID()) {
     result.reset(new base::Value([wk_result doubleValue]));
diff --git a/ios/web_view/internal/cwv_web_view.mm b/ios/web_view/internal/cwv_web_view.mm
index 7f93a2f..35c169e 100644
--- a/ios/web_view/internal/cwv_web_view.mm
+++ b/ios/web_view/internal/cwv_web_view.mm
@@ -39,15 +39,15 @@
   std::unique_ptr<web::WebStateObserverBridge> _webStateObserver;
   std::unique_ptr<ios_web_view::WebViewWebStatePolicyDecider>
       _webStatePolicyDecider;
-  CGFloat _loadProgress;
+  double _estimatedProgress;
   // Handles presentation of JavaScript dialogs.
   std::unique_ptr<ios_web_view::WebViewJavaScriptDialogPresenter>
       _javaScriptDialogPresenter;
 }
 
-// Redefine the property as readwrite to define -setLoadProgress:, which can be
-// used to send KVO notification.
-@property(nonatomic, readwrite) CGFloat loadProgress;
+// Redefine the property as readwrite to define -setEstimatedProgress:, which
+// can be used to send KVO notification.
+@property(nonatomic, readwrite) double estimatedProgress;
 
 @end
 
@@ -55,7 +55,7 @@
 
 @synthesize navigationDelegate = _navigationDelegate;
 @synthesize translationDelegate = _translationDelegate;
-@synthesize loadProgress = _loadProgress;
+@synthesize estimatedProgress = _estimatedProgress;
 @synthesize UIDelegate = _UIDelegate;
 
 - (instancetype)initWithFrame:(CGRect)frame
@@ -63,6 +63,7 @@
   self = [super initWithFrame:frame];
   if (self) {
     _configuration = [configuration copy];
+    _estimatedProgress = 0.0;
 
     web::WebState::CreateParams webStateCreateParams(
         [configuration.websiteDataStore browserState]);
@@ -196,7 +197,7 @@
 
 - (void)webState:(web::WebState*)webState
     didChangeLoadingProgress:(double)progress {
-  self.loadProgress = progress;
+  self.estimatedProgress = progress;
 }
 
 - (void)renderProcessGoneForWebState:(web::WebState*)webState {
diff --git a/ios/web_view/public/cwv_web_view.h b/ios/web_view/public/cwv_web_view.h
index c81d8ea..b8e5f73c4 100644
--- a/ios/web_view/public/cwv_web_view.h
+++ b/ios/web_view/public/cwv_web_view.h
@@ -45,9 +45,12 @@
 // The current page title.
 @property(nonatomic, readonly) NSString* pageTitle;
 
-// The current load progress, as a fraction between 0 and 1.  This value is
-// undefined if the web view is not currently loading.
-@property(nonatomic, readonly) CGFloat loadProgress;
+// Page loading progress from 0.0 to 1.0. KVO compliant.
+//
+// It is 0.0 initially before the first navigation starts. After a navigation
+// completes, it remains at 1.0 until a new navigation starts, at which point it
+// is reset to 0.0.
+@property(nonatomic, readonly) double estimatedProgress;
 
 // |configuration| must not be null
 - (instancetype)initWithFrame:(CGRect)frame
diff --git a/ipc/ipc_message_unittest.cc b/ipc/ipc_message_unittest.cc
index bde96a1..fd08452 100644
--- a/ipc/ipc_message_unittest.cc
+++ b/ipc/ipc_message_unittest.cc
@@ -66,7 +66,7 @@
 TEST(IPCMessageTest, ListValue) {
   base::ListValue input;
   input.Set(0, new base::Value(42.42));
-  input.Set(1, new base::StringValue("forty"));
+  input.Set(1, new base::Value("forty"));
   input.Set(2, base::Value::CreateNullValue());
 
   IPC::Message msg(1, 2, IPC::Message::PRIORITY_NORMAL);
@@ -93,13 +93,13 @@
   input.SetWithoutPathExpansion("int.with.dot", new base::Value(43));
 
   std::unique_ptr<base::DictionaryValue> subdict(new base::DictionaryValue());
-  subdict->Set("str", new base::StringValue("forty two"));
+  subdict->Set("str", new base::Value("forty two"));
   subdict->Set("bool", new base::Value(false));
 
   std::unique_ptr<base::ListValue> sublist(new base::ListValue());
   sublist->Set(0, new base::Value(42.42));
-  sublist->Set(1, new base::StringValue("forty"));
-  sublist->Set(2, new base::StringValue("two"));
+  sublist->Set(1, new base::Value("forty"));
+  sublist->Set(2, new base::Value("two"));
   subdict->Set("list", sublist.release());
 
   input.Set("dict", subdict.release());
diff --git a/ipc/ipc_message_utils.cc b/ipc/ipc_message_utils.cc
index 328e804..bf8daa5 100644
--- a/ipc/ipc_message_utils.cc
+++ b/ipc/ipc_message_utils.cc
@@ -96,7 +96,7 @@
       sizer->AddDouble();
       break;
     case base::Value::Type::STRING: {
-      const base::StringValue* result;
+      const base::Value* result;
       value->GetAsString(&result);
       if (value->GetAsString(&result)) {
         DCHECK(result);
@@ -289,7 +289,7 @@
       std::string val;
       if (!ReadParam(m, iter, &val))
         return false;
-      *value = new base::StringValue(val);
+      *value = new base::Value(val);
       break;
     }
     case base::Value::Type::BINARY: {
diff --git a/ipc/ipc_message_utils_unittest.cc b/ipc/ipc_message_utils_unittest.cc
index dae8675..36b0dbd 100644
--- a/ipc/ipc_message_utils_unittest.cc
+++ b/ipc/ipc_message_utils_unittest.cc
@@ -99,7 +99,7 @@
   std::unique_ptr<base::DictionaryValue> value(new base::DictionaryValue);
   value->SetWithoutPathExpansion("foo", new base::Value(42));
   value->SetWithoutPathExpansion("bar", new base::Value(3.14));
-  value->SetWithoutPathExpansion("baz", new base::StringValue("hello"));
+  value->SetWithoutPathExpansion("baz", new base::Value("hello"));
   value->SetWithoutPathExpansion("qux", base::Value::CreateNullValue());
 
   std::unique_ptr<base::DictionaryValue> nested_dict(new base::DictionaryValue);
diff --git a/media/base/pipeline_impl.cc b/media/base/pipeline_impl.cc
index f8761f4..a1e47d1e 100644
--- a/media/base/pipeline_impl.cc
+++ b/media/base/pipeline_impl.cc
@@ -505,7 +505,9 @@
   // implementations call DemuxerHost on the media thread.
   media_log_->AddEvent(media_log_->CreateTimeEvent(MediaLogEvent::DURATION_SET,
                                                    "duration", duration));
-  UMA_HISTOGRAM_LONG_TIMES("Media.Duration", duration);
+  UMA_HISTOGRAM_CUSTOM_TIMES(
+      "Media.Duration2", duration, base::TimeDelta::FromMilliseconds(1),
+      base::TimeDelta::FromDays(1), 50 /* bucket_count */);
 
   main_task_runner_->PostTask(
       FROM_HERE,
diff --git a/media/gpu/jpeg_decode_accelerator_unittest.cc b/media/gpu/jpeg_decode_accelerator_unittest.cc
index 00fa4f5..aa1f42d 100644
--- a/media/gpu/jpeg_decode_accelerator_unittest.cc
+++ b/media/gpu/jpeg_decode_accelerator_unittest.cc
@@ -475,7 +475,7 @@
 }
 
 TEST_F(JpegDecodeAcceleratorTest, SimpleDecode) {
-  for (const auto& image : g_env->image_data_user_) {
+  for (auto* image : g_env->image_data_user_) {
     test_image_files_.push_back(image);
     expected_status_.push_back(CS_DECODE_PASS);
   }
@@ -483,7 +483,7 @@
 }
 
 TEST_F(JpegDecodeAcceleratorTest, MultipleDecoders) {
-  for (const auto& image : g_env->image_data_user_) {
+  for (auto* image : g_env->image_data_user_) {
     test_image_files_.push_back(image);
     expected_status_.push_back(CS_DECODE_PASS);
   }
diff --git a/mojo/common/common_custom_types_unittest.cc b/mojo/common/common_custom_types_unittest.cc
index fe61a35cd..e3571d9 100644
--- a/mojo/common/common_custom_types_unittest.cc
+++ b/mojo/common/common_custom_types_unittest.cc
@@ -290,7 +290,7 @@
   ASSERT_TRUE(ptr->BounceValue(input->CreateDeepCopy(), &output));
   EXPECT_TRUE(base::Value::Equals(input.get(), output.get()));
 
-  input = base::MakeUnique<base::StringValue>("test string");
+  input = base::MakeUnique<base::Value>("test string");
   ASSERT_TRUE(ptr->BounceValue(input->CreateDeepCopy(), &output));
   EXPECT_TRUE(base::Value::Equals(input.get(), output.get()));
 
diff --git a/mojo/common/values_struct_traits.cc b/mojo/common/values_struct_traits.cc
index 9c5df7a..6af7a395 100644
--- a/mojo/common/values_struct_traits.cc
+++ b/mojo/common/values_struct_traits.cc
@@ -77,7 +77,7 @@
       base::StringPiece string_value;
       if (!data.ReadStringValue(&string_value))
         return false;
-      *value_out = base::MakeUnique<base::StringValue>(string_value);
+      *value_out = base::MakeUnique<base::Value>(string_value);
       return true;
     }
     case common::mojom::ValueDataView::Tag::BINARY_VALUE: {
diff --git a/mojo/public/cpp/bindings/struct_ptr.h b/mojo/public/cpp/bindings/struct_ptr.h
index a01c42f..b135312e 100644
--- a/mojo/public/cpp/bindings/struct_ptr.h
+++ b/mojo/public/cpp/bindings/struct_ptr.h
@@ -228,7 +228,7 @@
 class StructPtrWTFHelper {
  public:
   static bool IsHashTableDeletedValue(const StructPtr<Struct>& value) {
-    return value.ptr_ == reinterpret_cast<Struct*>(1u);
+    return value.ptr_.get() == reinterpret_cast<Struct*>(1u);
   }
 
   static void ConstructDeletedValue(mojo::StructPtr<Struct>& slot) {
@@ -239,7 +239,7 @@
     // Dirty trick: implant an invalid pointer in |ptr_|. Destructor isn't
     // called for deleted buckets, so this is okay.
     new (&slot) StructPtr<Struct>();
-    slot.ptr_ = reinterpret_cast<Struct*>(1u);
+    slot.ptr_.reset(reinterpret_cast<Struct*>(1u));
   }
 };
 
diff --git a/mojo/public/cpp/bindings/tests/BUILD.gn b/mojo/public/cpp/bindings/tests/BUILD.gn
index 71305b8e..6244226 100644
--- a/mojo/public/cpp/bindings/tests/BUILD.gn
+++ b/mojo/public/cpp/bindings/tests/BUILD.gn
@@ -21,6 +21,7 @@
     "handle_passing_unittest.cc",
     "hash_unittest.cc",
     "interface_ptr_unittest.cc",
+    "map_unittest.cc",
     "message_queue.cc",
     "message_queue.h",
     "multiplex_router_unittest.cc",
@@ -80,6 +81,7 @@
       "container_test_util.h",
       "variant_test_util.h",
       "wtf_hash_unittest.cc",
+      "wtf_map_unittest.cc",
       "wtf_types_unittest.cc",
     ]
 
diff --git a/mojo/public/cpp/bindings/tests/map_unittest.cc b/mojo/public/cpp/bindings/tests/map_unittest.cc
new file mode 100644
index 0000000..8d630a5
--- /dev/null
+++ b/mojo/public/cpp/bindings/tests/map_unittest.cc
@@ -0,0 +1,46 @@
+// Copyright 2017 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 <stddef.h>
+#include <stdint.h>
+#include <unordered_map>
+#include <utility>
+
+#include "mojo/public/cpp/bindings/tests/rect_chromium.h"
+#include "mojo/public/interfaces/bindings/tests/rect.mojom.h"
+#include "mojo/public/interfaces/bindings/tests/test_structs.mojom.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace mojo {
+namespace test {
+namespace {
+
+TEST(MapTest, StructKey) {
+  std::unordered_map<RectPtr, int32_t> map;
+  map.insert(std::make_pair(Rect::New(1, 2, 3, 4), 123));
+
+  RectPtr key = Rect::New(1, 2, 3, 4);
+  ASSERT_NE(map.end(), map.find(key));
+  ASSERT_EQ(123, map.find(key)->second);
+
+  map.erase(key);
+  ASSERT_EQ(0u, map.size());
+}
+
+TEST(MapTest, TypemappedStructKey) {
+  std::unordered_map<ContainsHashablePtr, int32_t> map;
+  map.insert(
+      std::make_pair(ContainsHashable::New(RectChromium(1, 2, 3, 4)), 123));
+
+  ContainsHashablePtr key = ContainsHashable::New(RectChromium(1, 2, 3, 4));
+  ASSERT_NE(map.end(), map.find(key));
+  ASSERT_EQ(123, map.find(key)->second);
+
+  map.erase(key);
+  ASSERT_EQ(0u, map.size());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace mojo
diff --git a/mojo/public/cpp/bindings/tests/wtf_hash_unittest.cc b/mojo/public/cpp/bindings/tests/wtf_hash_unittest.cc
index 2fc2a67..959d25b 100644
--- a/mojo/public/cpp/bindings/tests/wtf_hash_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/wtf_hash_unittest.cc
@@ -5,7 +5,9 @@
 #include "mojo/public/cpp/bindings/lib/wtf_hash_util.h"
 
 #include "mojo/public/interfaces/bindings/tests/test_structs.mojom-blink.h"
+#include "mojo/public/interfaces/bindings/tests/test_wtf_types.mojom-blink.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/Source/wtf/HashFunctions.h"
 
 namespace mojo {
 namespace test {
@@ -31,6 +33,28 @@
                                    blink::UnmappedNativeStruct::New()));
 }
 
+TEST_F(WTFHashTest, Enum) {
+  // Just check that this template instantiation compiles.
+
+  // Top-level.
+  ASSERT_EQ(WTF::DefaultHash<blink::TopLevelEnum>::Hash().hash(
+                blink::TopLevelEnum::E0),
+            WTF::DefaultHash<blink::TopLevelEnum>::Hash().hash(
+                blink::TopLevelEnum::E0));
+
+  // Nested in struct.
+  ASSERT_EQ(WTF::DefaultHash<blink::TestWTFStruct::NestedEnum>::Hash().hash(
+                blink::TestWTFStruct::NestedEnum::E0),
+            WTF::DefaultHash<blink::TestWTFStruct::NestedEnum>::Hash().hash(
+                blink::TestWTFStruct::NestedEnum::E0));
+
+  // Nested in interface.
+  ASSERT_EQ(WTF::DefaultHash<blink::TestWTF::NestedEnum>::Hash().hash(
+                blink::TestWTF::NestedEnum::E0),
+            WTF::DefaultHash<blink::TestWTF::NestedEnum>::Hash().hash(
+                blink::TestWTF::NestedEnum::E0));
+}
+
 }  // namespace
 }  // namespace test
 }  // namespace mojo
diff --git a/mojo/public/cpp/bindings/tests/wtf_map_unittest.cc b/mojo/public/cpp/bindings/tests/wtf_map_unittest.cc
new file mode 100644
index 0000000..5028087
--- /dev/null
+++ b/mojo/public/cpp/bindings/tests/wtf_map_unittest.cc
@@ -0,0 +1,41 @@
+// Copyright 2017 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 "mojo/public/cpp/bindings/tests/rect_blink.h"
+#include "mojo/public/interfaces/bindings/tests/rect.mojom-blink.h"
+#include "mojo/public/interfaces/bindings/tests/test_structs.mojom-blink.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace mojo {
+namespace test {
+namespace {
+
+TEST(WTFMapTest, StructKey) {
+  WTF::HashMap<blink::RectPtr, int32_t> map;
+  map.insert(blink::Rect::New(1, 2, 3, 4), 123);
+
+  blink::RectPtr key = blink::Rect::New(1, 2, 3, 4);
+  ASSERT_NE(map.end(), map.find(key));
+  ASSERT_EQ(123, map.find(key)->value);
+
+  map.remove(key);
+  ASSERT_EQ(0u, map.size());
+}
+
+TEST(WTFMapTest, TypemappedStructKey) {
+  WTF::HashMap<blink::ContainsHashablePtr, int32_t> map;
+  map.insert(blink::ContainsHashable::New(RectBlink(1, 2, 3, 4)), 123);
+
+  blink::ContainsHashablePtr key =
+      blink::ContainsHashable::New(RectBlink(1, 2, 3, 4));
+  ASSERT_NE(map.end(), map.find(key));
+  ASSERT_EQ(123, map.find(key)->value);
+
+  map.remove(key);
+  ASSERT_EQ(0u, map.size());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace mojo
diff --git a/mojo/public/interfaces/bindings/tests/test_wtf_types.mojom b/mojo/public/interfaces/bindings/tests/test_wtf_types.mojom
index 2fdbea8..183f184 100644
--- a/mojo/public/interfaces/bindings/tests/test_wtf_types.mojom
+++ b/mojo/public/interfaces/bindings/tests/test_wtf_types.mojom
@@ -25,13 +25,26 @@
 };
 
 struct TestWTFStruct {
+  enum NestedEnum {
+    E0,
+    E1,
+  };
   string str;
   int32 integer;
 };
 
 interface TestWTF {
+  enum NestedEnum {
+    E0,
+    E1,
+  };
   EchoString(string? str) => (string? str);
   EchoStringArray(array<string?>? arr) => (array<string?>? arr);
   EchoStringMap(map<string, string?>? str_map)
       => (map<string, string?>? str_map);
 };
+
+enum TopLevelEnum {
+  E0,
+  E1,
+};
diff --git a/mojo/public/tools/bindings/blink_bindings_configuration.gni b/mojo/public/tools/bindings/blink_bindings_configuration.gni
index cdf93b6..bb0fc43 100644
--- a/mojo/public/tools/bindings/blink_bindings_configuration.gni
+++ b/mojo/public/tools/bindings/blink_bindings_configuration.gni
@@ -30,8 +30,4 @@
       } ]
 }
 
-blacklist = [
-  # TODO(sammc): Remove the following once |for_blink| bindings support WTF
-  # maps with enum keys. See https://crbug.com/583738.
-  "//mojo/public/interfaces/bindings/tests/validation_test_interfaces.mojom",
-]
+blacklist = []
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/enum_macros.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/enum_macros.tmpl
index 9400ca7..92073bc 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/enum_macros.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/enum_macros.tmpl
@@ -78,3 +78,50 @@
 struct hash<{{enum_name}}>
     : public mojo::internal::EnumHashImpl<{{enum_name}}> {};
 {%- endmacro %}
+
+{%- macro enum_hash_blink(enum) %}
+{%-   set enum_name = enum|get_qualified_name_for_kind(
+          flatten_nested_kind=True, include_variant=False) %}
+{%-   set hash_fn_name = enum|wtf_hash_fn_name_for_enum %}
+{#    We need two unused enum values: #}
+{%-   set empty_value = -1000000 %}
+{%-   set deleted_value = -1000001 %}
+{%-   set empty_value_unused = "false" if empty_value in enum|all_enum_values else "true" %}
+{%-   set deleted_value_unused = "false" if empty_value in enum|all_enum_values else "true" %}
+namespace WTF {
+struct {{hash_fn_name}} {
+  static unsigned hash(const {{enum_name}}& value) {
+    typedef base::underlying_type<{{enum_name}}>::type utype;
+    return DefaultHash<utype>::Hash().hash(static_cast<utype>(value));
+  }
+  static bool equal(const {{enum_name}}& left, const {{enum_name}}& right) {
+    return left == right;
+  }
+  static const bool safeToCompareToEmptyOrDeleted = true;
+};
+
+template <>
+struct DefaultHash<{{enum_name}}> {
+  using Hash = {{hash_fn_name}};
+};
+
+template <>
+struct HashTraits<{{enum_name}}>
+    : public GenericHashTraits<{{enum_name}}> {
+  static_assert({{empty_value_unused}},
+                "{{empty_value}} is a reserved enum value");
+  static_assert({{deleted_value_unused}},
+                "{{deleted_value}} is a reserved enum value");
+  static const bool hasIsEmptyValueFunction = true;
+  static bool isEmptyValue(const {{enum_name}}& value) {
+    return value == static_cast<{{enum_name}}>({{empty_value}});
+  }
+  static void constructDeletedValue({{enum_name}}& slot, bool) {
+    slot = static_cast<{{enum_name}}>({{deleted_value}});
+  }
+  static bool isDeletedValue(const {{enum_name}}& value) {
+    return value == static_cast<{{enum_name}}>({{deleted_value}});
+  }
+};
+}  // namespace WTF
+{%- endmacro %}
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl
index 9306d2f8..acdad5e 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl
@@ -86,6 +86,16 @@
 #include "{{export_header}}"
 {%- endif %}
 
+{#--- WTF enum hashing #}
+{%- from "enum_macros.tmpl" import enum_hash_blink%}
+{%- if for_blink %}
+{%-   for enum in all_enums %}
+{%-     if not enum|is_native_only_kind %}
+{{enum_hash_blink(enum)}}
+{%-     endif %}
+{%-   endfor %}
+{%- endif %}
+
 {{namespace_begin()}}
 
 {#--- Enums #}
diff --git a/mojo/public/tools/bindings/generators/mojom_cpp_generator.py b/mojo/public/tools/bindings/generators/mojom_cpp_generator.py
index 87e39ecb..38d222b 100644
--- a/mojo/public/tools/bindings/generators/mojom_cpp_generator.py
+++ b/mojo/public/tools/bindings/generators/mojom_cpp_generator.py
@@ -153,10 +153,19 @@
       internal=internal, flatten_nested_kind=flatten_nested_kind,
       add_same_module_namespaces=add_same_module_namespaces)
 
-def GetQualifiedNameForKind(kind, internal=False, flatten_nested_kind=False):
-  return _NameFormatter(kind, _variant).FormatForCpp(
-      internal=internal, add_same_module_namespaces=True,
-      flatten_nested_kind=flatten_nested_kind)
+def GetQualifiedNameForKind(kind, internal=False, flatten_nested_kind=False,
+                            include_variant=True):
+  return _NameFormatter(
+      kind, _variant if include_variant else None).FormatForCpp(
+          internal=internal, add_same_module_namespaces=True,
+          flatten_nested_kind=flatten_nested_kind)
+
+
+def GetWtfHashFnNameForEnum(enum):
+  return _NameFormatter(
+      enum, None).Format("_", internal=True, add_same_module_namespaces=True,
+                         flatten_nested_kind=True) + "HashFn"
+
 
 def GetFullMojomNameForKind(kind):
   return _NameFormatter(kind, _variant).FormatForMojom()
@@ -211,6 +220,18 @@
   return Check(kind)
 
 
+def AllEnumValues(enum):
+  """Return all enum values associated with an enum.
+
+  Args:
+    enum: {mojom.Enum} The enum type.
+
+  Returns:
+   {Set[int]} The values.
+  """
+  return set(field.numeric_value for field in enum.fields)
+
+
 def GetNativeTypeName(typemapped_kind):
   return _current_typemap[GetFullMojomNameForKind(typemapped_kind)]["typename"]
 
@@ -584,6 +605,7 @@
 class Generator(generator.Generator):
 
   cpp_filters = {
+    "all_enum_values": AllEnumValues,
     "constant_value": ConstantValue,
     "contains_handles_or_interfaces": mojom.ContainsHandlesOrInterfaces,
     "contains_move_only_members": ContainsMoveOnlyMembers,
@@ -630,6 +652,7 @@
     "stylize_method": generator.StudlyCapsToCamel,
     "under_to_camel": generator.UnderToCamel,
     "unmapped_type_for_serializer": GetUnmappedTypeForSerializer,
+    "wtf_hash_fn_name_for_enum": GetWtfHashFnNameForEnum,
   }
 
   def GetExtraTraitsHeaders(self):
diff --git a/mojo/public/tools/bindings/pylib/mojom/generate/module.py b/mojo/public/tools/bindings/pylib/mojom/generate/module.py
index df9c2c5..3a5f188e 100644
--- a/mojo/public/tools/bindings/pylib/mojom/generate/module.py
+++ b/mojo/public/tools/bindings/pylib/mojom/generate/module.py
@@ -303,7 +303,7 @@
     module: {Module} The defining module.
     imported_from: {dict} Information about where this union was
         imported from.
-    fields: {List[StructField]} The members of the union.
+    fields: {List[StructField]} The members of the struct.
     attributes: {dict} Additional information about the struct, such as
         if it's a native struct.
   """
diff --git a/net/BUILD.gn b/net/BUILD.gn
index 63e6426..1f483d3 100644
--- a/net/BUILD.gn
+++ b/net/BUILD.gn
@@ -1261,10 +1261,6 @@
       "quic/core/quic_headers_stream.cc",
       "quic/core/quic_headers_stream.h",
       "quic/core/quic_iovector.h",
-      "quic/core/quic_multipath_received_packet_manager.cc",
-      "quic/core/quic_multipath_received_packet_manager.h",
-      "quic/core/quic_multipath_transmissions_map.cc",
-      "quic/core/quic_multipath_transmissions_map.h",
       "quic/core/quic_one_block_arena.h",
       "quic/core/quic_packet_creator.cc",
       "quic/core/quic_packet_creator.h",
@@ -4344,6 +4340,7 @@
     "log/trace_net_log_observer_unittest.cc",
     "log/write_to_file_net_log_observer_unittest.cc",
     "nqe/effective_connection_type_unittest.cc",
+    "nqe/event_creator_unittest.cc",
     "nqe/network_qualities_prefs_manager_unittest.cc",
     "nqe/network_quality_estimator_unittest.cc",
     "nqe/network_quality_store_unittest.cc",
diff --git a/net/cert/cert_verifier.h b/net/cert/cert_verifier.h
index be510119..50cc833 100644
--- a/net/cert/cert_verifier.h
+++ b/net/cert/cert_verifier.h
@@ -79,6 +79,11 @@
     // If set, certificates with SHA-1 signatures will be allowed, but only if
     // they are issued by non-public trust anchors.
     VERIFY_ENABLE_SHA1_LOCAL_ANCHORS = 1 << 5,
+
+    // If set, certificates which lack a subjectAltName will be allowed to
+    // match against the commonName of the certificate, but only if they are
+    // issued by non-public trust anchors.
+    VERIFY_ENABLE_COMMON_NAME_FALLBACK_LOCAL_ANCHORS = 1 << 6,
   };
 
   // Parameters to verify |certificate| against the supplied
diff --git a/net/cert/cert_verify_proc.cc b/net/cert/cert_verify_proc.cc
index 175deb6..7ce4eae 100644
--- a/net/cert/cert_verify_proc.cc
+++ b/net/cert/cert_verify_proc.cc
@@ -485,19 +485,14 @@
 
   ComputeSignatureHashAlgorithms(verify_result);
 
-  if (!cert->VerifyNameMatch(hostname,
-                             &verify_result->common_name_fallback_used)) {
+  bool allow_common_name_fallback =
+      !verify_result->is_issued_by_known_root &&
+      (flags & CertVerifier::VERIFY_ENABLE_COMMON_NAME_FALLBACK_LOCAL_ANCHORS);
+  if (!cert->VerifyNameMatch(hostname, allow_common_name_fallback)) {
     verify_result->cert_status |= CERT_STATUS_COMMON_NAME_INVALID;
     rv = MapCertStatusToNetError(verify_result->cert_status);
   }
 
-  UMA_HISTOGRAM_BOOLEAN("Net.CertCommonNameFallback",
-                        verify_result->common_name_fallback_used);
-  if (!verify_result->is_issued_by_known_root) {
-    UMA_HISTOGRAM_BOOLEAN("Net.CertCommonNameFallbackPrivateCA",
-                          verify_result->common_name_fallback_used);
-  }
-
   CheckOCSP(ocsp_response, *verify_result->verified_cert,
             &verify_result->ocsp_result);
 
diff --git a/net/cert/cert_verify_proc_android.cc b/net/cert/cert_verify_proc_android.cc
index 5c29b67..430ae631 100644
--- a/net/cert/cert_verify_proc_android.cc
+++ b/net/cert/cert_verify_proc_android.cc
@@ -398,6 +398,7 @@
     NOTREACHED();
     return ERR_FAILED;
   }
+
   if (IsCertStatusError(verify_result->cert_status))
     return MapCertStatusToNetError(verify_result->cert_status);
 
diff --git a/net/cert/cert_verify_proc_ios.cc b/net/cert/cert_verify_proc_ios.cc
index 42746499..84ecd2a 100644
--- a/net/cert/cert_verify_proc_ios.cc
+++ b/net/cert/cert_verify_proc_ios.cc
@@ -266,6 +266,9 @@
 
   GetCertChainInfo(final_chain, verify_result);
 
+  // iOS lacks the ability to distinguish built-in versus non-built-in roots,
+  // so opt to 'fail open' of any restrictive policies that apply to built-in
+  // roots.
   verify_result->is_issued_by_known_root = false;
 
   if (IsCertStatusError(verify_result->cert_status))
diff --git a/net/cert/cert_verify_proc_mac.cc b/net/cert/cert_verify_proc_mac.cc
index 987eed2..234d959 100644
--- a/net/cert/cert_verify_proc_mac.cc
+++ b/net/cert/cert_verify_proc_mac.cc
@@ -988,8 +988,8 @@
       break;
   }
 
-  // Perform hostname verification independent of SecTrustEvaluate. In order to
-  // do so, mask off any reported name errors first.
+  // Hostname validation is handled by CertVerifyProc, so mask off any errors
+  // that SecTrustEvaluate may have set, as its results are not used.
   verify_result->cert_status &= ~CERT_STATUS_COMMON_NAME_INVALID;
 
   // TODO(wtc): Suppress CERT_STATUS_NO_REVOCATION_MECHANISM for now to be
diff --git a/net/cert/cert_verify_proc_openssl.cc b/net/cert/cert_verify_proc_openssl.cc
index 2d28e49a..13a19d8 100644
--- a/net/cert/cert_verify_proc_openssl.cc
+++ b/net/cert/cert_verify_proc_openssl.cc
@@ -214,6 +214,7 @@
 
   GetCertChainInfo(ctx.get(), verify_result);
   AppendPublicKeyHashes(ctx.get(), &verify_result->public_key_hashes);
+
   if (IsCertStatusError(verify_result->cert_status))
     return MapCertStatusToNetError(verify_result->cert_status);
 
diff --git a/net/cert/cert_verify_proc_unittest.cc b/net/cert/cert_verify_proc_unittest.cc
index 1859645..de1a7c1 100644
--- a/net/cert/cert_verify_proc_unittest.cc
+++ b/net/cert/cert_verify_proc_unittest.cc
@@ -1801,6 +1801,73 @@
   VerifyCertName(".test.example", false);
 }
 
+// Tests that commonName-fallback is handled correctly:
+// - If it's a publicly trusted certificate, the commonName should never
+//   match.
+// - If it chains to a private root, the commonName should not match if
+//   the subjectAltName is absent, and the flags don't allow fallback.
+// - If it chains to a private root, the commonName SHOULD match iff the
+//   subjectAltName is absent and the flags allow a fallback.
+TEST_F(CertVerifyProcNameTest, HandlesCommonNameFallbackLocalAnchors) {
+  scoped_refptr<X509Certificate> cert(
+      ImportCertFromFile(GetTestCertsDirectory(), "salesforce_com_test.pem"));
+  ASSERT_TRUE(cert);
+
+  CertVerifyResult result;
+  scoped_refptr<CertVerifyProc> verify_proc;
+  CertVerifyResult verify_result;
+  int error;
+
+  // Publicly trusted: Always ignores commonName, regardless of flags.
+  result = CertVerifyResult();
+  verify_result = CertVerifyResult();
+  error = 0;
+  result.is_issued_by_known_root = true;
+  verify_proc = new MockCertVerifyProc(result);
+  error = verify_proc->Verify(cert.get(), "prerelna1.pre.salesforce.com",
+                              std::string(), 0, nullptr, CertificateList(),
+                              &verify_result);
+  EXPECT_THAT(error, IsError(ERR_CERT_COMMON_NAME_INVALID));
+  EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_COMMON_NAME_INVALID);
+
+  result = CertVerifyResult();
+  verify_result = CertVerifyResult();
+  error = 0;
+  result.is_issued_by_known_root = true;
+  verify_proc = new MockCertVerifyProc(result);
+  error = verify_proc->Verify(
+      cert.get(), "prerelna1.pre.salesforce.com", std::string(),
+      CertVerifier::VERIFY_ENABLE_COMMON_NAME_FALLBACK_LOCAL_ANCHORS, nullptr,
+      CertificateList(), &verify_result);
+  EXPECT_THAT(error, IsError(ERR_CERT_COMMON_NAME_INVALID));
+  EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_COMMON_NAME_INVALID);
+
+  // Privately trusted: Ignores commonName by default.
+  result = CertVerifyResult();
+  verify_result = CertVerifyResult();
+  error = 0;
+  result.is_issued_by_known_root = false;
+  verify_proc = new MockCertVerifyProc(result);
+  error = verify_proc->Verify(cert.get(), "prerelna1.pre.salesforce.com",
+                              std::string(), 0, nullptr, CertificateList(),
+                              &verify_result);
+  EXPECT_THAT(error, IsError(ERR_CERT_COMMON_NAME_INVALID));
+  EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_COMMON_NAME_INVALID);
+
+  // Privately trusted: Falls back to common name if flags allow.
+  result = CertVerifyResult();
+  verify_result = CertVerifyResult();
+  error = 0;
+  result.is_issued_by_known_root = false;
+  verify_proc = new MockCertVerifyProc(result);
+  error = verify_proc->Verify(
+      cert.get(), "prerelna1.pre.salesforce.com", std::string(),
+      CertVerifier::VERIFY_ENABLE_COMMON_NAME_FALLBACK_LOCAL_ANCHORS, nullptr,
+      CertificateList(), &verify_result);
+  EXPECT_THAT(error, IsOk());
+  EXPECT_FALSE(verify_result.cert_status & CERT_STATUS_COMMON_NAME_INVALID);
+}
+
 // Tests that CertVerifyProc records a histogram correctly when a
 // certificate chaining to a private root contains the TLS feature
 // extension and does not have a stapled OCSP response.
diff --git a/net/cert/internal/path_builder_unittest.cc b/net/cert/internal/path_builder_unittest.cc
index 212b8de3..be5432b5 100644
--- a/net/cert/internal/path_builder_unittest.cc
+++ b/net/cert/internal/path_builder_unittest.cc
@@ -134,7 +134,7 @@
       d_by_d_, e_by_e_, f_by_e_;
 
   SimpleSignaturePolicy signature_policy_;
-  der::GeneralizedTime time_ = {2016, 4, 11, 0, 0, 0};
+  der::GeneralizedTime time_ = {2017, 3, 1, 0, 0, 0};
 };
 
 void AddTrustedCertificate(scoped_refptr<ParsedCertificate> cert,
diff --git a/net/cert/x509_certificate.cc b/net/cert/x509_certificate.cc
index 0d6fe95..782f4a4c 100644
--- a/net/cert/x509_certificate.cc
+++ b/net/cert/x509_certificate.cc
@@ -493,7 +493,7 @@
     const std::string& cert_common_name,
     const std::vector<std::string>& cert_san_dns_names,
     const std::vector<std::string>& cert_san_ip_addrs,
-    bool* common_name_fallback_used) {
+    bool allow_common_name_fallback) {
   DCHECK(!hostname.empty());
   // Perform name verification following http://tools.ietf.org/html/rfc6125.
   // The terminology used in this method is as per that RFC:-
@@ -514,14 +514,17 @@
   if (reference_name.empty())
     return false;
 
-  // Allow fallback to Common name matching?
-  const bool common_name_fallback = cert_san_dns_names.empty() &&
-                                    cert_san_ip_addrs.empty();
-  *common_name_fallback_used = common_name_fallback;
+  if (!allow_common_name_fallback && cert_san_dns_names.empty() &&
+      cert_san_ip_addrs.empty()) {
+    // Common Name matching is not allowed, so fail fast.
+    return false;
+  }
 
   // Fully handle all cases where |hostname| contains an IP address.
   if (host_info.IsIPAddress()) {
-    if (common_name_fallback && host_info.family == url::CanonHostInfo::IPV4) {
+    if (allow_common_name_fallback && cert_san_dns_names.empty() &&
+        cert_san_ip_addrs.empty() &&
+        host_info.family == url::CanonHostInfo::IPV4) {
       // Fallback to Common name matching. As this is deprecated and only
       // supported for compatibility refuse it for IPv6 addresses.
       return reference_name == cert_common_name;
@@ -580,7 +583,8 @@
   // fallback to use the common name instead.
   std::vector<std::string> common_name_as_vector;
   const std::vector<std::string>* presented_names = &cert_san_dns_names;
-  if (common_name_fallback) {
+  if (allow_common_name_fallback && cert_san_dns_names.empty() &&
+      cert_san_ip_addrs.empty()) {
     // Note: there's a small possibility cert_common_name is an international
     // domain name in non-standard encoding (e.g. UTF8String or BMPString
     // instead of A-label). As common name fallback is deprecated we're not
@@ -628,11 +632,11 @@
 }
 
 bool X509Certificate::VerifyNameMatch(const std::string& hostname,
-                                      bool* common_name_fallback_used) const {
+                                      bool allow_common_name_fallback) const {
   std::vector<std::string> dns_names, ip_addrs;
   GetSubjectAltName(&dns_names, &ip_addrs);
   return VerifyHostname(hostname, subject_.common_name, dns_names, ip_addrs,
-                        common_name_fallback_used);
+                        allow_common_name_fallback);
 }
 
 // static
diff --git a/net/cert/x509_certificate.h b/net/cert/x509_certificate.h
index 0aff1be..4567f0e 100644
--- a/net/cert/x509_certificate.h
+++ b/net/cert/x509_certificate.h
@@ -287,11 +287,11 @@
   // Verifies that |hostname| matches this certificate.
   // Does not verify that the certificate is valid, only that the certificate
   // matches this host.
-  // Returns true if it matches, and updates |*common_name_fallback_used|,
-  // setting it to true if a fallback to the CN was used, rather than
-  // subjectAltName.
+  // If |allow_common_name_fallback| is set to true, and iff no SANs are
+  // present of type dNSName or iPAddress, then fallback to using the
+  // certificate's commonName field in the Subject.
   bool VerifyNameMatch(const std::string& hostname,
-                       bool* common_name_fallback_used) const;
+                       bool allow_common_name_fallback) const;
 
   // Obtains the DER encoded certificate data for |cert_handle|. On success,
   // returns true and writes the DER encoded certificate to |*der_encoded|.
@@ -420,14 +420,14 @@
   // extension, if present. Note these IP addresses are NOT ascii-encoded:
   // they must be 4 or 16 bytes of network-ordered data, for IPv4 and IPv6
   // addresses, respectively.
-  // |common_name_fallback_used| will be updated to true if cert_common_name
-  // was used to match the hostname, or false if either of the |cert_san_*|
-  // parameters was used to match the hostname.
+  // If |allow_common_name_fallback| is true, then the |cert_common_name| will
+  // be used if the |cert_san_dns_names| and |cert_san_ip_addrs| parameters are
+  // empty.
   static bool VerifyHostname(const std::string& hostname,
                              const std::string& cert_common_name,
                              const std::vector<std::string>& cert_san_dns_names,
                              const std::vector<std::string>& cert_san_ip_addrs,
-                             bool* common_name_fallback_used);
+                             bool allow_common_name_fallback);
 
   // Reads a single certificate from |pickle_iter| and returns a
   // platform-specific certificate handle. The format of the certificate
diff --git a/net/cert/x509_certificate_unittest.cc b/net/cert/x509_certificate_unittest.cc
index 9cadb266..d2974e56 100644
--- a/net/cert/x509_certificate_unittest.cc
+++ b/net/cert/x509_certificate_unittest.cc
@@ -167,12 +167,11 @@
   EXPECT_EQ("webkit.org", dns_names[1]);
 
   // Test that the wildcard cert matches properly.
-  bool unused = false;
-  EXPECT_TRUE(webkit_cert->VerifyNameMatch("www.webkit.org", &unused));
-  EXPECT_TRUE(webkit_cert->VerifyNameMatch("foo.webkit.org", &unused));
-  EXPECT_TRUE(webkit_cert->VerifyNameMatch("webkit.org", &unused));
-  EXPECT_FALSE(webkit_cert->VerifyNameMatch("www.webkit.com", &unused));
-  EXPECT_FALSE(webkit_cert->VerifyNameMatch("www.foo.webkit.com", &unused));
+  EXPECT_TRUE(webkit_cert->VerifyNameMatch("www.webkit.org", false));
+  EXPECT_TRUE(webkit_cert->VerifyNameMatch("foo.webkit.org", false));
+  EXPECT_TRUE(webkit_cert->VerifyNameMatch("webkit.org", false));
+  EXPECT_FALSE(webkit_cert->VerifyNameMatch("www.webkit.com", false));
+  EXPECT_FALSE(webkit_cert->VerifyNameMatch("www.foo.webkit.com", false));
 }
 
 TEST(X509CertificateTest, ThawteCertParsing) {
@@ -933,6 +932,10 @@
   // Comma separated list of certificate IP Addresses to match against. Each
   // address is x prefixed 16 byte hex code for v6 or dotted-decimals for v4.
   const char* ip_addrs;
+  // Whether to disable matching against the commonName. This is a negative
+  // condition so that tests can omit one or more of the above fields and
+  // allow default initialization to handle this case.
+  bool disable_fallback;
 };
 
 // GTest 'magic' pretty-printer, so that if/when a test fails, it knows how
@@ -946,7 +949,8 @@
       << "; hostname: " << data.hostname
       << "; common_name: " << data.common_name
       << "; dns_names: " << base::StringPiece(data.dns_names)
-      << "; ip_addrs: " << base::StringPiece(data.ip_addrs);
+      << "; ip_addrs: " << base::StringPiece(data.ip_addrs)
+      << "; disable_fallback: " << data.disable_fallback;
 }
 
 const CertificateNameVerifyTestData kNameVerifyTestData[] = {
@@ -975,12 +979,15 @@
     { true, "ww%57.foo.com", "", "www.foo.com" },
     { true, "www&.foo.com", "www%26.foo.com" },
     // Common name must not be used if subject alternative name was provided.
-    { false, "www.test.co.jp",  "www.test.co.jp",
+    { false, "www.test.co.jp", "www.test.co.jp",
         "*.test.de,*.jp,www.test.co.uk,www.*.co.jp" },
     { false, "www.bar.foo.com", "www.bar.foo.com",
       "*.foo.com,*.*.foo.com,*.*.bar.foo.com,*..bar.foo.com," },
     { false, "www.bath.org", "www.bath.org", "", "20.30.40.50" },
-    { false, "66.77.88.99", "www.bath.org", "www.bath.org" },
+    { false, "66.77.88.99", "66.77.88.99", "www.bath.org" },
+    // Common name must not be used if fallback is disabled.
+    { false, "www.test.com", "www.test.com", nullptr, nullptr, true },
+    { false, "127.0.0.1", "127.0.0.1", nullptr, nullptr, true },
     // IDN tests
     { true, "xn--poema-9qae5a.com.br", "xn--poema-9qae5a.com.br" },
     { true, "www.xn--poema-9qae5a.com.br", "*.xn--poema-9qae5a.com.br" },
@@ -1143,9 +1150,10 @@
     }
   }
 
-  bool unused = false;
-  EXPECT_EQ(test_data.expected, X509Certificate::VerifyHostname(
-      test_data.hostname, common_name, dns_names, ip_addressses, &unused));
+  EXPECT_EQ(test_data.expected,
+            X509Certificate::VerifyHostname(test_data.hostname, common_name,
+                                            dns_names, ip_addressses,
+                                            !test_data.disable_fallback));
 }
 
 INSTANTIATE_TEST_CASE_P(, X509CertificateNameVerifyTest,
diff --git a/net/data/cert_issuer_source_aia_unittest/generate-certs.py b/net/data/cert_issuer_source_aia_unittest/generate-certs.py
index b758e5a6..bda53fd 100755
--- a/net/data/cert_issuer_source_aia_unittest/generate-certs.py
+++ b/net/data/cert_issuer_source_aia_unittest/generate-certs.py
@@ -85,30 +85,39 @@
 # target certs
 
 target = common.create_end_entity_certificate('target', i_base)
+target.get_extensions().set_property('subjectAltName', 'DNS:target')
 common.write_string_to_file(target.get_cert_pem(), 'target_one_aia.pem')
 
 target = common.create_end_entity_certificate('target', i_no_aia)
+target.get_extensions().set_property('subjectAltName', 'DNS:target')
 common.write_string_to_file(target.get_cert_pem(), 'target_no_aia.pem')
 
 target = common.create_end_entity_certificate('target', i_two_aia)
+target.get_extensions().set_property('subjectAltName', 'DNS:target')
 common.write_string_to_file(target.get_cert_pem(), 'target_two_aia.pem')
 
 target = common.create_end_entity_certificate('target', i_three_aia)
+target.get_extensions().set_property('subjectAltName', 'DNS:target')
 common.write_string_to_file(target.get_cert_pem(), 'target_three_aia.pem')
 
 target = common.create_end_entity_certificate('target', i_six_aia)
+target.get_extensions().set_property('subjectAltName', 'DNS:target')
 common.write_string_to_file(target.get_cert_pem(), 'target_six_aia.pem')
 
 target = common.create_end_entity_certificate('target', i_file_aia)
+target.get_extensions().set_property('subjectAltName', 'DNS:target')
 common.write_string_to_file(target.get_cert_pem(), 'target_file_aia.pem')
 
 target = common.create_end_entity_certificate('target', i_invalid_url_aia)
+target.get_extensions().set_property('subjectAltName', 'DNS:target')
 common.write_string_to_file(target.get_cert_pem(), 'target_invalid_url_aia.pem')
 
 target = common.create_end_entity_certificate('target', i_file_and_http_aia)
+target.get_extensions().set_property('subjectAltName', 'DNS:target')
 common.write_string_to_file(target.get_cert_pem(),
                             'target_file_and_http_aia.pem')
 
 target = common.create_end_entity_certificate('target', i_invalid_and_http_aia)
+target.get_extensions().set_property('subjectAltName', 'DNS:target')
 common.write_string_to_file(target.get_cert_pem(),
                             'target_invalid_and_http_aia.pem')
diff --git a/net/data/cert_issuer_source_aia_unittest/i.pem b/net/data/cert_issuer_source_aia_unittest/i.pem
index 63ce691..c86a72b9 100644
--- a/net/data/cert_issuer_source_aia_unittest/i.pem
+++ b/net/data/cert_issuer_source_aia_unittest/i.pem
@@ -12,30 +12,30 @@
             Public Key Algorithm: rsaEncryption
                 Public-Key: (2048 bit)
                 Modulus:
-                    00:a7:94:9a:13:a0:38:6f:f9:cd:27:0d:9d:7d:f3:
-                    0c:fe:a0:dd:39:23:4d:33:d5:d9:88:c5:23:71:a1:
-                    a7:f5:50:c7:c6:38:cb:88:41:87:e8:25:75:14:be:
-                    09:ef:4f:b1:48:c7:50:f6:de:05:85:4a:01:7c:6c:
-                    e9:e1:4e:18:5f:43:38:cb:42:3a:e3:4a:7d:49:86:
-                    f5:30:d8:44:70:4e:c9:77:3d:ba:d2:a4:cc:a5:df:
-                    8c:e9:58:f8:2d:a5:b4:7a:7e:23:4e:0f:89:a0:5f:
-                    0f:f1:47:95:bd:f4:2f:e9:3b:0e:ba:ef:e7:10:03:
-                    0a:94:9d:fe:65:86:49:4d:c2:4f:b6:dc:23:e7:30:
-                    e6:10:64:0c:ed:4e:17:aa:1d:56:1d:6f:b8:3f:e5:
-                    8c:60:8a:f3:67:5a:04:6d:f3:84:98:01:db:11:c6:
-                    e2:c4:fc:0a:5a:33:77:eb:38:35:21:45:c0:b3:30:
-                    c2:95:4b:85:73:03:75:e5:9f:fd:a5:72:aa:21:64:
-                    cd:26:a6:8d:7a:bc:68:6a:36:ab:fe:a6:16:9c:b9:
-                    93:e9:26:cf:cb:3c:9d:a9:26:18:d1:83:61:25:e4:
-                    bc:6a:47:51:78:c9:1e:a2:38:10:8e:92:64:a8:aa:
-                    70:46:d3:cd:d2:5b:56:c3:98:ca:f1:b4:e0:cf:c9:
-                    48:b7
+                    00:ad:aa:76:dc:52:a2:4a:fd:8a:eb:22:f7:e2:32:
+                    88:2d:69:bb:cf:74:55:2d:db:bd:9a:00:41:8f:ea:
+                    28:b3:4a:ad:00:fc:fd:8b:46:32:13:8c:a8:a7:3b:
+                    00:53:60:37:cd:4c:3d:99:02:01:86:3f:f4:1a:b9:
+                    31:91:97:55:b5:5c:73:e5:45:80:63:fd:6f:c5:1d:
+                    16:c4:58:3d:33:eb:ce:2f:5d:bc:a1:fb:3d:13:d5:
+                    d2:34:10:ba:a5:80:49:3e:bb:e4:64:0a:73:84:8b:
+                    a6:3f:de:f4:46:c4:93:30:6c:d4:88:8f:a6:f0:e9:
+                    7b:c5:f2:e9:18:e0:3d:db:2e:81:5c:af:26:cb:14:
+                    f5:9d:51:8f:f5:b6:dc:e6:13:91:77:c8:02:cd:34:
+                    67:29:7f:4d:77:ff:68:10:9f:29:b6:6b:0a:85:17:
+                    45:65:18:bb:f4:ec:aa:ad:ea:6a:95:be:eb:3c:98:
+                    4d:79:3a:20:83:92:49:b0:75:a2:85:dd:0b:78:ee:
+                    91:f4:1a:59:2b:96:ca:08:a7:d8:49:de:37:95:15:
+                    b7:1b:e7:b7:a2:e7:29:65:33:ca:ca:33:b1:93:ce:
+                    a1:b6:23:52:9a:2b:cd:c1:92:24:f1:98:bc:ae:cc:
+                    87:26:e0:63:c5:3e:97:48:71:da:5a:a8:b7:89:d6:
+                    7c:e3
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Subject Key Identifier: 
-                40:91:28:21:9D:93:F3:9C:18:1B:FF:00:9C:B2:08:A0:A3:81:7D:2A
+                84:BA:05:06:4E:33:9D:11:AA:7A:F1:77:1F:A4:69:7E:4C:2D:D4:3F
             X509v3 Authority Key Identifier: 
-                keyid:E5:4E:96:E4:D9:82:36:BD:51:C3:57:BD:E6:DE:3C:C1:46:B4:49:0D
+                keyid:98:1F:DC:C5:E8:30:8D:5A:BA:9B:0C:EF:AD:CC:B8:AE:D4:F1:D1:63
 
             Authority Information Access: 
                 CA Issuers - URI:http://url-for-aia/Root.cer
@@ -50,39 +50,39 @@
             X509v3 Basic Constraints: critical
                 CA:TRUE
     Signature Algorithm: sha256WithRSAEncryption
-         96:0d:55:2e:09:b5:27:6b:48:e0:88:87:f2:fb:a0:04:99:c2:
-         7d:8c:8c:ad:60:ff:dd:6a:69:f3:cc:08:c9:1e:02:29:7a:73:
-         e3:ee:ef:9e:c1:52:dd:3e:9d:d4:07:6a:39:0b:0a:a2:6a:1e:
-         17:86:b5:8a:e4:53:f2:f7:00:bd:90:95:d2:08:9c:a3:28:2c:
-         4d:38:2d:eb:a4:a8:c4:17:44:1d:f6:57:d8:6d:98:06:3b:a9:
-         24:82:42:4e:8d:25:c9:5e:96:b6:f6:31:95:6c:49:3e:2d:15:
-         37:30:6f:d4:f1:15:ad:c2:49:35:89:76:c6:ac:dc:85:e2:ce:
-         d3:ba:cc:fd:fe:51:3a:a0:e6:56:4c:f8:21:b7:5c:f0:2c:88:
-         fa:9e:e9:85:76:de:8a:aa:48:d1:3f:03:01:41:6e:55:83:80:
-         5a:a0:36:5b:52:41:6e:2f:59:6d:07:fe:15:b1:7b:b7:c6:1b:
-         84:61:61:c5:82:84:98:22:20:45:69:d1:36:ea:7f:db:e0:03:
-         d6:73:a0:a9:6b:70:f2:9b:98:5e:f2:3e:30:c8:f6:b9:c9:35:
-         48:ae:68:21:ea:ec:9f:28:29:d2:88:bb:7e:e4:13:03:f9:79:
-         c9:2d:f7:41:90:28:4e:56:fc:c0:26:49:e4:0c:67:50:26:76:
-         7d:ba:c1:1c
+         54:74:10:33:68:ad:a0:f3:5e:42:ee:63:3c:33:7b:01:4f:aa:
+         8e:78:ec:91:51:c7:e0:31:4d:15:22:3f:88:70:f6:3a:8d:60:
+         72:e6:92:81:7b:34:40:d6:07:6a:a4:a1:42:84:cb:b3:a8:eb:
+         0b:07:6b:06:aa:60:70:4a:86:46:f7:0e:1e:95:c4:5b:ff:4e:
+         c9:86:15:ac:d7:44:ff:d6:7d:37:e7:f2:b9:da:7c:c9:b1:a8:
+         95:41:73:f9:be:b5:f6:8f:a8:d3:5b:05:6d:bd:55:69:dc:0e:
+         4f:c4:b3:45:ac:40:4f:f4:4d:3c:ff:be:9b:47:aa:c8:5f:47:
+         53:91:09:c7:2b:92:4d:4a:15:3f:49:04:40:17:e4:13:ab:26:
+         60:bb:ba:fc:e6:a0:02:d3:7e:af:9d:37:ae:20:ed:c7:be:1d:
+         9c:b6:94:13:73:27:45:2b:eb:0d:b9:64:09:78:97:d8:2f:36:
+         fc:79:a8:76:02:5f:e7:2c:60:af:8f:4d:dc:2a:47:54:65:f1:
+         c3:23:5e:fe:a1:4c:3e:2c:77:b1:f6:a0:32:3d:70:c0:cb:ab:
+         af:d7:cc:a5:19:2f:67:81:f1:19:0a:9c:06:4e:1e:a2:05:96:
+         ee:cb:fa:7a:b2:31:c0:54:a3:6c:66:7a:73:b2:76:85:9d:f2:
+         c5:bc:8d:f4
 -----BEGIN CERTIFICATE-----
 MIIDYjCCAkqgAwIBAgIBAjANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
 MB4XDTE1MDEwMTEyMDAwMFoXDTIxMDEwMTEyMDAwMFowDDEKMAgGA1UEAwwBSTCC
-ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKeUmhOgOG/5zScNnX3zDP6g
-3TkjTTPV2YjFI3Ghp/VQx8Y4y4hBh+gldRS+Ce9PsUjHUPbeBYVKAXxs6eFOGF9D
-OMtCOuNKfUmG9TDYRHBOyXc9utKkzKXfjOlY+C2ltHp+I04PiaBfD/FHlb30L+k7
-Drrv5xADCpSd/mWGSU3CT7bcI+cw5hBkDO1OF6odVh1vuD/ljGCK82daBG3zhJgB
-2xHG4sT8Clozd+s4NSFFwLMwwpVLhXMDdeWf/aVyqiFkzSamjXq8aGo2q/6mFpy5
-k+kmz8s8nakmGNGDYSXkvGpHUXjJHqI4EI6SZKiqcEbTzdJbVsOYyvG04M/JSLcC
-AwEAAaOByzCByDAdBgNVHQ4EFgQUQJEoIZ2T85wYG/8AnLIIoKOBfSowHwYDVR0j
-BBgwFoAU5U6W5NmCNr1Rw1e95t48wUa0SQ0wNwYIKwYBBQUHAQEEKzApMCcGCCsG
+ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK2qdtxSokr9iusi9+IyiC1p
+u890VS3bvZoAQY/qKLNKrQD8/YtGMhOMqKc7AFNgN81MPZkCAYY/9Bq5MZGXVbVc
+c+VFgGP9b8UdFsRYPTPrzi9dvKH7PRPV0jQQuqWAST675GQKc4SLpj/e9EbEkzBs
+1IiPpvDpe8Xy6RjgPdsugVyvJssU9Z1Rj/W23OYTkXfIAs00Zyl/TXf/aBCfKbZr
+CoUXRWUYu/Tsqq3qapW+6zyYTXk6IIOSSbB1ooXdC3jukfQaWSuWygin2EneN5UV
+txvnt6LnKWUzysozsZPOobYjUporzcGSJPGYvK7MhybgY8U+l0hx2lqot4nWfOMC
+AwEAAaOByzCByDAdBgNVHQ4EFgQUhLoFBk4znRGqevF3H6Rpfkwt1D8wHwYDVR0j
+BBgwFoAUmB/cxegwjVq6mwzvrcy4rtTx0WMwNwYIKwYBBQUHAQEEKzApMCcGCCsG
 AQUFBzAChhtodHRwOi8vdXJsLWZvci1haWEvUm9vdC5jZXIwLAYDVR0fBCUwIzAh
 oB+gHYYbaHR0cDovL3VybC1mb3ItY3JsL1Jvb3QuY3JsMA4GA1UdDwEB/wQEAwIB
-BjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCWDVUuCbUna0jg
-iIfy+6AEmcJ9jIytYP/damnzzAjJHgIpenPj7u+ewVLdPp3UB2o5Cwqiah4XhrWK
-5FPy9wC9kJXSCJyjKCxNOC3rpKjEF0Qd9lfYbZgGO6kkgkJOjSXJXpa29jGVbEk+
-LRU3MG/U8RWtwkk1iXbGrNyF4s7Tusz9/lE6oOZWTPght1zwLIj6numFdt6KqkjR
-PwMBQW5Vg4BaoDZbUkFuL1ltB/4VsXu3xhuEYWHFgoSYIiBFadE26n/b4APWc6Cp
-a3Dym5he8j4wyPa5yTVIrmgh6uyfKCnSiLt+5BMD+XnJLfdBkChOVvzAJknkDGdQ
-JnZ9usEc
+BjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBUdBAzaK2g815C
+7mM8M3sBT6qOeOyRUcfgMU0VIj+IcPY6jWBy5pKBezRA1gdqpKFChMuzqOsLB2sG
+qmBwSoZG9w4elcRb/07JhhWs10T/1n035/K52nzJsaiVQXP5vrX2j6jTWwVtvVVp
+3A5PxLNFrEBP9E08/76bR6rIX0dTkQnHK5JNShU/SQRAF+QTqyZgu7r85qAC036v
+nTeuIO3Hvh2ctpQTcydFK+sNuWQJeJfYLzb8eah2Al/nLGCvj03cKkdUZfHDI17+
+oUw+LHex9qAyPXDAy6uv18ylGS9ngfEZCpwGTh6iBZbuy/p6sjHAVKNsZnpzsnaF
+nfLFvI30
 -----END CERTIFICATE-----
diff --git a/net/data/cert_issuer_source_aia_unittest/i2.pem b/net/data/cert_issuer_source_aia_unittest/i2.pem
index 995570d..fde840a 100644
--- a/net/data/cert_issuer_source_aia_unittest/i2.pem
+++ b/net/data/cert_issuer_source_aia_unittest/i2.pem
@@ -12,30 +12,30 @@
             Public Key Algorithm: rsaEncryption
                 Public-Key: (2048 bit)
                 Modulus:
-                    00:a7:94:9a:13:a0:38:6f:f9:cd:27:0d:9d:7d:f3:
-                    0c:fe:a0:dd:39:23:4d:33:d5:d9:88:c5:23:71:a1:
-                    a7:f5:50:c7:c6:38:cb:88:41:87:e8:25:75:14:be:
-                    09:ef:4f:b1:48:c7:50:f6:de:05:85:4a:01:7c:6c:
-                    e9:e1:4e:18:5f:43:38:cb:42:3a:e3:4a:7d:49:86:
-                    f5:30:d8:44:70:4e:c9:77:3d:ba:d2:a4:cc:a5:df:
-                    8c:e9:58:f8:2d:a5:b4:7a:7e:23:4e:0f:89:a0:5f:
-                    0f:f1:47:95:bd:f4:2f:e9:3b:0e:ba:ef:e7:10:03:
-                    0a:94:9d:fe:65:86:49:4d:c2:4f:b6:dc:23:e7:30:
-                    e6:10:64:0c:ed:4e:17:aa:1d:56:1d:6f:b8:3f:e5:
-                    8c:60:8a:f3:67:5a:04:6d:f3:84:98:01:db:11:c6:
-                    e2:c4:fc:0a:5a:33:77:eb:38:35:21:45:c0:b3:30:
-                    c2:95:4b:85:73:03:75:e5:9f:fd:a5:72:aa:21:64:
-                    cd:26:a6:8d:7a:bc:68:6a:36:ab:fe:a6:16:9c:b9:
-                    93:e9:26:cf:cb:3c:9d:a9:26:18:d1:83:61:25:e4:
-                    bc:6a:47:51:78:c9:1e:a2:38:10:8e:92:64:a8:aa:
-                    70:46:d3:cd:d2:5b:56:c3:98:ca:f1:b4:e0:cf:c9:
-                    48:b7
+                    00:ad:aa:76:dc:52:a2:4a:fd:8a:eb:22:f7:e2:32:
+                    88:2d:69:bb:cf:74:55:2d:db:bd:9a:00:41:8f:ea:
+                    28:b3:4a:ad:00:fc:fd:8b:46:32:13:8c:a8:a7:3b:
+                    00:53:60:37:cd:4c:3d:99:02:01:86:3f:f4:1a:b9:
+                    31:91:97:55:b5:5c:73:e5:45:80:63:fd:6f:c5:1d:
+                    16:c4:58:3d:33:eb:ce:2f:5d:bc:a1:fb:3d:13:d5:
+                    d2:34:10:ba:a5:80:49:3e:bb:e4:64:0a:73:84:8b:
+                    a6:3f:de:f4:46:c4:93:30:6c:d4:88:8f:a6:f0:e9:
+                    7b:c5:f2:e9:18:e0:3d:db:2e:81:5c:af:26:cb:14:
+                    f5:9d:51:8f:f5:b6:dc:e6:13:91:77:c8:02:cd:34:
+                    67:29:7f:4d:77:ff:68:10:9f:29:b6:6b:0a:85:17:
+                    45:65:18:bb:f4:ec:aa:ad:ea:6a:95:be:eb:3c:98:
+                    4d:79:3a:20:83:92:49:b0:75:a2:85:dd:0b:78:ee:
+                    91:f4:1a:59:2b:96:ca:08:a7:d8:49:de:37:95:15:
+                    b7:1b:e7:b7:a2:e7:29:65:33:ca:ca:33:b1:93:ce:
+                    a1:b6:23:52:9a:2b:cd:c1:92:24:f1:98:bc:ae:cc:
+                    87:26:e0:63:c5:3e:97:48:71:da:5a:a8:b7:89:d6:
+                    7c:e3
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Subject Key Identifier: 
-                40:91:28:21:9D:93:F3:9C:18:1B:FF:00:9C:B2:08:A0:A3:81:7D:2A
+                84:BA:05:06:4E:33:9D:11:AA:7A:F1:77:1F:A4:69:7E:4C:2D:D4:3F
             X509v3 Authority Key Identifier: 
-                keyid:E5:4E:96:E4:D9:82:36:BD:51:C3:57:BD:E6:DE:3C:C1:46:B4:49:0D
+                keyid:98:1F:DC:C5:E8:30:8D:5A:BA:9B:0C:EF:AD:CC:B8:AE:D4:F1:D1:63
 
             Authority Information Access: 
                 CA Issuers - URI:http://url-for-aia/Root.cer
@@ -50,39 +50,39 @@
             X509v3 Basic Constraints: critical
                 CA:TRUE
     Signature Algorithm: sha256WithRSAEncryption
-         c2:83:63:7b:e6:d6:2b:b3:a7:f1:81:47:38:dc:65:9a:fc:3d:
-         1a:a7:2b:02:6c:98:32:6b:50:93:a9:cf:d1:03:12:b4:d7:b7:
-         15:49:a4:12:9e:95:c6:2b:ad:64:bc:16:4a:d9:b5:4b:3b:aa:
-         d9:d5:39:8d:ec:a6:1d:79:32:53:0a:66:41:c8:78:e4:74:d7:
-         e3:59:93:2e:2a:52:97:91:56:de:59:13:42:fa:a7:5b:80:82:
-         42:82:8c:c8:a2:90:89:45:4f:96:e2:88:3b:b5:52:70:22:3a:
-         f2:5d:2d:4f:2d:12:81:15:d8:10:3c:a1:72:19:07:86:2a:c4:
-         ac:79:2d:0f:a4:fc:8f:d5:18:eb:fc:e4:7e:a8:15:bb:1b:50:
-         5a:64:56:72:c3:96:e2:35:f7:03:54:4f:4a:0f:42:b6:53:61:
-         29:4f:f7:0f:7b:a9:d0:72:0b:43:18:08:4d:6c:35:4b:89:c3:
-         c4:4f:84:e1:c4:85:17:b4:cc:fa:a9:40:ad:aa:66:70:d6:ed:
-         f5:7a:7a:1b:bf:13:b9:68:b7:8a:23:14:29:2a:5a:af:0e:54:
-         28:87:31:7e:b7:34:ab:7f:ff:83:9d:b8:3a:ba:91:f4:93:70:
-         0e:8d:50:2f:67:d3:49:27:bd:db:25:d7:80:f4:58:8b:d3:01:
-         29:39:a9:2c
+         c9:b8:08:55:cd:6e:99:8f:1e:03:b6:00:7b:5f:65:63:6b:1d:
+         f1:27:84:0b:de:63:91:d2:bd:8a:28:ea:b0:f3:d6:a0:f6:11:
+         89:1b:a3:77:1f:f6:da:64:fd:36:24:9f:db:1c:b9:a1:f9:f1:
+         3f:ac:44:ed:08:4b:a2:7f:af:29:a7:01:7d:b9:88:ca:87:49:
+         a9:f1:9a:1d:3c:2e:ec:6b:a4:75:3e:29:29:2d:59:10:eb:39:
+         3a:9c:66:05:34:e9:c4:e9:37:0d:0f:74:be:f0:05:8c:0e:48:
+         e8:2d:c8:fa:81:01:11:b3:48:b3:5d:ba:a5:d6:30:bc:85:78:
+         70:a4:24:fd:36:ac:32:bf:17:5e:72:0a:1f:51:11:ba:c9:f2:
+         53:39:a1:4d:17:2e:de:f7:a4:33:ba:ce:d7:3c:f5:c0:bd:16:
+         22:48:f4:4e:a1:61:a6:62:b1:28:96:e5:9e:29:8f:b6:d3:53:
+         5a:3a:16:dc:3c:31:20:53:72:3d:cd:7a:e4:aa:0a:8d:83:0f:
+         68:74:1b:d5:22:87:31:a3:01:fc:18:7e:f5:35:cd:68:c8:ae:
+         71:e0:50:89:7d:96:e3:dd:df:62:a0:71:f1:56:5f:f6:79:11:
+         6f:28:a6:84:1f:63:a1:29:3e:c3:ef:1a:08:18:f8:95:6b:d7:
+         b6:a5:60:f5
 -----BEGIN CERTIFICATE-----
 MIIDYjCCAkqgAwIBAgIBAzANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
 MB4XDTE1MDEwMTEyMDAwMFoXDTIxMDEwMTEyMDAwMFowDDEKMAgGA1UEAwwBSTCC
-ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKeUmhOgOG/5zScNnX3zDP6g
-3TkjTTPV2YjFI3Ghp/VQx8Y4y4hBh+gldRS+Ce9PsUjHUPbeBYVKAXxs6eFOGF9D
-OMtCOuNKfUmG9TDYRHBOyXc9utKkzKXfjOlY+C2ltHp+I04PiaBfD/FHlb30L+k7
-Drrv5xADCpSd/mWGSU3CT7bcI+cw5hBkDO1OF6odVh1vuD/ljGCK82daBG3zhJgB
-2xHG4sT8Clozd+s4NSFFwLMwwpVLhXMDdeWf/aVyqiFkzSamjXq8aGo2q/6mFpy5
-k+kmz8s8nakmGNGDYSXkvGpHUXjJHqI4EI6SZKiqcEbTzdJbVsOYyvG04M/JSLcC
-AwEAAaOByzCByDAdBgNVHQ4EFgQUQJEoIZ2T85wYG/8AnLIIoKOBfSowHwYDVR0j
-BBgwFoAU5U6W5NmCNr1Rw1e95t48wUa0SQ0wNwYIKwYBBQUHAQEEKzApMCcGCCsG
+ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK2qdtxSokr9iusi9+IyiC1p
+u890VS3bvZoAQY/qKLNKrQD8/YtGMhOMqKc7AFNgN81MPZkCAYY/9Bq5MZGXVbVc
+c+VFgGP9b8UdFsRYPTPrzi9dvKH7PRPV0jQQuqWAST675GQKc4SLpj/e9EbEkzBs
+1IiPpvDpe8Xy6RjgPdsugVyvJssU9Z1Rj/W23OYTkXfIAs00Zyl/TXf/aBCfKbZr
+CoUXRWUYu/Tsqq3qapW+6zyYTXk6IIOSSbB1ooXdC3jukfQaWSuWygin2EneN5UV
+txvnt6LnKWUzysozsZPOobYjUporzcGSJPGYvK7MhybgY8U+l0hx2lqot4nWfOMC
+AwEAAaOByzCByDAdBgNVHQ4EFgQUhLoFBk4znRGqevF3H6Rpfkwt1D8wHwYDVR0j
+BBgwFoAUmB/cxegwjVq6mwzvrcy4rtTx0WMwNwYIKwYBBQUHAQEEKzApMCcGCCsG
 AQUFBzAChhtodHRwOi8vdXJsLWZvci1haWEvUm9vdC5jZXIwLAYDVR0fBCUwIzAh
 oB+gHYYbaHR0cDovL3VybC1mb3ItY3JsL1Jvb3QuY3JsMA4GA1UdDwEB/wQEAwIB
-BjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQDCg2N75tYrs6fx
-gUc43GWa/D0apysCbJgya1CTqc/RAxK017cVSaQSnpXGK61kvBZK2bVLO6rZ1TmN
-7KYdeTJTCmZByHjkdNfjWZMuKlKXkVbeWRNC+qdbgIJCgozIopCJRU+W4og7tVJw
-IjryXS1PLRKBFdgQPKFyGQeGKsSseS0PpPyP1Rjr/OR+qBW7G1BaZFZyw5biNfcD
-VE9KD0K2U2EpT/cPe6nQcgtDGAhNbDVLicPET4ThxIUXtMz6qUCtqmZw1u31enob
-vxO5aLeKIxQpKlqvDlQohzF+tzSrf/+Dnbg6upH0k3AOjVAvZ9NJJ73bJdeA9FiL
-0wEpOaks
+BjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQDJuAhVzW6Zjx4D
+tgB7X2Vjax3xJ4QL3mOR0r2KKOqw89ag9hGJG6N3H/baZP02JJ/bHLmh+fE/rETt
+CEuif68ppwF9uYjKh0mp8ZodPC7sa6R1PikpLVkQ6zk6nGYFNOnE6TcND3S+8AWM
+DkjoLcj6gQERs0izXbql1jC8hXhwpCT9NqwyvxdecgofURG6yfJTOaFNFy7e96Qz
+us7XPPXAvRYiSPROoWGmYrEoluWeKY+201NaOhbcPDEgU3I9zXrkqgqNgw9odBvV
+IocxowH8GH71Nc1oyK5x4FCJfZbj3d9ioHHxVl/2eRFvKKaEH2OhKT7D7xoIGPiV
+a9e2pWD1
 -----END CERTIFICATE-----
diff --git a/net/data/cert_issuer_source_aia_unittest/i3.pem b/net/data/cert_issuer_source_aia_unittest/i3.pem
index 064d732..76bd34da 100644
--- a/net/data/cert_issuer_source_aia_unittest/i3.pem
+++ b/net/data/cert_issuer_source_aia_unittest/i3.pem
@@ -12,30 +12,30 @@
             Public Key Algorithm: rsaEncryption
                 Public-Key: (2048 bit)
                 Modulus:
-                    00:a7:94:9a:13:a0:38:6f:f9:cd:27:0d:9d:7d:f3:
-                    0c:fe:a0:dd:39:23:4d:33:d5:d9:88:c5:23:71:a1:
-                    a7:f5:50:c7:c6:38:cb:88:41:87:e8:25:75:14:be:
-                    09:ef:4f:b1:48:c7:50:f6:de:05:85:4a:01:7c:6c:
-                    e9:e1:4e:18:5f:43:38:cb:42:3a:e3:4a:7d:49:86:
-                    f5:30:d8:44:70:4e:c9:77:3d:ba:d2:a4:cc:a5:df:
-                    8c:e9:58:f8:2d:a5:b4:7a:7e:23:4e:0f:89:a0:5f:
-                    0f:f1:47:95:bd:f4:2f:e9:3b:0e:ba:ef:e7:10:03:
-                    0a:94:9d:fe:65:86:49:4d:c2:4f:b6:dc:23:e7:30:
-                    e6:10:64:0c:ed:4e:17:aa:1d:56:1d:6f:b8:3f:e5:
-                    8c:60:8a:f3:67:5a:04:6d:f3:84:98:01:db:11:c6:
-                    e2:c4:fc:0a:5a:33:77:eb:38:35:21:45:c0:b3:30:
-                    c2:95:4b:85:73:03:75:e5:9f:fd:a5:72:aa:21:64:
-                    cd:26:a6:8d:7a:bc:68:6a:36:ab:fe:a6:16:9c:b9:
-                    93:e9:26:cf:cb:3c:9d:a9:26:18:d1:83:61:25:e4:
-                    bc:6a:47:51:78:c9:1e:a2:38:10:8e:92:64:a8:aa:
-                    70:46:d3:cd:d2:5b:56:c3:98:ca:f1:b4:e0:cf:c9:
-                    48:b7
+                    00:ad:aa:76:dc:52:a2:4a:fd:8a:eb:22:f7:e2:32:
+                    88:2d:69:bb:cf:74:55:2d:db:bd:9a:00:41:8f:ea:
+                    28:b3:4a:ad:00:fc:fd:8b:46:32:13:8c:a8:a7:3b:
+                    00:53:60:37:cd:4c:3d:99:02:01:86:3f:f4:1a:b9:
+                    31:91:97:55:b5:5c:73:e5:45:80:63:fd:6f:c5:1d:
+                    16:c4:58:3d:33:eb:ce:2f:5d:bc:a1:fb:3d:13:d5:
+                    d2:34:10:ba:a5:80:49:3e:bb:e4:64:0a:73:84:8b:
+                    a6:3f:de:f4:46:c4:93:30:6c:d4:88:8f:a6:f0:e9:
+                    7b:c5:f2:e9:18:e0:3d:db:2e:81:5c:af:26:cb:14:
+                    f5:9d:51:8f:f5:b6:dc:e6:13:91:77:c8:02:cd:34:
+                    67:29:7f:4d:77:ff:68:10:9f:29:b6:6b:0a:85:17:
+                    45:65:18:bb:f4:ec:aa:ad:ea:6a:95:be:eb:3c:98:
+                    4d:79:3a:20:83:92:49:b0:75:a2:85:dd:0b:78:ee:
+                    91:f4:1a:59:2b:96:ca:08:a7:d8:49:de:37:95:15:
+                    b7:1b:e7:b7:a2:e7:29:65:33:ca:ca:33:b1:93:ce:
+                    a1:b6:23:52:9a:2b:cd:c1:92:24:f1:98:bc:ae:cc:
+                    87:26:e0:63:c5:3e:97:48:71:da:5a:a8:b7:89:d6:
+                    7c:e3
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Subject Key Identifier: 
-                40:91:28:21:9D:93:F3:9C:18:1B:FF:00:9C:B2:08:A0:A3:81:7D:2A
+                84:BA:05:06:4E:33:9D:11:AA:7A:F1:77:1F:A4:69:7E:4C:2D:D4:3F
             X509v3 Authority Key Identifier: 
-                keyid:E5:4E:96:E4:D9:82:36:BD:51:C3:57:BD:E6:DE:3C:C1:46:B4:49:0D
+                keyid:98:1F:DC:C5:E8:30:8D:5A:BA:9B:0C:EF:AD:CC:B8:AE:D4:F1:D1:63
 
             Authority Information Access: 
                 CA Issuers - URI:http://url-for-aia/Root.cer
@@ -50,39 +50,39 @@
             X509v3 Basic Constraints: critical
                 CA:TRUE
     Signature Algorithm: sha256WithRSAEncryption
-         b1:46:b0:1d:f8:a1:ea:4c:fc:b3:48:41:66:45:97:39:88:ca:
-         d6:0c:d0:ee:8e:47:40:f0:26:a2:87:af:00:20:a2:39:7f:57:
-         fd:f0:4f:13:b9:6c:0b:ad:5a:6e:ef:d5:e9:6d:54:7c:d3:92:
-         19:e9:f8:0f:23:0c:87:51:b7:54:d4:b7:29:0a:f5:f6:6a:e1:
-         a2:1f:39:17:83:10:9f:52:b2:de:ac:02:a7:6a:04:88:15:bb:
-         f5:b3:0a:63:cf:db:b9:4a:53:c9:c1:f0:62:e0:90:a0:a8:3b:
-         8c:97:eb:cc:a4:e5:93:e6:1a:d4:25:ac:96:7a:a5:fb:ae:b2:
-         ce:2a:07:8f:58:e6:bd:e6:ac:03:38:5a:03:e0:93:e0:3e:fd:
-         11:90:93:86:3f:ca:8c:71:23:9c:af:24:95:20:c1:0e:bd:97:
-         dd:d7:85:8d:98:9b:b9:6d:b2:f9:4d:6a:e3:d0:3c:ea:b4:27:
-         59:cd:38:40:31:67:18:3e:a4:48:f6:9b:d4:20:23:20:1b:0b:
-         b1:57:51:17:79:66:bd:31:b5:01:29:b9:98:87:d1:86:71:34:
-         fc:78:a0:25:fd:49:25:41:09:88:15:53:2d:33:c1:7f:5d:d7:
-         66:2d:12:eb:90:d8:96:26:ee:7a:6c:50:f1:d9:90:0b:11:8d:
-         ff:7a:48:87
+         5e:ed:e2:76:4f:f0:ad:00:c5:37:64:c6:b2:ad:de:8f:90:68:
+         de:96:60:f4:ef:bb:09:0b:df:c8:98:f0:ad:27:79:51:b5:c3:
+         2d:01:f5:fc:3c:4e:a7:4a:b2:c5:b4:b0:52:c3:e7:e1:18:41:
+         4f:34:62:e5:79:b0:86:f8:83:4f:e9:b2:11:67:16:5d:9d:2c:
+         d5:f6:d0:ca:61:d5:44:67:12:24:0f:8e:37:f1:db:77:4c:a2:
+         ad:1c:8a:1f:54:e7:13:7d:f0:b8:e7:c7:21:46:be:7b:5a:f5:
+         23:53:cc:fa:09:cf:b7:a9:29:aa:84:94:69:3e:7b:7b:a3:5d:
+         f6:8f:5e:42:78:36:9c:34:b0:5f:50:d6:0c:53:ff:22:1b:b8:
+         90:5d:ec:eb:1d:2e:28:16:f3:3c:fe:da:a9:77:0b:e1:d0:a7:
+         1a:d2:54:e8:3c:a3:3b:79:b8:5c:30:ec:b4:1f:f1:f1:ff:d6:
+         cc:b8:18:ae:6c:ce:94:4d:fe:00:fc:9f:4e:11:6a:ec:de:33:
+         67:3a:e6:46:40:de:0e:18:6c:6f:79:f7:fc:93:07:f4:90:8b:
+         5e:44:27:8f:fe:1f:e2:91:4c:56:7d:27:df:f2:fc:2f:9a:96:
+         71:8b:40:9a:73:d6:73:41:74:2e:40:c6:eb:17:9c:23:0a:05:
+         9a:9c:47:37
 -----BEGIN CERTIFICATE-----
 MIIDYjCCAkqgAwIBAgIBBDANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
 MB4XDTE1MDEwMTEyMDAwMFoXDTIxMDEwMTEyMDAwMFowDDEKMAgGA1UEAwwBSTCC
-ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKeUmhOgOG/5zScNnX3zDP6g
-3TkjTTPV2YjFI3Ghp/VQx8Y4y4hBh+gldRS+Ce9PsUjHUPbeBYVKAXxs6eFOGF9D
-OMtCOuNKfUmG9TDYRHBOyXc9utKkzKXfjOlY+C2ltHp+I04PiaBfD/FHlb30L+k7
-Drrv5xADCpSd/mWGSU3CT7bcI+cw5hBkDO1OF6odVh1vuD/ljGCK82daBG3zhJgB
-2xHG4sT8Clozd+s4NSFFwLMwwpVLhXMDdeWf/aVyqiFkzSamjXq8aGo2q/6mFpy5
-k+kmz8s8nakmGNGDYSXkvGpHUXjJHqI4EI6SZKiqcEbTzdJbVsOYyvG04M/JSLcC
-AwEAAaOByzCByDAdBgNVHQ4EFgQUQJEoIZ2T85wYG/8AnLIIoKOBfSowHwYDVR0j
-BBgwFoAU5U6W5NmCNr1Rw1e95t48wUa0SQ0wNwYIKwYBBQUHAQEEKzApMCcGCCsG
+ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK2qdtxSokr9iusi9+IyiC1p
+u890VS3bvZoAQY/qKLNKrQD8/YtGMhOMqKc7AFNgN81MPZkCAYY/9Bq5MZGXVbVc
+c+VFgGP9b8UdFsRYPTPrzi9dvKH7PRPV0jQQuqWAST675GQKc4SLpj/e9EbEkzBs
+1IiPpvDpe8Xy6RjgPdsugVyvJssU9Z1Rj/W23OYTkXfIAs00Zyl/TXf/aBCfKbZr
+CoUXRWUYu/Tsqq3qapW+6zyYTXk6IIOSSbB1ooXdC3jukfQaWSuWygin2EneN5UV
+txvnt6LnKWUzysozsZPOobYjUporzcGSJPGYvK7MhybgY8U+l0hx2lqot4nWfOMC
+AwEAAaOByzCByDAdBgNVHQ4EFgQUhLoFBk4znRGqevF3H6Rpfkwt1D8wHwYDVR0j
+BBgwFoAUmB/cxegwjVq6mwzvrcy4rtTx0WMwNwYIKwYBBQUHAQEEKzApMCcGCCsG
 AQUFBzAChhtodHRwOi8vdXJsLWZvci1haWEvUm9vdC5jZXIwLAYDVR0fBCUwIzAh
 oB+gHYYbaHR0cDovL3VybC1mb3ItY3JsL1Jvb3QuY3JsMA4GA1UdDwEB/wQEAwIB
-BjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCxRrAd+KHqTPyz
-SEFmRZc5iMrWDNDujkdA8Caih68AIKI5f1f98E8TuWwLrVpu79XpbVR805IZ6fgP
-IwyHUbdU1LcpCvX2auGiHzkXgxCfUrLerAKnagSIFbv1swpjz9u5SlPJwfBi4JCg
-qDuMl+vMpOWT5hrUJayWeqX7rrLOKgePWOa95qwDOFoD4JPgPv0RkJOGP8qMcSOc
-rySVIMEOvZfd14WNmJu5bbL5TWrj0DzqtCdZzThAMWcYPqRI9pvUICMgGwuxV1EX
-eWa9MbUBKbmYh9GGcTT8eKAl/UklQQmIFVMtM8F/XddmLRLrkNiWJu56bFDx2ZAL
-EY3/ekiH
+BjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBe7eJ2T/CtAMU3
+ZMayrd6PkGjelmD077sJC9/ImPCtJ3lRtcMtAfX8PE6nSrLFtLBSw+fhGEFPNGLl
+ebCG+INP6bIRZxZdnSzV9tDKYdVEZxIkD4438dt3TKKtHIofVOcTffC458chRr57
+WvUjU8z6Cc+3qSmqhJRpPnt7o132j15CeDacNLBfUNYMU/8iG7iQXezrHS4oFvM8
+/tqpdwvh0Kca0lToPKM7ebhcMOy0H/Hx/9bMuBiubM6UTf4A/J9OEWrs3jNnOuZG
+QN4OGGxveff8kwf0kIteRCeP/h/ikUxWfSff8vwvmpZxi0Cac9ZzQXQuQMbrF5wj
+CgWanEc3
 -----END CERTIFICATE-----
diff --git a/net/data/cert_issuer_source_aia_unittest/root.pem b/net/data/cert_issuer_source_aia_unittest/root.pem
index 3889c51..864402e 100644
--- a/net/data/cert_issuer_source_aia_unittest/root.pem
+++ b/net/data/cert_issuer_source_aia_unittest/root.pem
@@ -12,30 +12,30 @@
             Public Key Algorithm: rsaEncryption
                 Public-Key: (2048 bit)
                 Modulus:
-                    00:c5:4d:a6:fe:7f:c0:31:03:69:d9:4b:40:aa:ea:
-                    7f:d8:a9:ba:5e:7f:05:a9:b1:14:38:11:fd:35:c9:
-                    21:06:4b:ae:91:51:ff:9b:fa:de:78:7b:ec:7f:85:
-                    49:18:91:97:3d:73:1f:71:2d:41:cf:9e:a7:26:d7:
-                    0a:11:51:79:0c:0d:40:18:8e:4d:8b:03:42:a9:25:
-                    e4:e7:26:d9:d9:da:13:27:dd:ad:02:27:b3:53:07:
-                    8b:32:1d:1a:bd:6a:73:59:02:58:3d:8d:dc:e3:8d:
-                    ee:9a:e5:b7:56:5f:b0:5e:a6:f9:cc:0f:13:9e:6f:
-                    cf:73:77:84:23:8a:6b:6c:a5:cd:d8:19:1d:c5:8c:
-                    d2:e3:a5:bc:4e:26:10:49:dc:95:5e:b6:8d:73:7e:
-                    f1:e9:70:11:72:85:ab:b7:29:be:72:13:d0:18:8d:
-                    ab:4c:67:22:7a:03:2e:0c:f8:47:27:af:f8:a1:87:
-                    b2:99:36:65:9d:00:a6:70:87:64:bc:dc:86:c3:0a:
-                    73:06:12:d9:56:9c:72:cf:63:88:85:e7:46:0b:33:
-                    91:8e:4c:76:ab:b7:e0:3a:41:a7:a0:d4:92:d7:c9:
-                    11:d1:c8:77:c1:a9:69:69:57:eb:91:a4:49:a2:57:
-                    15:f1:9d:7d:fa:f9:f0:98:be:4b:0b:1b:d7:92:e4:
-                    50:47
+                    00:e0:76:77:42:80:12:21:1a:78:ca:6b:2d:b4:92:
+                    2a:2e:5d:8b:15:4b:d2:6a:55:6c:7d:a2:ec:db:ba:
+                    c5:54:63:17:bd:a6:a2:6d:a8:46:9a:e1:40:d8:38:
+                    97:b7:05:df:41:d5:8d:32:0c:76:71:e6:a2:b6:ff:
+                    17:37:ef:66:e4:c5:05:15:de:a1:c8:d9:68:48:d2:
+                    92:fb:5a:3e:5d:89:d1:3f:8a:15:a4:37:82:18:fd:
+                    79:58:8a:47:39:15:57:d5:de:45:66:21:af:80:7b:
+                    21:53:be:0b:94:03:e1:4e:a3:32:28:6f:76:9c:ab:
+                    0f:74:df:54:f8:eb:f4:87:c9:a0:0f:21:75:b4:4c:
+                    e7:73:7d:53:78:e5:88:95:90:62:28:47:08:a9:73:
+                    55:dc:ab:b5:d0:f4:c0:cb:68:b7:e4:d7:3f:62:ef:
+                    89:c5:27:e0:1d:5f:a8:88:f2:a1:dd:15:8a:62:ae:
+                    7b:7f:46:da:2f:a6:ef:37:6a:fe:8a:db:e4:91:db:
+                    ec:e4:e8:c0:7c:bb:96:ff:43:e6:02:9e:e4:07:d6:
+                    ca:b9:6d:a0:ba:d9:f9:70:c5:d8:15:10:d8:a1:61:
+                    b7:d4:44:04:67:e5:d2:b9:80:d1:86:c4:e5:40:c5:
+                    02:c5:83:16:7d:7b:db:af:95:66:9b:fb:42:9c:c8:
+                    51:5b
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Subject Key Identifier: 
-                E5:4E:96:E4:D9:82:36:BD:51:C3:57:BD:E6:DE:3C:C1:46:B4:49:0D
+                98:1F:DC:C5:E8:30:8D:5A:BA:9B:0C:EF:AD:CC:B8:AE:D4:F1:D1:63
             X509v3 Authority Key Identifier: 
-                keyid:E5:4E:96:E4:D9:82:36:BD:51:C3:57:BD:E6:DE:3C:C1:46:B4:49:0D
+                keyid:98:1F:DC:C5:E8:30:8D:5A:BA:9B:0C:EF:AD:CC:B8:AE:D4:F1:D1:63
 
             Authority Information Access: 
                 CA Issuers - URI:http://url-for-aia/Root.cer
@@ -50,39 +50,39 @@
             X509v3 Basic Constraints: critical
                 CA:TRUE
     Signature Algorithm: sha256WithRSAEncryption
-         5f:d4:9c:32:27:c2:19:48:51:1a:59:b3:16:7b:55:ec:c5:39:
-         e6:3b:08:0b:31:60:0b:8b:50:57:26:b9:67:12:f8:5b:95:ca:
-         f7:b9:88:28:65:50:ab:c6:60:9a:29:05:92:e6:b6:72:02:f4:
-         e2:95:b8:d9:29:fc:61:62:a4:1f:1e:0b:22:a7:80:5e:08:2c:
-         a2:c5:1c:20:47:cc:dc:6c:8e:95:c1:34:a0:c8:35:f1:48:f6:
-         96:a6:ee:e4:cb:58:55:b2:6e:a5:25:c8:a9:b8:6d:bb:50:dd:
-         0b:3b:83:f2:84:4b:b8:14:30:2c:38:a5:67:89:dd:be:d6:45:
-         80:23:7c:87:02:96:39:22:87:58:ce:fa:7e:0d:2e:60:54:ca:
-         9a:01:70:39:eb:6d:8f:82:d0:68:46:ee:3a:9a:54:df:d8:74:
-         4c:3a:5e:96:d8:4b:c7:86:04:d0:b7:96:f9:b3:c1:a3:a7:95:
-         b8:d7:7e:8b:f1:2a:b7:e0:8c:fb:ce:15:d1:cc:81:4f:40:96:
-         18:a8:aa:d7:97:3d:27:60:1f:ac:60:92:d1:b0:53:77:73:d7:
-         85:c8:6c:8a:36:8f:6a:2d:e7:6a:16:d5:f9:a3:42:e3:84:32:
-         ee:d3:e9:18:41:b6:07:30:87:03:b0:54:c3:2a:49:bc:00:13:
-         d1:79:5e:06
+         bf:ee:de:10:57:08:17:93:3a:c7:4e:74:db:d8:6d:7e:b5:f2:
+         1f:45:3c:5b:70:b1:0f:a4:d2:da:29:4a:49:a5:8d:7e:28:7e:
+         04:9d:a6:a0:6d:47:5d:05:4e:f6:b6:3a:73:66:05:d6:bd:52:
+         6d:1e:2e:3f:f1:37:e2:c0:95:c5:25:ca:dd:4c:32:bb:f4:22:
+         3b:41:4d:0b:31:9c:1a:eb:84:95:90:4e:4e:2f:8a:2d:22:43:
+         41:37:56:4a:0f:d8:6f:ff:54:2b:af:5b:f0:ac:3c:36:39:a3:
+         8f:02:7d:ff:45:25:a0:b9:57:61:15:f3:3a:67:49:da:b8:f4:
+         e5:7d:12:89:08:42:67:14:be:6a:a0:10:27:10:f0:21:78:1d:
+         cf:07:d0:50:7a:0e:7a:a2:00:5a:c1:dc:b9:d5:2a:ba:bb:7a:
+         99:5c:57:d1:14:1b:10:c9:51:9d:82:7b:fe:05:7e:87:fe:05:
+         55:52:3d:88:6a:44:bd:8c:61:f0:0c:5c:de:f6:85:1d:41:a9:
+         10:fa:89:3c:8c:69:f6:99:69:69:b9:18:a5:40:7d:7e:52:04:
+         f8:92:91:be:02:7a:25:42:c8:e4:d3:dd:da:60:82:f2:f3:2c:
+         9f:d9:cb:4c:13:a2:ea:a1:39:b0:35:37:3a:4d:e1:89:9f:24:
+         f3:b2:30:1f
 -----BEGIN CERTIFICATE-----
 MIIDZTCCAk2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
 MB4XDTE1MDEwMTEyMDAwMFoXDTIxMDEwMTEyMDAwMFowDzENMAsGA1UEAwwEUm9v
-dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMVNpv5/wDEDadlLQKrq
-f9ipul5/BamxFDgR/TXJIQZLrpFR/5v63nh77H+FSRiRlz1zH3EtQc+epybXChFR
-eQwNQBiOTYsDQqkl5Ocm2dnaEyfdrQIns1MHizIdGr1qc1kCWD2N3OON7prlt1Zf
-sF6m+cwPE55vz3N3hCOKa2ylzdgZHcWM0uOlvE4mEEnclV62jXN+8elwEXKFq7cp
-vnIT0BiNq0xnInoDLgz4Ryev+KGHspk2ZZ0ApnCHZLzchsMKcwYS2Vaccs9jiIXn
-RgszkY5Mdqu34DpBp6DUktfJEdHId8GpaWlX65GkSaJXFfGdffr58Ji+Swsb15Lk
-UEcCAwEAAaOByzCByDAdBgNVHQ4EFgQU5U6W5NmCNr1Rw1e95t48wUa0SQ0wHwYD
-VR0jBBgwFoAU5U6W5NmCNr1Rw1e95t48wUa0SQ0wNwYIKwYBBQUHAQEEKzApMCcG
+dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOB2d0KAEiEaeMprLbSS
+Ki5dixVL0mpVbH2i7Nu6xVRjF72mom2oRprhQNg4l7cF30HVjTIMdnHmorb/Fzfv
+ZuTFBRXeocjZaEjSkvtaPl2J0T+KFaQ3ghj9eViKRzkVV9XeRWYhr4B7IVO+C5QD
+4U6jMihvdpyrD3TfVPjr9IfJoA8hdbRM53N9U3jliJWQYihHCKlzVdyrtdD0wMto
+t+TXP2LvicUn4B1fqIjyod0VimKue39G2i+m7zdq/orb5JHb7OTowHy7lv9D5gKe
+5AfWyrltoLrZ+XDF2BUQ2KFht9REBGfl0rmA0YbE5UDFAsWDFn1726+VZpv7QpzI
+UVsCAwEAAaOByzCByDAdBgNVHQ4EFgQUmB/cxegwjVq6mwzvrcy4rtTx0WMwHwYD
+VR0jBBgwFoAUmB/cxegwjVq6mwzvrcy4rtTx0WMwNwYIKwYBBQUHAQEEKzApMCcG
 CCsGAQUFBzAChhtodHRwOi8vdXJsLWZvci1haWEvUm9vdC5jZXIwLAYDVR0fBCUw
 IzAhoB+gHYYbaHR0cDovL3VybC1mb3ItY3JsL1Jvb3QuY3JsMA4GA1UdDwEB/wQE
-AwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBf1JwyJ8IZ
-SFEaWbMWe1XsxTnmOwgLMWALi1BXJrlnEvhblcr3uYgoZVCrxmCaKQWS5rZyAvTi
-lbjZKfxhYqQfHgsip4BeCCyixRwgR8zcbI6VwTSgyDXxSPaWpu7ky1hVsm6lJcip
-uG27UN0LO4PyhEu4FDAsOKVnid2+1kWAI3yHApY5IodYzvp+DS5gVMqaAXA5622P
-gtBoRu46mlTf2HRMOl6W2EvHhgTQt5b5s8Gjp5W4136L8Sq34Iz7zhXRzIFPQJYY
-qKrXlz0nYB+sYJLRsFN3c9eFyGyKNo9qLedqFtX5o0LjhDLu0+kYQbYHMIcDsFTD
-Kkm8ABPReV4G
+AwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQC/7t4QVwgX
+kzrHTnTb2G1+tfIfRTxbcLEPpNLaKUpJpY1+KH4EnaagbUddBU72tjpzZgXWvVJt
+Hi4/8TfiwJXFJcrdTDK79CI7QU0LMZwa64SVkE5OL4otIkNBN1ZKD9hv/1Qrr1vw
+rDw2OaOPAn3/RSWguVdhFfM6Z0nauPTlfRKJCEJnFL5qoBAnEPAheB3PB9BQeg56
+ogBawdy51Sq6u3qZXFfRFBsQyVGdgnv+BX6H/gVVUj2IakS9jGHwDFze9oUdQakQ
++ok8jGn2mWlpuRilQH1+UgT4kpG+AnolQsjk093aYILy8yyf2ctME6LqoTmwNTc6
+TeGJnyTzsjAf
 -----END CERTIFICATE-----
diff --git a/net/data/cert_issuer_source_aia_unittest/target_file_aia.pem b/net/data/cert_issuer_source_aia_unittest/target_file_aia.pem
index d9d08d5..980aa12 100644
--- a/net/data/cert_issuer_source_aia_unittest/target_file_aia.pem
+++ b/net/data/cert_issuer_source_aia_unittest/target_file_aia.pem
@@ -12,30 +12,30 @@
             Public Key Algorithm: rsaEncryption
                 Public-Key: (2048 bit)
                 Modulus:
-                    00:ee:22:a3:0e:ba:89:a9:fc:95:d9:52:63:da:11:
-                    41:eb:fe:16:b2:fb:28:bc:f0:46:43:3b:6d:72:04:
-                    33:d1:8c:ab:4c:1a:dc:af:68:7d:a4:61:a4:44:dc:
-                    1f:1f:8f:cf:e5:8b:e5:fa:ec:12:92:19:18:e1:ec:
-                    a3:52:7c:06:c5:a6:9c:f6:af:0b:40:3c:44:cb:64:
-                    a1:8b:60:65:5f:f0:e0:b7:cf:86:38:5a:2d:36:12:
-                    0b:f9:c2:b3:c4:ed:36:13:67:b6:c3:9a:43:97:e5:
-                    44:dc:5d:62:ed:37:da:c7:66:73:fc:67:0e:32:9a:
-                    5f:db:b1:8a:4a:12:a4:a5:47:24:84:b3:0d:3b:32:
-                    bb:98:e9:24:db:58:41:4e:ef:51:a6:07:00:ed:e2:
-                    5d:22:43:b4:48:7f:82:f8:e4:c5:98:7f:4b:df:b0:
-                    9a:e1:78:65:c5:65:bf:7e:09:75:96:e4:9c:93:40:
-                    95:76:02:ae:dd:d0:cf:42:4d:53:c6:45:6c:80:cf:
-                    a9:0c:f6:f5:b6:b2:f7:fd:47:68:53:5d:39:8c:3d:
-                    2b:e3:eb:7e:0a:b6:c9:19:f4:70:3b:df:4b:c0:ad:
-                    27:df:b2:80:a7:1b:4f:cf:2a:51:1a:f4:10:b8:1a:
-                    ff:0f:36:e5:be:4e:b6:89:73:ca:56:5f:3b:89:48:
-                    d0:c7
+                    00:c2:b8:d6:fd:7b:fb:c3:a4:78:0a:f0:bc:2a:2d:
+                    2f:64:dc:94:cd:83:39:63:b6:17:f8:cb:8a:56:b7:
+                    7b:81:99:73:2e:ae:83:d0:94:1b:6c:12:95:1c:d3:
+                    73:c6:b9:e8:ed:68:8f:e7:84:f5:b6:8c:c0:aa:75:
+                    1d:7e:d2:96:d8:27:1e:50:65:9c:5b:88:7d:b8:a4:
+                    ea:3b:9b:ab:68:54:41:97:52:15:b9:be:fa:5e:35:
+                    4a:8c:ae:bf:67:e4:85:79:4a:e4:14:4a:3b:90:6b:
+                    76:43:34:e3:6c:09:1f:56:ce:1b:a2:3d:fa:ce:2b:
+                    7b:fe:12:1f:04:2f:7e:99:ab:7d:a4:34:0a:59:c4:
+                    7a:fa:f8:af:2f:c3:ee:71:12:44:22:17:b7:d7:b4:
+                    72:9e:9b:90:3f:a0:14:aa:aa:d4:3d:a4:bf:aa:bc:
+                    92:6e:bc:97:89:db:8a:cf:45:8a:b9:3e:6b:b7:60:
+                    c0:3f:dc:1c:24:e9:04:01:8d:f5:bb:0f:80:60:c5:
+                    d5:6d:94:43:55:bc:15:6b:c7:f9:ff:e4:d4:b0:2f:
+                    ad:2f:8f:3d:be:84:12:36:59:8b:1d:06:ce:f2:47:
+                    a7:d3:4e:48:0c:f4:42:bf:2f:ae:f3:12:dc:14:21:
+                    4c:35:2f:49:cf:7a:30:17:27:21:89:20:21:20:f1:
+                    0a:95
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Subject Key Identifier: 
-                A7:CF:5E:6D:C8:A0:41:B5:7B:39:EA:C3:A5:F9:13:14:80:1E:3C:81
+                FF:42:DD:71:AA:35:67:90:AF:8A:A5:37:2C:D0:81:00:CD:0D:C4:F9
             X509v3 Authority Key Identifier: 
-                keyid:40:91:28:21:9D:93:F3:9C:18:1B:FF:00:9C:B2:08:A0:A3:81:7D:2A
+                keyid:84:BA:05:06:4E:33:9D:11:AA:7A:F1:77:1F:A4:69:7E:4C:2D:D4:3F
 
             Authority Information Access: 
                 CA Issuers - URI:file:///dev/null
@@ -49,40 +49,42 @@
                 Digital Signature, Key Encipherment
             X509v3 Extended Key Usage: 
                 TLS Web Server Authentication, TLS Web Client Authentication
+            X509v3 Subject Alternative Name: 
+                DNS:target
     Signature Algorithm: sha256WithRSAEncryption
-         28:b6:d2:18:91:33:ed:df:67:ec:f5:c1:c7:37:25:1c:ec:95:
-         71:d9:ec:80:4c:e9:8b:d5:66:15:c2:19:e3:47:da:a7:b5:bb:
-         df:59:84:2f:07:96:c5:80:26:d7:d6:df:ce:cd:0b:28:fc:de:
-         c9:cc:b0:43:76:83:46:02:b1:f0:d0:3d:2e:6b:52:be:24:54:
-         ab:03:72:ee:a6:8c:cf:17:81:0b:c3:29:2f:da:ed:7a:e8:43:
-         90:57:97:56:6b:f9:76:25:93:ed:b7:a0:53:f1:ff:83:7e:53:
-         0c:ca:bb:a6:16:25:4d:fc:b6:cd:54:5a:fa:f8:12:a5:8c:46:
-         5a:64:e8:ba:f8:26:2e:15:8d:fa:00:e7:96:f7:47:73:5c:0c:
-         30:68:4b:db:0b:92:31:2d:1a:a0:14:77:10:dc:cb:07:ef:f1:
-         30:76:fa:dd:41:e4:b1:a3:d3:aa:c2:20:f7:77:f4:72:41:5b:
-         38:96:ce:e6:72:60:ff:63:d2:25:8b:99:cd:f6:34:34:73:67:
-         9a:cc:da:d3:76:da:ef:fb:d5:4a:cf:fe:34:27:fb:32:96:5b:
-         bf:b7:72:87:a7:f2:1e:7a:fc:e8:9d:ee:f6:94:44:88:63:47:
-         ec:e9:e8:61:74:9d:28:bd:2c:fd:b7:b3:b2:ed:68:c8:d6:ff:
-         53:93:61:36
+         83:37:89:c7:c3:ff:da:25:ef:02:0e:61:c7:a0:4d:8c:f3:f5:
+         c0:17:3f:12:42:ab:77:b4:e2:a5:38:e4:4f:79:5a:ca:a0:dc:
+         e8:99:3a:46:06:96:ea:49:24:52:5a:f8:9c:00:a7:65:c6:2a:
+         e7:89:b5:e4:7f:a7:22:b9:8b:09:6f:bc:5b:30:fe:6d:6e:32:
+         d6:3c:dd:9d:96:2c:9b:71:a3:2a:0f:ad:a1:ab:33:8f:e9:1f:
+         97:cd:fd:bc:7b:13:c6:d5:9d:40:4f:35:94:3a:0e:c0:a3:87:
+         7b:fa:4e:f4:e0:d7:6c:03:df:96:90:90:5d:f4:69:2e:ad:f0:
+         ce:26:13:a8:8a:69:9d:4c:98:91:06:f1:aa:2b:f8:29:9c:c3:
+         d7:97:58:6f:6f:29:76:45:68:9d:1c:9d:af:5a:1a:51:ba:df:
+         13:81:1a:45:f4:f8:74:37:c9:67:3b:91:86:b8:da:ec:c7:38:
+         77:75:12:5e:5e:22:a3:e7:ed:74:5a:2a:35:4a:ea:0c:7f:40:
+         15:fd:b3:82:ab:b9:0f:f3:da:87:31:22:d5:8d:73:25:a9:dd:
+         f3:1f:03:b0:e4:e5:dc:4a:2f:fd:71:11:79:ee:b8:50:a5:0f:
+         cc:ba:07:90:15:3f:c9:a6:e9:32:ac:fe:77:e9:74:5e:a0:de:
+         f6:24:1a:d4
 -----BEGIN CERTIFICATE-----
-MIIDZDCCAkygAwIBAgIBBjANBgkqhkiG9w0BAQsFADAMMQowCAYDVQQDDAFJMB4X
+MIIDdzCCAl+gAwIBAgIBBjANBgkqhkiG9w0BAQsFADAMMQowCAYDVQQDDAFJMB4X
 DTE1MDEwMTEyMDAwMFoXDTIxMDEwMTEyMDAwMFowETEPMA0GA1UEAwwGdGFyZ2V0
-MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7iKjDrqJqfyV2VJj2hFB
-6/4WsvsovPBGQzttcgQz0YyrTBrcr2h9pGGkRNwfH4/P5Yvl+uwSkhkY4eyjUnwG
-xaac9q8LQDxEy2Shi2BlX/Dgt8+GOFotNhIL+cKzxO02E2e2w5pDl+VE3F1i7Tfa
-x2Zz/GcOMppf27GKShKkpUckhLMNOzK7mOkk21hBTu9RpgcA7eJdIkO0SH+C+OTF
-mH9L37Ca4XhlxWW/fgl1luSck0CVdgKu3dDPQk1TxkVsgM+pDPb1trL3/UdoU105
-jD0r4+t+CrbJGfRwO99LwK0n37KApxtPzypRGvQQuBr/Dzblvk62iXPKVl87iUjQ
-xwIDAQABo4HLMIHIMB0GA1UdDgQWBBSnz15tyKBBtXs56sOl+RMUgB48gTAfBgNV
-HSMEGDAWgBRAkSghnZPznBgb/wCcsgigo4F9KjAsBggrBgEFBQcBAQQgMB4wHAYI
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwrjW/Xv7w6R4CvC8Ki0v
+ZNyUzYM5Y7YX+MuKVrd7gZlzLq6D0JQbbBKVHNNzxrno7WiP54T1tozAqnUdftKW
+2CceUGWcW4h9uKTqO5uraFRBl1IVub76XjVKjK6/Z+SFeUrkFEo7kGt2QzTjbAkf
+Vs4boj36zit7/hIfBC9+mat9pDQKWcR6+vivL8PucRJEIhe317RynpuQP6AUqqrU
+PaS/qrySbryXiduKz0WKuT5rt2DAP9wcJOkEAY31uw+AYMXVbZRDVbwVa8f5/+TU
+sC+tL489voQSNlmLHQbO8ken005IDPRCvy+u8xLcFCFMNS9Jz3owFychiSAhIPEK
+lQIDAQABo4HeMIHbMB0GA1UdDgQWBBT/Qt1xqjVnkK+KpTcs0IEAzQ3E+TAfBgNV
+HSMEGDAWgBSEugUGTjOdEap68XcfpGl+TC3UPzAsBggrBgEFBQcBAQQgMB4wHAYI
 KwYBBQUHMAKGEGZpbGU6Ly8vZGV2L251bGwwKQYDVR0fBCIwIDAeoBygGoYYaHR0
 cDovL3VybC1mb3ItY3JsL0kuY3JsMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAU
-BggrBgEFBQcDAQYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBACi20hiRM+3f
-Z+z1wcc3JRzslXHZ7IBM6YvVZhXCGeNH2qe1u99ZhC8HlsWAJtfW387NCyj83snM
-sEN2g0YCsfDQPS5rUr4kVKsDcu6mjM8XgQvDKS/a7XroQ5BXl1Zr+XYlk+23oFPx
-/4N+UwzKu6YWJU38ts1UWvr4EqWMRlpk6Lr4Ji4VjfoA55b3R3NcDDBoS9sLkjEt
-GqAUdxDcywfv8TB2+t1B5LGj06rCIPd39HJBWziWzuZyYP9j0iWLmc32NDRzZ5rM
-2tN22u/71UrP/jQn+zKWW7+3coen8h56/Oid7vaURIhjR+zp6GF0nSi9LP23s7Lt
-aMjW/1OTYTY=
+BggrBgEFBQcDAQYIKwYBBQUHAwIwEQYDVR0RBAowCIIGdGFyZ2V0MA0GCSqGSIb3
+DQEBCwUAA4IBAQCDN4nHw//aJe8CDmHHoE2M8/XAFz8SQqt3tOKlOORPeVrKoNzo
+mTpGBpbqSSRSWvicAKdlxirnibXkf6ciuYsJb7xbMP5tbjLWPN2dliybcaMqD62h
+qzOP6R+Xzf28exPG1Z1ATzWUOg7Ao4d7+k704NdsA9+WkJBd9GkurfDOJhOoimmd
+TJiRBvGqK/gpnMPXl1hvbyl2RWidHJ2vWhpRut8TgRpF9Ph0N8lnO5GGuNrsxzh3
+dRJeXiKj5+10Wio1SuoMf0AV/bOCq7kP89qHMSLVjXMlqd3zHwOw5OXcSi/9cRF5
+7rhQpQ/MugeQFT/JpukyrP536XReoN72JBrU
 -----END CERTIFICATE-----
diff --git a/net/data/cert_issuer_source_aia_unittest/target_file_and_http_aia.pem b/net/data/cert_issuer_source_aia_unittest/target_file_and_http_aia.pem
index 8066e42..7b6be73c 100644
--- a/net/data/cert_issuer_source_aia_unittest/target_file_and_http_aia.pem
+++ b/net/data/cert_issuer_source_aia_unittest/target_file_and_http_aia.pem
@@ -12,30 +12,30 @@
             Public Key Algorithm: rsaEncryption
                 Public-Key: (2048 bit)
                 Modulus:
-                    00:c8:03:32:ae:0e:d4:6b:f1:27:56:39:2f:62:ae:
-                    56:60:79:57:73:86:89:35:8c:07:ba:b5:d1:55:c7:
-                    a8:fc:91:d7:c9:20:4d:93:bd:7b:5d:40:73:d2:af:
-                    69:91:3b:69:49:58:4c:bb:6f:a9:a3:bc:51:9b:1c:
-                    7d:06:fa:67:3f:50:09:9e:1e:4d:08:8f:12:0a:1a:
-                    be:8c:26:45:b7:2d:73:2d:3e:d8:fe:31:3f:c3:42:
-                    bd:90:44:2b:05:7f:53:68:51:ef:59:88:6c:0e:7d:
-                    e3:cd:7b:65:08:5f:7f:4f:85:11:0b:8d:ce:27:e3:
-                    69:7f:1d:24:6c:ea:12:6e:d0:6a:13:31:d5:8c:d4:
-                    f4:b1:3a:df:20:cb:f4:1f:05:71:6d:17:ee:37:28:
-                    c7:b8:b0:d5:5a:12:cd:7e:40:65:fa:33:49:c6:83:
-                    bd:bb:37:0b:3b:a7:0c:c5:0b:99:ed:b7:d2:9a:ba:
-                    ba:f8:d7:8c:23:ed:12:ad:ac:b3:29:a3:70:71:5c:
-                    42:7b:e5:46:8c:1f:95:0d:cc:22:24:3a:d8:4e:91:
-                    42:1e:c9:a5:77:c2:49:b7:04:68:9c:5e:bb:48:e8:
-                    1b:03:dd:28:69:5f:1a:43:2b:75:0f:86:c1:b0:af:
-                    98:b8:c8:0c:a6:2a:25:d7:73:4d:85:63:df:75:1f:
-                    39:4b
+                    00:b2:4e:8e:4e:eb:87:1c:99:f2:14:5d:b0:e0:b6:
+                    83:01:1a:a7:39:0b:7d:35:ef:d7:4f:b2:76:84:46:
+                    b9:10:fb:5a:ed:08:ed:2a:32:41:72:cb:3b:2b:25:
+                    2d:e6:44:1b:04:71:c6:58:73:8d:1b:a8:1f:dd:56:
+                    0f:c7:4c:1d:03:91:01:fa:a9:43:ed:95:a9:f0:8e:
+                    28:b2:ed:f2:78:84:cc:9a:d2:d6:5e:9e:44:be:70:
+                    29:29:d0:44:80:93:ee:37:72:8c:52:aa:3a:76:5b:
+                    74:46:09:39:22:51:c7:92:70:d7:b1:2c:1f:74:db:
+                    e6:77:f4:b2:84:1c:d8:c1:ff:75:48:fb:6a:a4:43:
+                    c1:cb:02:07:f9:d3:1a:46:52:c7:9a:60:f6:ed:5a:
+                    1f:36:81:fe:a0:56:f9:bd:dd:3a:4a:a7:a0:13:06:
+                    c6:9c:d3:f4:92:e1:0f:fe:2d:41:70:05:7d:2b:e0:
+                    8b:5e:f7:5e:fc:4d:50:0d:36:bf:36:35:6e:ed:66:
+                    c5:0e:b8:73:98:8e:7d:a1:80:1f:cd:37:c9:44:6d:
+                    f2:1b:29:06:f0:51:90:55:2e:a0:ef:43:41:e5:fb:
+                    f8:5b:16:d6:a6:70:2a:24:9b:3a:a2:d1:85:f3:31:
+                    7f:dc:56:ef:28:cd:cc:e3:ca:2a:e1:ed:78:cc:56:
+                    57:69
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Subject Key Identifier: 
-                6D:14:70:82:6B:4A:03:46:1B:B4:E3:B1:BC:40:78:FF:7B:28:45:55
+                B5:51:F6:D3:5D:24:43:E0:10:85:9D:4C:5F:DA:EB:69:00:3B:B8:FE
             X509v3 Authority Key Identifier: 
-                keyid:40:91:28:21:9D:93:F3:9C:18:1B:FF:00:9C:B2:08:A0:A3:81:7D:2A
+                keyid:84:BA:05:06:4E:33:9D:11:AA:7A:F1:77:1F:A4:69:7E:4C:2D:D4:3F
 
             Authority Information Access: 
                 CA Issuers - URI:file:///dev/null
@@ -50,40 +50,43 @@
                 Digital Signature, Key Encipherment
             X509v3 Extended Key Usage: 
                 TLS Web Server Authentication, TLS Web Client Authentication
+            X509v3 Subject Alternative Name: 
+                DNS:target
     Signature Algorithm: sha256WithRSAEncryption
-         90:dd:9e:1e:9a:20:5e:bc:dd:ea:be:35:6d:73:5e:9e:17:d7:
-         06:92:2c:d6:05:3d:a5:90:5a:f0:b5:55:d6:1e:d6:78:8d:aa:
-         8b:94:8f:2e:68:64:09:72:ff:a5:95:61:49:33:79:67:4d:1d:
-         53:3b:59:16:82:bc:1b:27:05:7e:f2:41:80:09:e0:b2:92:85:
-         a0:fa:32:f2:99:49:ce:63:5a:c2:f4:89:d0:0f:39:a1:0f:b1:
-         61:0c:fd:a7:b1:d4:8f:a4:b1:9a:4f:da:81:ec:41:ee:c1:5b:
-         1b:3e:df:8e:0f:1c:aa:a6:63:0f:6b:e5:0a:36:a3:e1:72:3c:
-         74:49:cd:2b:eb:f5:d0:c8:87:c0:22:3a:51:7b:58:3b:6c:4b:
-         6a:70:74:be:1c:68:49:7b:9d:62:ef:4a:e8:d2:3f:5a:ec:5f:
-         48:80:55:e0:10:b9:67:8c:12:3c:a2:3b:6a:f6:47:8a:59:30:
-         f9:67:92:59:da:ed:1e:b7:30:ef:2d:bf:53:c2:dd:08:a1:e0:
-         fd:78:4e:fa:36:59:ca:53:f8:62:c1:c4:56:c1:56:73:74:8e:
-         c9:ca:07:14:5e:d4:be:be:b2:38:6a:d4:74:e5:60:7c:e7:d4:
-         8d:30:25:e2:da:85:c9:85:69:46:99:40:56:65:ca:40:59:59:
-         98:9c:18:04
+         34:75:8e:0a:28:46:43:e1:8f:d3:23:62:85:bc:e9:ea:2f:d2:
+         27:de:4b:03:6b:36:02:e0:aa:2a:33:4e:3c:5c:51:38:9e:9b:
+         9a:d9:0c:b3:73:75:c0:e4:d9:f1:cc:5c:fa:39:7a:a7:4b:1c:
+         88:51:72:6e:f6:c1:d8:75:64:2a:a1:16:99:1c:cb:c1:7f:be:
+         be:0b:62:25:13:96:3f:56:41:7e:cd:e2:05:fd:f8:06:fc:3d:
+         9f:b3:92:b2:7a:87:e0:b5:d5:50:8e:95:c3:3d:bf:78:28:01:
+         37:28:e7:d7:d5:67:99:4b:0d:23:93:04:7f:1b:11:c7:22:08:
+         c2:67:06:9b:bf:b0:d8:e2:c4:72:85:39:23:f4:46:77:20:ce:
+         72:f3:17:07:d9:e4:1d:53:0f:ea:c6:10:be:23:b7:25:06:c5:
+         bb:52:f7:f0:df:35:b0:37:9e:d2:94:26:85:e6:8a:ab:dc:e7:
+         6c:13:a5:7a:ad:01:c4:c3:7b:d7:24:39:2f:55:f4:92:52:2b:
+         74:46:d9:af:2a:01:40:5b:94:75:bc:c2:d1:d3:7e:4d:fd:36:
+         50:e5:8f:f3:54:17:3c:d8:b4:2c:e3:be:d9:0d:a3:e9:39:a9:
+         8a:26:dc:80:ab:fe:ce:f2:5c:29:4b:ea:98:55:44:25:93:36:
+         31:6e:24:d5
 -----BEGIN CERTIFICATE-----
-MIIDjDCCAnSgAwIBAgIBCDANBgkqhkiG9w0BAQsFADAMMQowCAYDVQQDDAFJMB4X
+MIIDoTCCAomgAwIBAgIBCDANBgkqhkiG9w0BAQsFADAMMQowCAYDVQQDDAFJMB4X
 DTE1MDEwMTEyMDAwMFoXDTIxMDEwMTEyMDAwMFowETEPMA0GA1UEAwwGdGFyZ2V0
-MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyAMyrg7Ua/EnVjkvYq5W
-YHlXc4aJNYwHurXRVceo/JHXySBNk717XUBz0q9pkTtpSVhMu2+po7xRmxx9Bvpn
-P1AJnh5NCI8SChq+jCZFty1zLT7Y/jE/w0K9kEQrBX9TaFHvWYhsDn3jzXtlCF9/
-T4URC43OJ+Npfx0kbOoSbtBqEzHVjNT0sTrfIMv0HwVxbRfuNyjHuLDVWhLNfkBl
-+jNJxoO9uzcLO6cMxQuZ7bfSmrq6+NeMI+0SrayzKaNwcVxCe+VGjB+VDcwiJDrY
-TpFCHsmld8JJtwRonF67SOgbA90oaV8aQyt1D4bBsK+YuMgMpiol13NNhWPfdR85
-SwIDAQABo4HzMIHwMB0GA1UdDgQWBBRtFHCCa0oDRhu047G8QHj/eyhFVTAfBgNV
-HSMEGDAWgBRAkSghnZPznBgb/wCcsgigo4F9KjBUBggrBgEFBQcBAQRIMEYwHAYI
-KwYBBQUHMAKGEGZpbGU6Ly8vZGV2L251bGwwJgYIKwYBBQUHMAKGGmh0dHA6Ly91
-cmwtZm9yLWFpYTIvSTIuZm9vMCkGA1UdHwQiMCAwHqAcoBqGGGh0dHA6Ly91cmwt
-Zm9yLWNybC9JLmNybDAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUH
-AwEGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQCQ3Z4emiBevN3qvjVtc16e
-F9cGkizWBT2lkFrwtVXWHtZ4jaqLlI8uaGQJcv+llWFJM3lnTR1TO1kWgrwbJwV+
-8kGACeCykoWg+jLymUnOY1rC9InQDzmhD7FhDP2nsdSPpLGaT9qB7EHuwVsbPt+O
-DxyqpmMPa+UKNqPhcjx0Sc0r6/XQyIfAIjpRe1g7bEtqcHS+HGhJe51i70ro0j9a
-7F9IgFXgELlnjBI8ojtq9keKWTD5Z5JZ2u0etzDvLb9Twt0IoeD9eE76NlnKU/hi
-wcRWwVZzdI7JygcUXtS+vrI4atR05WB859SNMCXi2oXJhWlGmUBWZcpAWVmYnBgE
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsk6OTuuHHJnyFF2w4LaD
+ARqnOQt9Ne/XT7J2hEa5EPta7QjtKjJBcss7KyUt5kQbBHHGWHONG6gf3VYPx0wd
+A5EB+qlD7ZWp8I4osu3yeITMmtLWXp5EvnApKdBEgJPuN3KMUqo6dlt0Rgk5IlHH
+knDXsSwfdNvmd/SyhBzYwf91SPtqpEPBywIH+dMaRlLHmmD27VofNoH+oFb5vd06
+SqegEwbGnNP0kuEP/i1BcAV9K+CLXvde/E1QDTa/NjVu7WbFDrhzmI59oYAfzTfJ
+RG3yGykG8FGQVS6g70NB5fv4WxbWpnAqJJs6otGF8zF/3FbvKM3M48oq4e14zFZX
+aQIDAQABo4IBBzCCAQMwHQYDVR0OBBYEFLVR9tNdJEPgEIWdTF/a62kAO7j+MB8G
+A1UdIwQYMBaAFIS6BQZOM50Rqnrxdx+kaX5MLdQ/MFQGCCsGAQUFBwEBBEgwRjAc
+BggrBgEFBQcwAoYQZmlsZTovLy9kZXYvbnVsbDAmBggrBgEFBQcwAoYaaHR0cDov
+L3VybC1mb3ItYWlhMi9JMi5mb28wKQYDVR0fBCIwIDAeoBygGoYYaHR0cDovL3Vy
+bC1mb3ItY3JsL0kuY3JsMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEF
+BQcDAQYIKwYBBQUHAwIwEQYDVR0RBAowCIIGdGFyZ2V0MA0GCSqGSIb3DQEBCwUA
+A4IBAQA0dY4KKEZD4Y/TI2KFvOnqL9In3ksDazYC4KoqM048XFE4npua2Qyzc3XA
+5NnxzFz6OXqnSxyIUXJu9sHYdWQqoRaZHMvBf76+C2IlE5Y/VkF+zeIF/fgG/D2f
+s5KyeofgtdVQjpXDPb94KAE3KOfX1WeZSw0jkwR/GxHHIgjCZwabv7DY4sRyhTkj
+9EZ3IM5y8xcH2eQdUw/qxhC+I7clBsW7Uvfw3zWwN57SlCaF5oqr3OdsE6V6rQHE
+w3vXJDkvVfSSUit0RtmvKgFAW5R1vMLR035N/TZQ5Y/zVBc82LQs477ZDaPpOamK
+JtyAq/7O8lwpS+qYVUQlkzYxbiTV
 -----END CERTIFICATE-----
diff --git a/net/data/cert_issuer_source_aia_unittest/target_invalid_and_http_aia.pem b/net/data/cert_issuer_source_aia_unittest/target_invalid_and_http_aia.pem
index ef2e666..b7669e01 100644
--- a/net/data/cert_issuer_source_aia_unittest/target_invalid_and_http_aia.pem
+++ b/net/data/cert_issuer_source_aia_unittest/target_invalid_and_http_aia.pem
@@ -12,30 +12,30 @@
             Public Key Algorithm: rsaEncryption
                 Public-Key: (2048 bit)
                 Modulus:
-                    00:b3:04:b7:2a:7f:85:9a:b4:30:29:77:0b:50:c8:
-                    1f:b3:0d:98:9b:f7:4f:ab:32:79:11:fd:73:f7:c4:
-                    af:28:f8:c7:15:66:50:2e:26:ab:76:ca:72:f2:d9:
-                    7f:1a:ee:64:e8:f2:87:4f:8d:32:09:1d:e8:14:fc:
-                    18:c5:13:f5:d7:74:94:61:8b:5f:e0:67:0a:84:fa:
-                    8b:2c:7e:8d:47:5b:7e:91:98:ef:14:58:b0:77:07:
-                    c7:78:12:6c:e1:60:82:f4:fb:44:c3:64:7c:59:52:
-                    f7:bb:ca:a0:28:4e:da:a0:53:95:80:d5:fd:1f:a6:
-                    d7:8b:27:2a:f0:fc:67:e9:b2:c6:54:97:a2:9b:92:
-                    b6:4f:c1:c8:82:2b:a4:ff:2a:d0:c2:7c:83:8d:b2:
-                    0c:29:a1:d9:86:b2:a0:f1:8a:50:fa:e7:e6:a6:f0:
-                    fa:52:85:28:98:da:53:05:d8:62:1e:33:8a:c2:89:
-                    e3:e8:98:f1:64:1a:bc:8d:c0:90:54:7b:8d:c4:00:
-                    77:52:fe:14:f3:79:0f:34:e9:6f:b2:b0:e1:e1:e5:
-                    b5:77:71:c8:f3:cf:3e:38:4c:d4:b0:bf:aa:74:45:
-                    22:7e:18:23:ab:39:b0:a4:09:e3:35:73:8e:4e:91:
-                    b6:c1:77:4f:39:b6:e4:24:95:92:5b:0b:6e:3f:ee:
-                    f9:cf
+                    00:9d:3f:f0:25:34:e1:e0:c3:a7:5a:2b:72:6d:e1:
+                    35:3a:99:eb:b4:12:7b:aa:2b:bc:a6:df:82:01:b1:
+                    e9:8a:39:3a:b1:c5:0f:07:94:0a:97:c9:b0:4e:11:
+                    11:35:02:65:96:36:65:dc:6f:26:00:1e:1e:38:15:
+                    7c:ca:08:2b:66:89:a0:c3:38:ff:03:d5:e3:9d:c0:
+                    98:55:fb:45:d7:57:17:84:6c:6a:af:72:4f:1d:28:
+                    0c:95:77:35:dd:b1:42:66:96:bd:f9:ec:6e:d6:c3:
+                    c2:23:1d:c4:55:43:ae:b2:12:29:22:7b:33:5a:55:
+                    8f:d1:24:ce:e3:e1:b9:42:e4:18:ab:64:48:75:f7:
+                    4d:9e:cf:a0:b9:29:32:71:8c:2b:32:d6:5a:f3:c2:
+                    8d:25:2c:a6:db:d5:fe:b1:46:20:ed:92:be:3a:0f:
+                    93:e7:45:ba:36:80:33:36:0c:df:bd:d0:c9:82:db:
+                    51:96:33:f7:78:9e:b0:7b:4f:04:31:aa:2a:a8:1b:
+                    90:4f:dd:58:16:33:3a:09:4d:1e:c8:18:9f:62:bf:
+                    21:4d:89:eb:a6:0e:25:3b:ae:f0:78:1f:9a:de:bc:
+                    17:06:73:16:7f:49:3b:4c:b3:a8:9e:a3:8d:79:d6:
+                    de:6b:24:67:75:d3:f0:15:d0:91:a0:9c:ff:d7:fa:
+                    09:41
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Subject Key Identifier: 
-                11:AD:0A:17:B2:9E:A2:12:F6:B2:82:F7:92:A9:01:AD:9C:D3:98:3B
+                6E:CC:5D:F5:E6:D9:A6:B7:8C:4B:CB:A4:A7:C5:70:66:DA:FA:0E:E6
             X509v3 Authority Key Identifier: 
-                keyid:40:91:28:21:9D:93:F3:9C:18:1B:FF:00:9C:B2:08:A0:A3:81:7D:2A
+                keyid:84:BA:05:06:4E:33:9D:11:AA:7A:F1:77:1F:A4:69:7E:4C:2D:D4:3F
 
             Authority Information Access: 
                 CA Issuers - URI:foobar
@@ -50,40 +50,43 @@
                 Digital Signature, Key Encipherment
             X509v3 Extended Key Usage: 
                 TLS Web Server Authentication, TLS Web Client Authentication
+            X509v3 Subject Alternative Name: 
+                DNS:target
     Signature Algorithm: sha256WithRSAEncryption
-         11:05:b5:d9:cd:93:1b:2e:e1:6a:71:d1:e1:a5:53:7f:b6:75:
-         6f:ac:4a:56:f9:1b:f0:cc:ef:5d:37:56:23:72:75:c5:bb:cb:
-         b7:3e:04:e3:e7:de:af:97:e1:6a:6e:86:f1:55:6b:42:95:a3:
-         16:fa:2f:38:cb:c0:0e:a9:eb:af:91:55:49:d6:65:21:25:83:
-         2a:50:06:68:c4:e7:2d:09:da:0b:8f:d1:ce:30:21:74:66:02:
-         17:3a:6c:5b:67:d7:20:64:69:a7:83:60:bb:08:9e:2f:ae:38:
-         9e:8e:83:9e:5a:24:a8:65:0f:9f:b0:bb:ae:db:4f:ba:b4:4e:
-         80:53:9e:4a:a7:23:ac:7f:db:f1:0e:8b:d9:7c:6c:bd:6c:8e:
-         b3:07:29:d8:9d:88:33:1f:40:ec:33:8b:a7:52:96:cf:e9:8d:
-         15:48:57:cb:77:df:bd:f5:31:ee:64:bc:55:89:48:1b:26:56:
-         73:a8:a5:88:fc:61:5f:d1:9a:28:0f:f7:69:88:0a:87:b0:a9:
-         ca:f4:e4:b2:31:11:b2:b2:15:88:7d:0c:8a:29:5a:ad:1a:29:
-         74:13:06:2f:45:c0:48:83:60:89:fd:8c:7f:a3:4d:9e:5d:1c:
-         a9:61:19:fd:d5:a0:7e:a3:b7:59:a6:bb:bd:72:f2:da:ea:0b:
-         05:05:56:e1
+         58:8b:4c:19:cb:8f:e1:77:47:86:03:f4:27:e8:2c:ff:e6:b3:
+         34:df:9c:97:90:d9:a2:f4:a6:ca:be:aa:0b:5a:03:84:c6:d2:
+         c0:ce:31:c5:8b:30:3a:48:9a:21:42:61:b6:21:96:90:b1:f7:
+         6e:8a:02:d5:fd:ba:2e:4e:22:12:0d:ad:b1:8d:4a:4b:16:ea:
+         86:8c:04:65:fd:9c:55:09:17:f2:cb:f3:b6:94:bc:c5:fb:8e:
+         f3:8c:d9:48:95:7f:b8:3d:50:f0:eb:20:fd:93:89:c6:21:09:
+         39:26:e2:68:d2:34:3f:27:d0:25:5f:b6:e4:7a:ff:8c:da:3c:
+         38:7c:f7:51:97:ad:83:3a:69:98:8b:8a:df:f8:ba:e7:0b:a2:
+         f6:eb:5d:c7:db:7d:8e:00:3c:ae:18:2b:66:77:50:9b:8c:d5:
+         2e:ef:15:e0:eb:da:de:78:78:73:d0:ba:bb:d8:2e:0a:03:f3:
+         05:7b:3b:bc:09:a1:4d:3c:f7:29:63:e1:f5:6b:2f:3c:45:a9:
+         9f:5b:6d:13:82:e6:e1:f1:c1:56:b3:bf:dd:ac:ef:ab:d1:f9:
+         de:dc:32:ce:50:2d:8c:b6:30:f9:13:f8:1f:a2:2e:ea:43:8c:
+         50:d8:d2:b1:a8:af:0a:c4:ef:4c:2f:61:3c:8c:af:34:a2:80:
+         d5:fe:21:2b
 -----BEGIN CERTIFICATE-----
-MIIDgjCCAmqgAwIBAgIBCTANBgkqhkiG9w0BAQsFADAMMQowCAYDVQQDDAFJMB4X
+MIIDlTCCAn2gAwIBAgIBCTANBgkqhkiG9w0BAQsFADAMMQowCAYDVQQDDAFJMB4X
 DTE1MDEwMTEyMDAwMFoXDTIxMDEwMTEyMDAwMFowETEPMA0GA1UEAwwGdGFyZ2V0
-MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAswS3Kn+FmrQwKXcLUMgf
-sw2Ym/dPqzJ5Ef1z98SvKPjHFWZQLiardspy8tl/Gu5k6PKHT40yCR3oFPwYxRP1
-13SUYYtf4GcKhPqLLH6NR1t+kZjvFFiwdwfHeBJs4WCC9PtEw2R8WVL3u8qgKE7a
-oFOVgNX9H6bXiycq8Pxn6bLGVJeim5K2T8HIgiuk/yrQwnyDjbIMKaHZhrKg8YpQ
-+ufmpvD6UoUomNpTBdhiHjOKwonj6JjxZBq8jcCQVHuNxAB3Uv4U83kPNOlvsrDh
-4eW1d3HI888+OEzUsL+qdEUifhgjqzmwpAnjNXOOTpG2wXdPObbkJJWSWwtuP+75
-zwIDAQABo4HpMIHmMB0GA1UdDgQWBBQRrQoXsp6iEvaygveSqQGtnNOYOzAfBgNV
-HSMEGDAWgBRAkSghnZPznBgb/wCcsgigo4F9KjBKBggrBgEFBQcBAQQ+MDwwEgYI
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnT/wJTTh4MOnWitybeE1
+OpnrtBJ7qiu8pt+CAbHpijk6scUPB5QKl8mwThERNQJlljZl3G8mAB4eOBV8yggr
+Zomgwzj/A9XjncCYVftF11cXhGxqr3JPHSgMlXc13bFCZpa9+exu1sPCIx3EVUOu
+shIpInszWlWP0STO4+G5QuQYq2RIdfdNns+guSkycYwrMtZa88KNJSym29X+sUYg
+7ZK+Og+T50W6NoAzNgzfvdDJgttRljP3eJ6we08EMaoqqBuQT91YFjM6CU0eyBif
+Yr8hTYnrpg4lO67weB+a3rwXBnMWf0k7TLOonqONedbeayRnddPwFdCRoJz/1/oJ
+QQIDAQABo4H8MIH5MB0GA1UdDgQWBBRuzF315tmmt4xLy6SnxXBm2voO5jAfBgNV
+HSMEGDAWgBSEugUGTjOdEap68XcfpGl+TC3UPzBKBggrBgEFBQcBAQQ+MDwwEgYI
 KwYBBQUHMAKGBmZvb2JhcjAmBggrBgEFBQcwAoYaaHR0cDovL3VybC1mb3ItYWlh
 Mi9JMi5mb28wKQYDVR0fBCIwIDAeoBygGoYYaHR0cDovL3VybC1mb3ItY3JsL0ku
 Y3JsMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUH
-AwIwDQYJKoZIhvcNAQELBQADggEBABEFtdnNkxsu4Wpx0eGlU3+2dW+sSlb5G/DM
-7103ViNydcW7y7c+BOPn3q+X4WpuhvFVa0KVoxb6LzjLwA6p66+RVUnWZSElgypQ
-BmjE5y0J2guP0c4wIXRmAhc6bFtn1yBkaaeDYLsIni+uOJ6Og55aJKhlD5+wu67b
-T7q0ToBTnkqnI6x/2/EOi9l8bL1sjrMHKdidiDMfQOwzi6dSls/pjRVIV8t33731
-Me5kvFWJSBsmVnOopYj8YV/RmigP92mICoewqcr05LIxEbKyFYh9DIopWq0aKXQT
-Bi9FwEiDYIn9jH+jTZ5dHKlhGf3VoH6jt1mmu71y8trqCwUFVuE=
+AwIwEQYDVR0RBAowCIIGdGFyZ2V0MA0GCSqGSIb3DQEBCwUAA4IBAQBYi0wZy4/h
+d0eGA/Qn6Cz/5rM035yXkNmi9KbKvqoLWgOExtLAzjHFizA6SJohQmG2IZaQsfdu
+igLV/bouTiISDa2xjUpLFuqGjARl/ZxVCRfyy/O2lLzF+47zjNlIlX+4PVDw6yD9
+k4nGIQk5JuJo0jQ/J9AlX7bkev+M2jw4fPdRl62DOmmYi4rf+LrnC6L2613H232O
+ADyuGCtmd1CbjNUu7xXg69reeHhz0Lq72C4KA/MFezu8CaFNPPcpY+H1ay88Ramf
+W20Tgubh8cFWs7/drO+r0fne3DLOUC2MtjD5E/gfoi7qQ4xQ2NKxqK8KxO9ML2E8
+jK80ooDV/iEr
 -----END CERTIFICATE-----
diff --git a/net/data/cert_issuer_source_aia_unittest/target_invalid_url_aia.pem b/net/data/cert_issuer_source_aia_unittest/target_invalid_url_aia.pem
index 2bf9b60..8b7b1a72d 100644
--- a/net/data/cert_issuer_source_aia_unittest/target_invalid_url_aia.pem
+++ b/net/data/cert_issuer_source_aia_unittest/target_invalid_url_aia.pem
@@ -12,30 +12,30 @@
             Public Key Algorithm: rsaEncryption
                 Public-Key: (2048 bit)
                 Modulus:
-                    00:a2:bc:d6:77:b0:d2:ca:cf:ec:a9:ae:5a:5d:88:
-                    50:50:12:9e:76:62:86:dc:61:78:d8:13:b3:e0:4f:
-                    a8:d3:54:57:b5:ce:bf:75:c7:56:27:d2:8e:61:9c:
-                    48:cb:3e:d2:bb:17:69:63:ca:eb:a4:56:bd:90:32:
-                    28:bb:0a:ae:9d:4d:60:40:16:3b:4c:ca:4e:da:55:
-                    d2:84:16:ae:c5:66:eb:bb:8b:3d:33:05:dc:e8:f3:
-                    db:4d:4f:87:5c:eb:11:28:bc:ed:c8:fe:9d:b1:8a:
-                    eb:c3:79:d0:e6:99:41:52:ec:68:97:48:78:4a:c3:
-                    e1:b6:ec:38:1e:38:5b:fe:1b:f5:b4:76:94:d0:f3:
-                    89:50:da:97:0b:f3:5e:86:bd:26:72:de:bb:41:92:
-                    a4:a1:bf:77:55:aa:b1:f3:95:6f:c2:ac:bf:ad:8a:
-                    a6:c4:2b:5e:ed:55:55:a6:c4:fe:6c:68:dd:ea:54:
-                    3f:46:b2:98:e7:fa:54:fa:be:65:7a:5f:4f:c8:45:
-                    d4:5d:7b:a0:56:35:83:d8:f0:e9:7f:63:0f:87:b6:
-                    82:bc:2f:53:5d:01:f2:94:bf:12:37:84:e6:a0:63:
-                    8c:8a:bc:a1:c9:1f:3c:1e:fb:95:60:41:47:bf:60:
-                    1a:f3:7c:99:7d:66:75:99:5d:c2:ca:53:c1:8b:99:
-                    59:37
+                    00:d8:3c:a7:4c:90:77:93:ce:72:3b:a5:61:af:f1:
+                    fd:2f:72:2e:3f:37:2c:7d:94:45:c7:c9:7e:b4:26:
+                    65:2b:d3:42:fb:89:bb:b0:a1:68:e8:4f:4d:c3:dd:
+                    b8:3c:ad:ec:0d:1b:f9:e9:ba:99:f5:74:26:11:2e:
+                    62:e1:e9:4a:d9:07:e3:82:dc:44:66:53:83:bd:aa:
+                    08:4c:9c:14:fa:3f:80:ba:b0:10:48:2d:59:73:cb:
+                    22:65:42:1c:68:c4:9d:fb:94:75:5f:84:11:61:7c:
+                    10:08:a8:48:04:99:75:8a:d2:5e:89:16:0c:04:62:
+                    e2:ae:23:7c:b1:cb:ce:f8:eb:a5:a4:32:66:83:0d:
+                    9e:a7:7c:40:5f:41:c9:e6:63:d0:a6:8b:94:4b:aa:
+                    25:38:db:46:d9:16:14:dd:a0:29:16:99:a8:f4:0a:
+                    87:58:71:3d:b4:a7:e3:d1:10:0e:96:b2:70:fb:59:
+                    09:22:e8:19:9f:c2:1d:11:c6:26:dc:1c:3d:4d:52:
+                    13:c8:3e:38:c8:7e:90:0f:9b:d0:60:03:6b:19:f6:
+                    71:6a:22:a1:1f:00:c5:63:19:36:a3:db:da:6c:b2:
+                    b8:fe:a9:1c:37:19:00:ce:03:60:58:6e:da:cd:31:
+                    7e:ee:69:06:12:36:c4:11:66:53:a2:14:9b:75:af:
+                    eb:2f
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Subject Key Identifier: 
-                09:96:BA:42:0D:69:29:BC:6A:FB:3C:58:30:08:12:31:BF:5B:C0:CB
+                43:35:C7:A5:6B:23:40:8A:30:33:E2:B1:4E:51:18:C8:EC:3A:79:F3
             X509v3 Authority Key Identifier: 
-                keyid:40:91:28:21:9D:93:F3:9C:18:1B:FF:00:9C:B2:08:A0:A3:81:7D:2A
+                keyid:84:BA:05:06:4E:33:9D:11:AA:7A:F1:77:1F:A4:69:7E:4C:2D:D4:3F
 
             Authority Information Access: 
                 CA Issuers - URI:foobar
@@ -49,39 +49,42 @@
                 Digital Signature, Key Encipherment
             X509v3 Extended Key Usage: 
                 TLS Web Server Authentication, TLS Web Client Authentication
+            X509v3 Subject Alternative Name: 
+                DNS:target
     Signature Algorithm: sha256WithRSAEncryption
-         40:71:3c:29:92:1a:64:8e:7f:5b:3f:89:2f:33:b6:5f:9f:a7:
-         de:3a:c8:30:97:4d:67:96:c1:28:e0:7e:49:bb:07:05:09:d3:
-         47:62:4f:79:8b:e7:12:ad:59:ff:84:4f:e8:a8:49:99:93:47:
-         e8:14:85:ff:dc:de:4c:e7:e5:69:c8:3c:93:5f:11:d1:0b:e0:
-         98:e3:41:5b:25:5a:90:dd:c1:ce:d9:5c:de:fb:0a:74:fc:fd:
-         52:49:55:cc:cc:85:f3:00:e9:48:5f:72:06:8e:82:4d:54:62:
-         d2:fe:a3:8c:6d:87:6e:30:d7:26:34:d2:db:ec:cf:7e:e6:38:
-         0c:b0:c9:0b:16:09:e1:15:3d:ed:63:87:9d:63:a6:3f:78:29:
-         1a:71:c0:6e:c4:0c:9f:ad:3f:29:0a:7d:7f:3a:09:36:ee:1f:
-         4e:9f:d9:95:0f:c9:21:e4:92:ae:eb:76:bb:b9:41:ca:e3:86:
-         92:54:c7:48:c9:89:d5:0a:5a:f4:b0:48:8a:ef:bd:99:03:dd:
-         93:bc:22:ee:97:78:79:3a:1e:d1:2c:b2:d7:59:d6:79:a3:f9:
-         28:47:e8:9a:fe:21:4b:f4:d8:a7:8b:de:9a:49:d6:6b:86:2c:
-         8f:ad:76:70:e1:f2:12:ad:26:85:c4:4a:d5:48:58:61:fa:79:
-         42:9c:03:6f
+         1b:31:59:4e:06:a8:af:82:35:d2:5f:30:33:ed:8c:58:79:ef:
+         80:fd:b4:e8:ac:45:2a:ed:b8:cf:a7:37:7e:c7:f6:d3:ea:8d:
+         f1:eb:38:87:16:5e:d8:62:0b:56:a1:37:74:18:c3:85:bd:79:
+         c6:9c:06:57:4a:60:3a:d3:17:db:60:4b:f2:19:ff:54:38:04:
+         7a:2b:f1:b6:f7:47:d1:71:51:22:cf:de:b2:14:9b:e4:66:f2:
+         cf:be:98:10:77:1d:8e:f5:7b:51:fe:ca:33:0d:8d:24:d4:be:
+         8f:96:3d:67:0e:ad:b0:3c:28:13:58:05:fd:23:9c:0f:fe:1b:
+         d6:8a:42:e6:c7:ad:c5:66:ca:4a:16:6e:d3:3c:4c:f5:a6:76:
+         7e:68:51:38:af:1c:75:9c:ac:f1:14:5e:11:47:b0:ea:e8:8c:
+         00:2d:00:7e:be:e8:30:e1:16:47:3e:93:6b:e5:30:19:2e:98:
+         56:d0:7f:0f:48:6f:82:59:e5:38:e5:96:15:36:75:94:a1:e8:
+         ce:22:91:0f:32:f1:6c:a2:ed:c4:72:14:51:90:3d:3b:73:cd:
+         12:02:1d:a0:b3:fe:14:e5:ac:b5:b1:3c:18:99:5d:de:2e:fc:
+         3c:e4:9a:1f:ff:65:96:6b:48:2b:dd:d8:c2:d7:a8:5c:85:91:
+         f8:1f:22:a4
 -----BEGIN CERTIFICATE-----
-MIIDWjCCAkKgAwIBAgIBBzANBgkqhkiG9w0BAQsFADAMMQowCAYDVQQDDAFJMB4X
+MIIDbTCCAlWgAwIBAgIBBzANBgkqhkiG9w0BAQsFADAMMQowCAYDVQQDDAFJMB4X
 DTE1MDEwMTEyMDAwMFoXDTIxMDEwMTEyMDAwMFowETEPMA0GA1UEAwwGdGFyZ2V0
-MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAorzWd7DSys/sqa5aXYhQ
-UBKedmKG3GF42BOz4E+o01RXtc6/dcdWJ9KOYZxIyz7SuxdpY8rrpFa9kDIouwqu
-nU1gQBY7TMpO2lXShBauxWbru4s9MwXc6PPbTU+HXOsRKLztyP6dsYrrw3nQ5plB
-Uuxol0h4SsPhtuw4Hjhb/hv1tHaU0POJUNqXC/Nehr0mct67QZKkob93Vaqx85Vv
-wqy/rYqmxCte7VVVpsT+bGjd6lQ/RrKY5/pU+r5lel9PyEXUXXugVjWD2PDpf2MP
-h7aCvC9TXQHylL8SN4TmoGOMiryhyR88HvuVYEFHv2Aa83yZfWZ1mV3CylPBi5lZ
-NwIDAQABo4HBMIG+MB0GA1UdDgQWBBQJlrpCDWkpvGr7PFgwCBIxv1vAyzAfBgNV
-HSMEGDAWgBRAkSghnZPznBgb/wCcsgigo4F9KjAiBggrBgEFBQcBAQQWMBQwEgYI
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2DynTJB3k85yO6Vhr/H9
+L3IuPzcsfZRFx8l+tCZlK9NC+4m7sKFo6E9Nw924PK3sDRv56bqZ9XQmES5i4elK
+2QfjgtxEZlODvaoITJwU+j+AurAQSC1Zc8siZUIcaMSd+5R1X4QRYXwQCKhIBJl1
+itJeiRYMBGLiriN8scvO+OulpDJmgw2ep3xAX0HJ5mPQpouUS6olONtG2RYU3aAp
+Fpmo9AqHWHE9tKfj0RAOlrJw+1kJIugZn8IdEcYm3Bw9TVITyD44yH6QD5vQYANr
+GfZxaiKhHwDFYxk2o9vabLK4/qkcNxkAzgNgWG7azTF+7mkGEjbEEWZTohSbda/r
+LwIDAQABo4HUMIHRMB0GA1UdDgQWBBRDNcelayNAijAz4rFOURjI7Dp58zAfBgNV
+HSMEGDAWgBSEugUGTjOdEap68XcfpGl+TC3UPzAiBggrBgEFBQcBAQQWMBQwEgYI
 KwYBBQUHMAKGBmZvb2JhcjApBgNVHR8EIjAgMB6gHKAahhhodHRwOi8vdXJsLWZv
 ci1jcmwvSS5jcmwwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMB
-BggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAAOCAQEAQHE8KZIaZI5/Wz+JLzO2X5+n
-3jrIMJdNZ5bBKOB+SbsHBQnTR2JPeYvnEq1Z/4RP6KhJmZNH6BSF/9zeTOflacg8
-k18R0QvgmONBWyVakN3Bztlc3vsKdPz9UklVzMyF8wDpSF9yBo6CTVRi0v6jjG2H
-bjDXJjTS2+zPfuY4DLDJCxYJ4RU97WOHnWOmP3gpGnHAbsQMn60/KQp9fzoJNu4f
-Tp/ZlQ/JIeSSrut2u7lByuOGklTHSMmJ1Qpa9LBIiu+9mQPdk7wi7pd4eToe0Syy
-11nWeaP5KEfomv4hS/TYp4vemknWa4Ysj612cOHyEq0mhcRK1UhYYfp5QpwDbw==
+BggrBgEFBQcDAjARBgNVHREECjAIggZ0YXJnZXQwDQYJKoZIhvcNAQELBQADggEB
+ABsxWU4GqK+CNdJfMDPtjFh574D9tOisRSrtuM+nN37H9tPqjfHrOIcWXthiC1ah
+N3QYw4W9ecacBldKYDrTF9tgS/IZ/1Q4BHor8bb3R9FxUSLP3rIUm+Rm8s++mBB3
+HY71e1H+yjMNjSTUvo+WPWcOrbA8KBNYBf0jnA/+G9aKQubHrcVmykoWbtM8TPWm
+dn5oUTivHHWcrPEUXhFHsOrojAAtAH6+6DDhFkc+k2vlMBkumFbQfw9Ib4JZ5Tjl
+lhU2dZSh6M4ikQ8y8Wyi7cRyFFGQPTtzzRICHaCz/hTlrLWxPBiZXd4u/Dzkmh//
+ZZZrSCvd2MLXqFyFkfgfIqQ=
 -----END CERTIFICATE-----
diff --git a/net/data/cert_issuer_source_aia_unittest/target_no_aia.pem b/net/data/cert_issuer_source_aia_unittest/target_no_aia.pem
index e1279a4..a98b38cb 100644
--- a/net/data/cert_issuer_source_aia_unittest/target_no_aia.pem
+++ b/net/data/cert_issuer_source_aia_unittest/target_no_aia.pem
@@ -12,30 +12,30 @@
             Public Key Algorithm: rsaEncryption
                 Public-Key: (2048 bit)
                 Modulus:
-                    00:b3:43:32:88:c1:3b:65:14:01:c1:e3:e7:52:74:
-                    40:83:65:0d:97:4a:0a:64:60:86:72:b8:89:99:da:
-                    f9:ab:21:74:ce:f8:89:f7:34:d8:4c:51:34:3d:56:
-                    1a:a2:fb:90:55:5a:62:e3:ab:16:3b:a8:8f:cd:f7:
-                    43:5a:e9:f0:1c:d5:38:a6:f7:e0:26:11:d7:bb:01:
-                    74:88:a6:e2:86:57:a0:78:ac:d4:1e:01:c6:4b:08:
-                    f7:d3:02:6f:fa:3d:7b:6f:ca:7b:1d:ae:44:59:e2:
-                    86:4a:34:5b:e2:18:c9:fd:f9:a4:39:4e:e0:2a:41:
-                    4e:86:f3:d5:9b:0c:00:a7:b5:81:92:e2:44:56:9d:
-                    02:66:e6:50:02:02:44:b4:5f:02:ac:ae:50:12:75:
-                    7e:62:7e:b7:44:17:e1:e2:43:f7:1a:03:31:84:86:
-                    8a:63:4f:76:73:49:92:ab:8e:61:78:4c:a2:c5:53:
-                    a7:c4:c1:91:20:08:45:fd:4d:97:1f:65:20:d4:e5:
-                    e8:db:67:2c:7b:aa:dd:98:de:d8:3b:0e:af:09:52:
-                    17:af:d8:21:67:08:1d:df:ad:41:f1:62:f2:6e:8e:
-                    f7:0b:80:a8:d4:29:7b:5f:87:e0:a1:96:e3:60:98:
-                    5f:c1:63:b8:eb:01:9d:b7:51:30:01:bd:1b:a7:7e:
-                    be:ad
+                    00:bc:7b:d4:48:5a:3b:ab:be:72:da:b4:1d:81:4d:
+                    42:5b:82:82:c2:10:11:36:b9:59:00:88:18:bd:99:
+                    a2:f0:40:cb:ae:bb:99:81:66:a3:45:ee:cd:da:f1:
+                    83:91:1b:5a:65:33:86:6e:ed:15:eb:54:a9:20:17:
+                    2b:1e:13:fe:69:a0:6c:72:a5:ca:be:2f:d3:d5:14:
+                    2a:91:d5:08:bd:6b:26:e8:a4:a8:19:97:b3:1f:28:
+                    6f:59:54:dc:65:61:34:05:fe:67:80:d3:63:9d:a5:
+                    e7:a2:e0:aa:12:e6:d0:77:ff:72:27:84:23:fa:18:
+                    00:85:e3:fc:66:0b:99:31:0e:a2:fd:c8:ca:cc:64:
+                    da:14:27:b3:9e:cf:a6:10:0a:5a:29:1a:29:b8:6a:
+                    b5:a1:fe:89:ae:51:e7:f2:5b:ab:7f:c6:37:51:44:
+                    81:30:3a:35:e2:28:a8:7f:4b:7a:c8:a3:c9:13:11:
+                    23:de:4a:4b:52:41:cb:64:81:13:1b:d2:ac:cd:c5:
+                    a0:96:b6:a2:c7:f7:55:06:cb:fd:64:be:e1:22:b3:
+                    a0:bd:77:46:be:1e:eb:ea:cd:de:af:a5:89:13:82:
+                    55:12:b8:c4:6b:01:33:69:32:21:18:c3:1c:01:1b:
+                    09:2b:a4:cb:80:23:15:3b:26:ea:c3:01:59:8c:a2:
+                    35:c3
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Subject Key Identifier: 
-                B7:FF:6C:44:69:C6:FE:C3:8B:69:5F:60:FB:BC:5D:76:FE:50:D3:1A
+                D2:58:5E:31:E6:B5:6D:8F:58:B6:D0:DA:C1:4D:38:43:9A:D3:C1:7A
             X509v3 Authority Key Identifier: 
-                keyid:40:91:28:21:9D:93:F3:9C:18:1B:FF:00:9C:B2:08:A0:A3:81:7D:2A
+                keyid:84:BA:05:06:4E:33:9D:11:AA:7A:F1:77:1F:A4:69:7E:4C:2D:D4:3F
 
             X509v3 CRL Distribution Points: 
 
@@ -46,39 +46,41 @@
                 Digital Signature, Key Encipherment
             X509v3 Extended Key Usage: 
                 TLS Web Server Authentication, TLS Web Client Authentication
+            X509v3 Subject Alternative Name: 
+                DNS:target
     Signature Algorithm: sha256WithRSAEncryption
-         76:cf:2a:df:5e:f3:e8:b2:b2:13:c6:59:a2:98:4e:46:42:48:
-         9a:a4:5e:d1:3a:c9:5b:4d:4f:69:74:ca:26:af:43:79:52:5c:
-         7d:13:7f:ba:1e:0c:1a:47:6d:72:89:8c:5b:2d:11:de:3f:df:
-         20:3d:32:94:9a:34:87:b6:e1:93:ae:73:98:31:c7:40:b4:ad:
-         95:97:e5:2a:f8:17:c2:2e:a3:ac:7c:d6:a6:db:66:1c:1f:85:
-         ae:7b:e8:cd:d4:95:27:16:80:b0:d8:4c:e9:02:40:61:89:7f:
-         58:40:7e:0d:74:cc:f3:d4:98:f9:eb:18:b9:12:78:17:22:f0:
-         13:aa:0f:1b:c4:12:fc:77:9d:ef:cb:12:e5:99:aa:03:76:ff:
-         41:07:20:3c:3f:5f:cb:de:a4:9c:6f:a0:eb:83:84:d2:32:1b:
-         c9:ee:e8:30:9b:a9:d9:2d:57:72:e0:a1:b1:f2:94:82:fe:8f:
-         05:6d:52:c4:17:96:14:79:be:22:85:27:78:6e:25:fb:56:3c:
-         34:d5:8b:a5:e5:f8:2d:31:6a:d5:fc:7c:e6:9d:8b:fc:d8:42:
-         24:c3:b7:67:99:8a:46:fb:f0:a3:74:fd:eb:71:94:a4:31:b3:
-         94:b1:90:c4:42:04:32:56:0c:c6:70:b0:bd:22:ce:1f:95:f1:
-         25:80:ac:8e
+         59:c0:18:ae:e6:ec:1d:a0:df:9c:07:d9:94:1b:a1:dd:22:14:
+         8f:6f:2c:17:e3:cd:b8:83:17:aa:6d:34:d5:3f:3b:6d:ab:6d:
+         fe:c0:9d:c6:d9:1b:77:32:8b:0d:4e:4f:64:d5:49:c5:71:08:
+         1e:a2:87:0f:28:27:6e:a5:b9:a1:02:da:c4:b7:a8:49:dd:ce:
+         b2:39:67:67:e8:ee:f0:bf:83:bb:0f:21:9f:a2:62:53:1e:7f:
+         a0:84:8a:1b:c4:62:98:06:4d:5d:6b:3f:55:5b:71:e3:4c:fc:
+         6b:4d:38:ed:f7:84:11:26:86:58:2e:7a:1d:4c:8f:30:ea:ab:
+         5d:55:44:2a:ae:35:42:16:bc:c9:ee:88:6c:9f:79:f5:f2:a0:
+         c2:5b:e7:c0:fb:01:11:50:0c:1d:ea:62:79:79:59:cd:34:4b:
+         60:9f:cf:4c:66:eb:8f:28:52:54:ff:6a:df:12:ab:c3:35:8b:
+         31:4d:9e:bc:02:c0:87:5e:ff:80:1f:ba:b4:a4:22:89:2f:ae:
+         f4:fb:07:86:9d:72:b3:36:ac:9e:95:e0:6b:a2:67:54:ef:90:
+         f0:c8:81:92:0d:4e:a4:7f:2b:bb:3e:5e:6c:ed:cf:45:20:76:
+         ab:07:b5:07:48:8d:33:08:a1:89:b8:5f:f8:33:e7:31:42:4a:
+         4f:6e:59:18
 -----BEGIN CERTIFICATE-----
-MIIDNjCCAh6gAwIBAgIBAjANBgkqhkiG9w0BAQsFADAMMQowCAYDVQQDDAFJMB4X
+MIIDSTCCAjGgAwIBAgIBAjANBgkqhkiG9w0BAQsFADAMMQowCAYDVQQDDAFJMB4X
 DTE1MDEwMTEyMDAwMFoXDTIxMDEwMTEyMDAwMFowETEPMA0GA1UEAwwGdGFyZ2V0
-MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs0MyiME7ZRQBwePnUnRA
-g2UNl0oKZGCGcriJmdr5qyF0zviJ9zTYTFE0PVYaovuQVVpi46sWO6iPzfdDWunw
-HNU4pvfgJhHXuwF0iKbihlegeKzUHgHGSwj30wJv+j17b8p7Ha5EWeKGSjRb4hjJ
-/fmkOU7gKkFOhvPVmwwAp7WBkuJEVp0CZuZQAgJEtF8CrK5QEnV+Yn63RBfh4kP3
-GgMxhIaKY092c0mSq45heEyixVOnxMGRIAhF/U2XH2Ug1OXo22cse6rdmN7YOw6v
-CVIXr9ghZwgd361B8WLybo73C4Co1Cl7X4fgoZbjYJhfwWO46wGdt1EwAb0bp36+
-rQIDAQABo4GdMIGaMB0GA1UdDgQWBBS3/2xEacb+w4tpX2D7vF12/lDTGjAfBgNV
-HSMEGDAWgBRAkSghnZPznBgb/wCcsgigo4F9KjApBgNVHR8EIjAgMB6gHKAahhho
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvHvUSFo7q75y2rQdgU1C
+W4KCwhARNrlZAIgYvZmi8EDLrruZgWajRe7N2vGDkRtaZTOGbu0V61SpIBcrHhP+
+aaBscqXKvi/T1RQqkdUIvWsm6KSoGZezHyhvWVTcZWE0Bf5ngNNjnaXnouCqEubQ
+d/9yJ4Qj+hgAheP8ZguZMQ6i/cjKzGTaFCezns+mEApaKRopuGq1of6JrlHn8lur
+f8Y3UUSBMDo14iiof0t6yKPJExEj3kpLUkHLZIETG9KszcWglraix/dVBsv9ZL7h
+IrOgvXdGvh7r6s3er6WJE4JVErjEawEzaTIhGMMcARsJK6TLgCMVOybqwwFZjKI1
+wwIDAQABo4GwMIGtMB0GA1UdDgQWBBTSWF4x5rVtj1i20NrBTThDmtPBejAfBgNV
+HSMEGDAWgBSEugUGTjOdEap68XcfpGl+TC3UPzApBgNVHR8EIjAgMB6gHKAahhho
 dHRwOi8vdXJsLWZvci1jcmwvSS5jcmwwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQW
-MBQGCCsGAQUFBwMBBggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAAOCAQEAds8q317z
-6LKyE8ZZophORkJImqRe0TrJW01PaXTKJq9DeVJcfRN/uh4MGkdtcomMWy0R3j/f
-ID0ylJo0h7bhk65zmDHHQLStlZflKvgXwi6jrHzWpttmHB+FrnvozdSVJxaAsNhM
-6QJAYYl/WEB+DXTM89SY+esYuRJ4FyLwE6oPG8QS/Hed78sS5ZmqA3b/QQcgPD9f
-y96knG+g64OE0jIbye7oMJup2S1XcuChsfKUgv6PBW1SxBeWFHm+IoUneG4l+1Y8
-NNWLpeX4LTFq1fx85p2L/NhCJMO3Z5mKRvvwo3T963GUpDGzlLGQxEIEMlYMxnCw
-vSLOH5XxJYCsjg==
+MBQGCCsGAQUFBwMBBggrBgEFBQcDAjARBgNVHREECjAIggZ0YXJnZXQwDQYJKoZI
+hvcNAQELBQADggEBAFnAGK7m7B2g35wH2ZQbod0iFI9vLBfjzbiDF6ptNNU/O22r
+bf7AncbZG3cyiw1OT2TVScVxCB6ihw8oJ26luaEC2sS3qEndzrI5Z2fo7vC/g7sP
+IZ+iYlMef6CEihvEYpgGTV1rP1VbceNM/GtNOO33hBEmhlgueh1MjzDqq11VRCqu
+NUIWvMnuiGyfefXyoMJb58D7ARFQDB3qYnl5Wc00S2Cfz0xm648oUlT/at8Sq8M1
+izFNnrwCwIde/4AfurSkIokvrvT7B4adcrM2rJ6V4GuiZ1TvkPDIgZINTqR/K7s+
+Xmztz0UgdqsHtQdIjTMIoYm4X/gz5zFCSk9uWRg=
 -----END CERTIFICATE-----
diff --git a/net/data/cert_issuer_source_aia_unittest/target_one_aia.pem b/net/data/cert_issuer_source_aia_unittest/target_one_aia.pem
index c89862f7..32c4655 100644
--- a/net/data/cert_issuer_source_aia_unittest/target_one_aia.pem
+++ b/net/data/cert_issuer_source_aia_unittest/target_one_aia.pem
@@ -12,30 +12,30 @@
             Public Key Algorithm: rsaEncryption
                 Public-Key: (2048 bit)
                 Modulus:
-                    00:ba:f4:30:40:ee:e8:c3:44:66:c1:07:f4:27:30:
-                    bc:76:aa:df:c1:f9:84:f8:2d:60:d8:a3:96:8c:9e:
-                    e6:9d:ea:d9:98:dc:64:01:3e:ae:9f:82:23:52:64:
-                    60:75:98:9c:2d:ea:55:a3:80:42:be:31:9d:51:49:
-                    a6:ea:e3:9d:a8:cc:89:93:36:3a:a3:33:5c:56:e9:
-                    4b:f0:cf:81:bd:5e:52:05:44:34:ad:25:af:61:b5:
-                    da:d5:30:e9:18:e0:23:64:1c:08:d2:8f:43:8f:84:
-                    3b:62:7e:2e:e8:71:8a:0b:9a:4d:0e:20:90:14:77:
-                    40:83:39:92:93:66:44:7f:c9:94:e0:ba:7b:82:95:
-                    4d:bf:3a:72:8f:00:4c:62:dc:72:a7:43:43:53:0b:
-                    bb:52:b5:3f:42:5b:3b:6a:89:a2:ed:c9:27:0b:49:
-                    74:51:da:0e:53:72:87:7c:4c:30:26:a4:ca:53:59:
-                    8e:4f:75:b7:c8:1e:7b:77:35:d8:5e:f7:9f:f4:1b:
-                    77:31:19:4f:4b:f9:1f:e6:c0:84:9c:21:b0:5f:1d:
-                    5e:24:14:35:ee:80:98:8d:eb:77:06:6f:27:61:fc:
-                    ac:3b:99:f5:d9:86:85:ee:e1:79:90:62:05:b6:58:
-                    a2:9e:31:34:d7:b9:38:39:3b:91:92:37:de:68:e0:
-                    4b:85
+                    00:e6:20:5f:6c:8f:17:bb:ad:da:b9:19:22:1e:19:
+                    dc:04:47:cd:0b:e9:72:33:6f:5e:c6:91:aa:7e:6e:
+                    8b:9a:9d:6a:41:47:3f:67:8e:da:bf:ec:76:d9:e7:
+                    91:58:9a:9a:ab:b5:47:5f:90:c1:c3:31:de:ae:17:
+                    09:b4:6a:b9:07:1a:82:a1:0a:76:df:69:91:5a:01:
+                    ed:ec:bd:1f:cc:9e:c5:27:54:1d:48:f5:16:e0:11:
+                    3d:f0:8c:a6:91:ec:41:35:c0:ea:5f:61:d8:14:a5:
+                    b5:48:7a:fd:fd:f8:9e:30:50:bb:73:70:4b:bb:52:
+                    a8:73:18:90:75:3a:1d:42:7b:d7:0c:26:fd:83:26:
+                    43:47:f6:a8:2e:46:6d:01:96:2d:12:5a:d7:ec:cb:
+                    46:fe:22:c1:3c:a0:8b:43:d6:92:be:ba:0c:05:01:
+                    59:0d:ea:32:ee:d2:fe:63:76:17:f4:a4:c3:74:85:
+                    1e:2f:15:fe:01:b8:1a:27:4f:96:20:55:c2:6e:a4:
+                    b0:3e:ef:ac:07:b9:2f:e3:55:1b:1f:ab:2d:5d:aa:
+                    fc:95:85:9f:ee:e3:25:ee:df:b3:3a:2f:69:04:bb:
+                    e7:37:54:56:3a:02:d2:12:79:05:56:a5:03:3c:47:
+                    f0:12:56:3d:3b:ff:f3:28:8f:73:96:93:38:21:5f:
+                    98:3b
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Subject Key Identifier: 
-                F4:04:58:42:C7:F3:33:C8:D7:AE:12:EC:87:E9:98:48:2D:E9:33:1E
+                EF:EB:BB:51:07:08:E2:B1:D5:35:CC:96:47:4C:E6:3E:00:0D:8C:AE
             X509v3 Authority Key Identifier: 
-                keyid:40:91:28:21:9D:93:F3:9C:18:1B:FF:00:9C:B2:08:A0:A3:81:7D:2A
+                keyid:84:BA:05:06:4E:33:9D:11:AA:7A:F1:77:1F:A4:69:7E:4C:2D:D4:3F
 
             Authority Information Access: 
                 CA Issuers - URI:http://url-for-aia/I.cer
@@ -49,40 +49,42 @@
                 Digital Signature, Key Encipherment
             X509v3 Extended Key Usage: 
                 TLS Web Server Authentication, TLS Web Client Authentication
+            X509v3 Subject Alternative Name: 
+                DNS:target
     Signature Algorithm: sha256WithRSAEncryption
-         0f:eb:81:92:ea:ac:d4:ac:84:d7:a2:b0:b0:55:78:47:37:af:
-         e5:0d:97:a6:ff:67:ff:e7:3b:71:8b:0d:67:84:b5:d2:4f:8f:
-         5f:2b:26:f7:92:66:1d:8a:5d:b6:25:24:6f:84:2f:bc:ea:30:
-         1d:f8:34:84:12:ea:69:05:76:d5:61:dd:eb:d3:70:3b:68:58:
-         87:f9:c6:cf:04:6e:8a:e5:02:94:39:9d:a1:45:50:92:00:20:
-         98:d6:6f:a4:45:08:83:f8:3a:f0:67:aa:67:01:79:c9:bc:89:
-         8e:77:68:15:20:00:d0:3d:80:d4:c4:e1:7a:73:cd:16:18:bd:
-         7c:a4:5c:2f:5c:c9:d7:2e:63:e8:38:63:b5:f4:6a:11:c9:1f:
-         8e:3b:44:9a:51:d0:d8:8d:a6:33:ab:12:4c:76:27:36:67:ec:
-         15:2e:93:79:e5:33:b5:7a:74:c6:ac:c2:82:79:4f:cf:96:79:
-         20:81:4f:aa:12:25:03:9c:0c:45:83:65:5e:45:e1:01:00:a2:
-         b7:a4:27:00:4f:ad:c1:2a:e6:66:46:16:44:0e:9d:c4:32:73:
-         72:ae:f9:2b:d9:71:0a:d6:ca:56:a8:9b:8b:c2:44:b5:fe:48:
-         54:c9:b8:60:d8:5d:c2:2f:2c:34:73:66:54:5c:c3:c9:8d:c6:
-         c7:a8:76:d8
+         91:15:64:f2:07:45:63:3c:8b:07:28:31:76:22:df:a1:1e:cd:
+         a0:a1:8f:9c:62:99:f2:22:f6:22:fb:e4:74:ef:77:17:50:16:
+         05:99:46:c5:79:66:19:62:ea:57:38:0c:f2:0d:55:2a:95:7e:
+         10:4f:b4:a9:3a:c7:61:af:37:cd:b5:70:85:c0:9e:db:3a:ca:
+         70:96:ca:2c:7f:e6:c4:47:f3:42:ae:c3:64:14:31:23:4e:7d:
+         24:9b:23:6d:87:69:02:b9:1f:1c:e0:b6:8d:e5:ad:5c:13:f4:
+         9f:a3:d8:3b:08:48:24:e5:df:bf:15:03:a4:5a:c7:8d:39:1c:
+         6d:1c:45:db:3c:ac:63:39:71:fd:33:4c:b7:3c:ec:5c:de:c8:
+         a5:41:d9:75:52:c9:45:cc:b7:fa:14:9f:ba:d1:04:aa:9d:ea:
+         23:93:e2:c6:35:33:e8:f8:2e:6a:13:e5:ce:f0:ed:8a:b0:5b:
+         31:1a:56:91:15:2a:d8:e6:d4:bb:70:91:9d:8d:37:53:09:9a:
+         af:af:84:67:2c:59:c3:2e:da:56:a6:1f:9b:75:c6:80:b0:f4:
+         95:a7:78:15:e3:b5:e9:06:f9:01:63:5b:bf:2f:dd:ff:65:b9:
+         cc:9b:90:a6:de:90:e3:32:f7:48:bf:3b:fa:a0:c3:98:15:58:
+         53:ad:ad:28
 -----BEGIN CERTIFICATE-----
-MIIDbDCCAlSgAwIBAgIBATANBgkqhkiG9w0BAQsFADAMMQowCAYDVQQDDAFJMB4X
+MIIDfzCCAmegAwIBAgIBATANBgkqhkiG9w0BAQsFADAMMQowCAYDVQQDDAFJMB4X
 DTE1MDEwMTEyMDAwMFoXDTIxMDEwMTEyMDAwMFowETEPMA0GA1UEAwwGdGFyZ2V0
-MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuvQwQO7ow0RmwQf0JzC8
-dqrfwfmE+C1g2KOWjJ7mnerZmNxkAT6un4IjUmRgdZicLepVo4BCvjGdUUmm6uOd
-qMyJkzY6ozNcVulL8M+BvV5SBUQ0rSWvYbXa1TDpGOAjZBwI0o9Dj4Q7Yn4u6HGK
-C5pNDiCQFHdAgzmSk2ZEf8mU4Lp7gpVNvzpyjwBMYtxyp0NDUwu7UrU/Qls7aomi
-7cknC0l0UdoOU3KHfEwwJqTKU1mOT3W3yB57dzXYXvef9Bt3MRlPS/kf5sCEnCGw
-Xx1eJBQ17oCYjet3Bm8nYfysO5n12YaF7uF5kGIFtliinjE017k4OTuRkjfeaOBL
-hQIDAQABo4HTMIHQMB0GA1UdDgQWBBT0BFhCx/MzyNeuEuyH6ZhILekzHjAfBgNV
-HSMEGDAWgBRAkSghnZPznBgb/wCcsgigo4F9KjA0BggrBgEFBQcBAQQoMCYwJAYI
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5iBfbI8Xu63auRkiHhnc
+BEfNC+lyM29expGqfm6Lmp1qQUc/Z47av+x22eeRWJqaq7VHX5DBwzHerhcJtGq5
+BxqCoQp232mRWgHt7L0fzJ7FJ1QdSPUW4BE98IymkexBNcDqX2HYFKW1SHr9/fie
+MFC7c3BLu1KocxiQdTodQnvXDCb9gyZDR/aoLkZtAZYtElrX7MtG/iLBPKCLQ9aS
+vroMBQFZDeoy7tL+Y3YX9KTDdIUeLxX+AbgaJ0+WIFXCbqSwPu+sB7kv41UbH6st
+Xar8lYWf7uMl7t+zOi9pBLvnN1RWOgLSEnkFVqUDPEfwElY9O//zKI9zlpM4IV+Y
+OwIDAQABo4HmMIHjMB0GA1UdDgQWBBTv67tRBwjisdU1zJZHTOY+AA2MrjAfBgNV
+HSMEGDAWgBSEugUGTjOdEap68XcfpGl+TC3UPzA0BggrBgEFBQcBAQQoMCYwJAYI
 KwYBBQUHMAKGGGh0dHA6Ly91cmwtZm9yLWFpYS9JLmNlcjApBgNVHR8EIjAgMB6g
 HKAahhhodHRwOi8vdXJsLWZvci1jcmwvSS5jcmwwDgYDVR0PAQH/BAQDAgWgMB0G
-A1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAAOCAQEA
-D+uBkuqs1KyE16KwsFV4Rzev5Q2Xpv9n/+c7cYsNZ4S10k+PXysm95JmHYpdtiUk
-b4QvvOowHfg0hBLqaQV21WHd69NwO2hYh/nGzwRuiuUClDmdoUVQkgAgmNZvpEUI
-g/g68GeqZwF5ybyJjndoFSAA0D2A1MThenPNFhi9fKRcL1zJ1y5j6DhjtfRqEckf
-jjtEmlHQ2I2mM6sSTHYnNmfsFS6TeeUztXp0xqzCgnlPz5Z5IIFPqhIlA5wMRYNl
-XkXhAQCit6QnAE+twSrmZkYWRA6dxDJzcq75K9lxCtbKVqibi8JEtf5IVMm4YNhd
-wi8sNHNmVFzDyY3Gx6h22A==
+A1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjARBgNVHREECjAIggZ0YXJnZXQw
+DQYJKoZIhvcNAQELBQADggEBAJEVZPIHRWM8iwcoMXYi36EezaChj5ximfIi9iL7
+5HTvdxdQFgWZRsV5Zhli6lc4DPINVSqVfhBPtKk6x2GvN821cIXAnts6ynCWyix/
+5sRH80Kuw2QUMSNOfSSbI22HaQK5Hxzgto3lrVwT9J+j2DsISCTl378VA6Rax405
+HG0cRds8rGM5cf0zTLc87FzeyKVB2XVSyUXMt/oUn7rRBKqd6iOT4sY1M+j4LmoT
+5c7w7YqwWzEaVpEVKtjm1LtwkZ2NN1MJmq+vhGcsWcMu2lamH5t1xoCw9JWneBXj
+tekG+QFjW78v3f9lucybkKbekOMy90i/O/qgw5gVWFOtrSg=
 -----END CERTIFICATE-----
diff --git a/net/data/cert_issuer_source_aia_unittest/target_six_aia.pem b/net/data/cert_issuer_source_aia_unittest/target_six_aia.pem
index 1ded810f..f18af2db 100644
--- a/net/data/cert_issuer_source_aia_unittest/target_six_aia.pem
+++ b/net/data/cert_issuer_source_aia_unittest/target_six_aia.pem
@@ -12,30 +12,30 @@
             Public Key Algorithm: rsaEncryption
                 Public-Key: (2048 bit)
                 Modulus:
-                    00:b2:52:ee:94:90:a8:1a:32:bb:4f:64:17:a6:31:
-                    ab:08:09:91:ef:ec:ad:0a:e9:fb:5b:fa:6a:1f:e6:
-                    68:2f:53:8b:04:74:32:75:9d:bc:fd:b3:c9:a2:ba:
-                    6a:0d:94:6f:02:e5:c6:06:1a:5c:2a:d2:95:25:6e:
-                    53:86:88:d3:1c:11:db:b8:b8:9a:94:9a:89:65:c6:
-                    c5:6a:2e:b3:4f:07:80:40:d1:21:29:4c:52:84:e9:
-                    b4:a7:2d:f3:21:66:23:24:a7:b3:de:95:a3:79:4f:
-                    26:31:6c:b9:da:76:d6:ec:d4:7e:d1:44:b7:63:d3:
-                    8b:75:ff:04:a0:e2:96:57:5a:85:28:3b:0f:f3:12:
-                    0c:15:b9:7f:39:6a:9a:0b:95:ee:bc:d9:09:00:3e:
-                    b3:04:b5:7e:d8:af:42:6e:c5:cf:0f:d2:9b:71:aa:
-                    14:b6:cb:b0:9b:d6:5f:2c:97:24:c4:3f:27:e6:a7:
-                    47:5a:54:bf:84:68:ea:4f:e1:f0:1a:3b:7a:1b:85:
-                    d3:e9:8e:5f:b5:18:93:36:54:f1:15:e8:6f:52:c9:
-                    b7:5d:90:9d:d5:2f:fb:49:8c:b8:52:4e:34:bf:46:
-                    f4:8f:ee:76:1b:ca:9d:56:4d:f5:96:07:c3:76:60:
-                    66:3b:8c:e7:ef:fc:29:51:6d:0f:f0:f9:fb:db:44:
-                    e3:f5
+                    00:a8:d1:9d:45:4a:dd:38:b7:b6:76:e5:20:8e:f3:
+                    68:3a:98:11:33:6e:35:88:1a:ba:18:48:4c:c8:2e:
+                    72:dd:3d:84:5d:67:ba:99:23:90:14:99:de:7a:6b:
+                    6c:a7:c9:4f:81:72:d1:62:0a:cb:87:41:c3:c8:74:
+                    1e:56:b9:96:bf:ea:0c:c8:ff:a8:1b:17:97:74:6f:
+                    8c:ad:92:42:57:df:6b:e9:d0:4a:9a:0b:05:61:3d:
+                    50:ce:44:0f:22:41:83:10:f9:02:68:fe:94:c8:e4:
+                    5b:49:20:1c:02:2c:76:4e:82:0b:8f:f6:ae:53:c1:
+                    df:c0:48:22:78:1e:6f:03:75:00:26:b3:ad:c1:02:
+                    7f:83:cf:52:7c:6c:58:59:1e:1f:1e:a0:31:b5:38:
+                    91:4c:e4:2e:c9:71:e4:16:96:33:22:a9:cd:df:9a:
+                    b1:9e:84:29:93:b5:74:f6:5f:9c:8c:9a:3b:8f:11:
+                    a0:8d:82:68:ee:ba:2d:eb:b8:5d:62:f2:32:18:2c:
+                    84:94:d2:9f:65:e2:2c:eb:93:93:dd:6f:37:1e:ed:
+                    11:f8:50:ae:d6:e4:68:e3:20:2d:2b:11:cb:fc:37:
+                    cf:14:a7:cf:75:6d:03:44:99:b0:6d:ec:da:a4:fd:
+                    74:5e:d5:7c:58:42:59:22:bd:1e:53:09:00:0b:45:
+                    1e:87
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Subject Key Identifier: 
-                D9:D1:6E:42:D5:27:F3:97:CB:FD:15:37:54:E7:C9:A4:EA:F1:FB:D9
+                50:7F:07:06:90:38:D2:E8:2A:77:30:AD:87:F8:5B:26:E3:1D:97:47
             X509v3 Authority Key Identifier: 
-                keyid:40:91:28:21:9D:93:F3:9C:18:1B:FF:00:9C:B2:08:A0:A3:81:7D:2A
+                keyid:84:BA:05:06:4E:33:9D:11:AA:7A:F1:77:1F:A4:69:7E:4C:2D:D4:3F
 
             Authority Information Access: 
                 CA Issuers - URI:http://url-for-aia/I.cer
@@ -54,44 +54,46 @@
                 Digital Signature, Key Encipherment
             X509v3 Extended Key Usage: 
                 TLS Web Server Authentication, TLS Web Client Authentication
+            X509v3 Subject Alternative Name: 
+                DNS:target
     Signature Algorithm: sha256WithRSAEncryption
-         a4:55:b4:2e:7a:ab:a8:51:ce:14:7a:de:8f:6b:15:ae:ce:a1:
-         6f:ea:00:d8:9d:2f:55:55:42:a9:9c:f5:88:56:eb:b6:fa:be:
-         59:42:98:c7:c9:52:5c:52:1a:eb:a8:f7:29:48:fa:c9:66:41:
-         2b:77:24:9d:0b:d9:cf:c4:77:42:a1:44:58:64:a3:13:13:4f:
-         2f:c0:9b:e6:20:f5:35:bd:6d:d7:50:55:2d:30:e9:22:09:e1:
-         03:b9:8f:5f:77:66:14:d4:d7:26:3a:dc:bf:65:07:1e:8b:ee:
-         ca:d5:2a:3d:57:b9:8a:0f:df:27:9a:3e:d6:15:5f:ff:28:b1:
-         af:c6:35:1a:ba:b5:6c:ae:9e:3d:1e:38:2a:77:d7:d2:19:db:
-         a6:4d:5f:28:7e:19:80:d5:71:e5:11:0a:1e:db:46:f5:db:29:
-         4f:bb:d3:4d:3c:f2:6b:84:b1:87:6a:b5:56:b7:b0:76:61:a1:
-         2c:25:6d:6e:79:28:8a:40:fc:18:d9:a7:9c:4c:94:c5:28:75:
-         e9:2f:0d:12:35:d8:17:07:a4:aa:51:fe:b3:a0:57:e8:04:b2:
-         89:c0:c2:c3:85:4c:da:26:0a:f6:53:1a:be:f0:88:f1:a6:ff:
-         d7:85:1f:3d:02:ae:33:7b:b8:10:16:ce:4a:92:de:d5:e5:ef:
-         0c:72:47:3e
+         93:3c:98:46:dc:74:09:e3:f0:fd:dd:80:9d:b5:4d:4f:60:f2:
+         94:fc:4a:7c:f4:60:f6:70:50:0d:00:22:fa:d8:aa:46:88:de:
+         09:43:76:0f:2e:34:a1:d8:6c:a8:0e:7e:a4:09:cb:ae:12:b7:
+         dc:fa:31:1b:9c:ae:89:c1:36:77:13:f7:68:f8:13:f0:1d:b7:
+         b0:8a:6f:01:57:62:41:a1:9a:c9:4a:72:23:8a:37:2b:fc:02:
+         30:06:16:eb:73:56:30:e6:1b:a7:88:b1:59:24:5b:ee:8b:7d:
+         34:b9:12:ba:d8:dd:e1:44:e9:9b:45:b0:5c:75:47:f1:4c:99:
+         ed:98:d7:c3:a8:a9:7e:4e:5b:a1:9f:f2:bc:61:eb:a2:2b:8d:
+         ff:ab:a2:6b:37:88:2a:9f:09:83:eb:a9:48:1c:2f:88:ce:5c:
+         9f:5d:5d:4a:2f:74:ea:c5:2c:c7:e3:c9:b8:71:f0:80:e1:87:
+         f7:eb:cb:9c:23:8c:ad:1a:10:e7:00:6e:99:25:eb:2a:97:2f:
+         31:96:12:27:9e:e9:59:d8:6a:f5:87:e5:66:e3:61:eb:b6:f9:
+         30:27:13:f8:e3:87:27:06:e4:c8:fb:df:f9:49:20:7b:a5:9c:
+         90:2e:30:af:00:50:95:ea:95:1c:b4:90:49:df:b4:18:33:04:
+         8d:ec:c8:57
 -----BEGIN CERTIFICATE-----
-MIIEOTCCAyGgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAMMQowCAYDVQQDDAFJMB4X
+MIIETDCCAzSgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAMMQowCAYDVQQDDAFJMB4X
 DTE1MDEwMTEyMDAwMFoXDTIxMDEwMTEyMDAwMFowETEPMA0GA1UEAwwGdGFyZ2V0
-MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAslLulJCoGjK7T2QXpjGr
-CAmR7+ytCun7W/pqH+ZoL1OLBHQydZ28/bPJorpqDZRvAuXGBhpcKtKVJW5ThojT
-HBHbuLialJqJZcbFai6zTweAQNEhKUxShOm0py3zIWYjJKez3pWjeU8mMWy52nbW
-7NR+0US3Y9OLdf8EoOKWV1qFKDsP8xIMFbl/OWqaC5XuvNkJAD6zBLV+2K9CbsXP
-D9KbcaoUtsuwm9ZfLJckxD8n5qdHWlS/hGjqT+HwGjt6G4XT6Y5ftRiTNlTxFehv
-Usm3XZCd1S/7SYy4Uk40v0b0j+52G8qdVk31lgfDdmBmO4zn7/wpUW0P8Pn720Tj
-9QIDAQABo4IBnzCCAZswHQYDVR0OBBYEFNnRbkLVJ/OXy/0VN1TnyaTq8fvZMB8G
-A1UdIwQYMBaAFECRKCGdk/OcGBv/AJyyCKCjgX0qMIH+BggrBgEFBQcBAQSB8TCB
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqNGdRUrdOLe2duUgjvNo
+OpgRM241iBq6GEhMyC5y3T2EXWe6mSOQFJneemtsp8lPgXLRYgrLh0HDyHQeVrmW
+v+oMyP+oGxeXdG+MrZJCV99r6dBKmgsFYT1QzkQPIkGDEPkCaP6UyORbSSAcAix2
+ToILj/auU8HfwEgieB5vA3UAJrOtwQJ/g89SfGxYWR4fHqAxtTiRTOQuyXHkFpYz
+IqnN35qxnoQpk7V09l+cjJo7jxGgjYJo7rot67hdYvIyGCyElNKfZeIs65OT3W83
+Hu0R+FCu1uRo4yAtKxHL/DfPFKfPdW0DRJmwbezapP10XtV8WEJZIr0eUwkAC0Ue
+hwIDAQABo4IBsjCCAa4wHQYDVR0OBBYEFFB/BwaQONLoKncwrYf4WybjHZdHMB8G
+A1UdIwQYMBaAFIS6BQZOM50Rqnrxdx+kaX5MLdQ/MIH+BggrBgEFBQcBAQSB8TCB
 7jAkBggrBgEFBQcwAoYYaHR0cDovL3VybC1mb3ItYWlhL0kuY2VyMCYGCCsGAQUF
 BzAChhpodHRwOi8vdXJsLWZvci1haWEyL0kyLmZvbzAmBggrBgEFBQcwAoYaaHR0
 cDovL3VybC1mb3ItYWlhMy9JMy5mb28wJgYIKwYBBQUHMAKGGmh0dHA6Ly91cmwt
 Zm9yLWFpYTQvSTQuZm9vMCYGCCsGAQUFBzAChhpodHRwOi8vdXJsLWZvci1haWE1
 L0k1LmZvbzAmBggrBgEFBQcwAoYaaHR0cDovL3VybC1mb3ItYWlhNi9JNi5mb28w
 KQYDVR0fBCIwIDAeoBygGoYYaHR0cDovL3VybC1mb3ItY3JsL0kuY3JsMA4GA1Ud
-DwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDQYJKoZI
-hvcNAQELBQADggEBAKRVtC56q6hRzhR63o9rFa7OoW/qANidL1VVQqmc9YhW67b6
-vllCmMfJUlxSGuuo9ylI+slmQSt3JJ0L2c/Ed0KhRFhkoxMTTy/Am+Yg9TW9bddQ
-VS0w6SIJ4QO5j193ZhTU1yY63L9lBx6L7srVKj1XuYoP3yeaPtYVX/8osa/GNRq6
-tWyunj0eOCp319IZ26ZNXyh+GYDVceURCh7bRvXbKU+700088muEsYdqtVa3sHZh
-oSwlbW55KIpA/BjZp5xMlMUodekvDRI12BcHpKpR/rOgV+gEsonAwsOFTNomCvZT
-Gr7wiPGm/9eFHz0CrjN7uBAWzkqS3tXl7wxyRz4=
+DwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwEQYDVR0R
+BAowCIIGdGFyZ2V0MA0GCSqGSIb3DQEBCwUAA4IBAQCTPJhG3HQJ4/D93YCdtU1P
+YPKU/Ep89GD2cFANACL62KpGiN4JQ3YPLjSh2GyoDn6kCcuuErfc+jEbnK6JwTZ3
+E/do+BPwHbewim8BV2JBoZrJSnIjijcr/AIwBhbrc1Yw5huniLFZJFvui300uRK6
+2N3hROmbRbBcdUfxTJntmNfDqKl+Tluhn/K8YeuiK43/q6JrN4gqnwmD66lIHC+I
+zlyfXV1KL3TqxSzH48m4cfCA4Yf368ucI4ytGhDnAG6ZJesqly8xlhInnulZ2Gr1
+h+Vm42HrtvkwJxP444cnBuTI+9/5SSB7pZyQLjCvAFCV6pUctJBJ37QYMwSN7MhX
 -----END CERTIFICATE-----
diff --git a/net/data/cert_issuer_source_aia_unittest/target_three_aia.pem b/net/data/cert_issuer_source_aia_unittest/target_three_aia.pem
index 18699cf..5f24ab3 100644
--- a/net/data/cert_issuer_source_aia_unittest/target_three_aia.pem
+++ b/net/data/cert_issuer_source_aia_unittest/target_three_aia.pem
@@ -12,30 +12,30 @@
             Public Key Algorithm: rsaEncryption
                 Public-Key: (2048 bit)
                 Modulus:
-                    00:ce:0f:06:90:e0:8b:9f:3b:85:b8:f4:fc:73:6c:
-                    5c:8a:8d:b9:1d:cf:03:37:36:ec:c6:da:e6:c3:7b:
-                    ff:59:8b:3b:c7:ef:9d:e4:6f:52:08:c9:89:cb:f6:
-                    a1:98:70:c5:72:a0:49:a8:92:7b:a4:fe:7f:4e:e7:
-                    04:dd:14:5c:64:ed:bd:6e:e0:6b:8a:dd:ff:ac:37:
-                    ba:6d:24:44:0b:0a:51:34:ae:51:a2:3c:50:90:e5:
-                    8e:26:22:f0:93:c0:ae:65:de:a4:cb:58:50:4c:01:
-                    ee:eb:64:d0:31:5c:7c:3a:d5:74:d5:59:b7:5d:bb:
-                    7a:bf:93:46:a8:fd:66:ad:81:5d:af:69:2c:f3:42:
-                    d4:7b:76:9c:12:8b:90:c8:52:38:d8:d5:74:b7:65:
-                    c2:ae:cf:d4:78:78:19:e6:ce:2c:dc:2b:c5:2f:96:
-                    a4:72:18:21:86:2e:77:65:10:a8:47:8b:e0:2a:01:
-                    e4:d2:62:df:61:71:06:04:e3:1e:76:3f:55:a1:79:
-                    d6:11:ed:24:79:3b:f3:13:08:99:d8:88:4f:25:39:
-                    d9:1b:d1:2a:e7:93:a4:ba:01:eb:f1:fc:a4:c8:c3:
-                    8b:d9:91:2d:64:48:5c:9a:1e:d1:35:f9:a0:67:7d:
-                    21:8a:1a:a0:58:75:a4:31:17:73:1a:c0:e3:1c:a5:
-                    b3:19
+                    00:ab:6d:a7:ab:5c:a3:04:f8:18:44:5a:e6:16:3b:
+                    37:be:ec:13:da:6e:5c:55:4e:19:e9:14:d9:f5:0e:
+                    2e:56:bb:52:bb:58:f0:f7:89:e8:a8:85:47:02:f7:
+                    51:1c:b8:29:ce:1b:2c:0a:4e:de:8e:c5:d9:a1:aa:
+                    0f:a3:fd:51:61:fb:7f:e4:e9:05:49:b2:58:6d:10:
+                    fe:11:60:13:24:98:69:17:d1:56:60:93:da:6b:26:
+                    8b:d7:c3:dc:e5:4f:c0:d1:cd:e5:80:21:3c:68:b0:
+                    2e:fc:bf:06:9e:2e:0d:26:bf:12:f3:4a:f0:98:9d:
+                    d8:b0:24:3b:27:46:bf:ca:45:29:96:71:00:48:83:
+                    08:29:22:68:a8:2d:ba:90:38:4b:50:d9:ab:5f:f2:
+                    89:08:ee:43:ac:e0:ca:2b:2a:45:70:08:23:3b:be:
+                    fe:6f:1d:81:a6:6b:df:19:31:d2:a2:58:b2:87:8c:
+                    83:ff:ff:5d:47:4d:50:a7:07:3a:b7:1e:f0:b0:6d:
+                    57:5b:d0:45:06:a5:0e:97:fd:ff:d5:62:71:9f:0d:
+                    bb:35:f0:b8:d1:92:09:42:c9:dd:64:c8:17:8f:3f:
+                    b3:36:dd:ea:5c:58:8e:d6:a4:ed:c1:8e:9f:01:1e:
+                    fd:15:a4:45:97:b8:56:db:85:84:a5:33:82:c1:da:
+                    82:15
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Subject Key Identifier: 
-                1B:54:9F:9B:A8:BB:5F:37:19:D9:66:AE:B3:0A:65:58:04:81:29:8D
+                13:C9:D0:AB:5F:EF:0C:5E:23:88:F5:C4:44:2C:0A:3F:3B:13:21:C2
             X509v3 Authority Key Identifier: 
-                keyid:40:91:28:21:9D:93:F3:9C:18:1B:FF:00:9C:B2:08:A0:A3:81:7D:2A
+                keyid:84:BA:05:06:4E:33:9D:11:AA:7A:F1:77:1F:A4:69:7E:4C:2D:D4:3F
 
             Authority Information Access: 
                 CA Issuers - URI:http://url-for-aia/I.cer
@@ -51,42 +51,44 @@
                 Digital Signature, Key Encipherment
             X509v3 Extended Key Usage: 
                 TLS Web Server Authentication, TLS Web Client Authentication
+            X509v3 Subject Alternative Name: 
+                DNS:target
     Signature Algorithm: sha256WithRSAEncryption
-         01:98:3b:ee:4c:4e:91:e7:97:bf:1d:18:2b:bd:f4:a5:ba:75:
-         fd:f1:9f:73:0e:25:dc:4d:7b:e8:69:0a:22:55:4f:96:30:64:
-         e5:05:73:ef:ef:ef:5a:50:48:50:a8:e5:e5:c6:a3:3b:0e:e8:
-         48:b7:6f:0d:d4:ae:5e:2a:15:e5:86:45:02:83:f8:1a:b0:2d:
-         0f:19:df:ed:dd:5d:fb:e4:31:b7:18:5e:de:8a:62:cd:53:77:
-         b0:cf:1c:a0:9a:fc:20:94:6f:37:2a:3b:af:36:65:e1:98:c4:
-         e1:f6:b4:fc:d7:08:c5:6d:90:ba:67:2c:06:ff:1c:62:af:99:
-         f2:f6:40:41:30:6c:4a:66:fb:ae:5f:2b:0e:33:f4:9a:34:62:
-         4d:ca:a1:b9:da:f9:14:7a:ff:87:c7:89:d5:c0:da:1d:6d:5e:
-         7f:81:84:77:53:cb:24:d9:dc:25:51:51:7a:85:c3:9c:22:9f:
-         b9:4f:17:cf:80:b7:21:7c:6d:6d:15:dd:11:23:66:f7:58:77:
-         32:c3:88:2b:6c:e3:db:d7:c8:cb:a8:52:02:f6:85:3f:00:22:
-         5e:33:3f:d6:5b:fc:7d:41:3c:de:0d:6e:c4:83:a8:32:e5:29:
-         40:d7:c4:0f:50:22:9f:5b:55:d8:4f:0c:93:08:cb:c5:b7:fc:
-         b0:f1:24:14
+         11:88:ca:4b:ea:92:84:28:28:21:ff:a6:22:d3:c3:ab:d0:cd:
+         b1:6d:bc:db:4c:0a:80:d0:f9:f0:36:6b:41:9d:1e:fc:75:5a:
+         61:56:66:62:93:9f:ba:77:f5:e1:aa:0d:72:14:ea:07:3b:2d:
+         bd:7d:18:f5:b5:82:e6:28:79:b1:c0:c9:41:26:24:58:fd:73:
+         4e:6a:ec:b2:b0:52:59:c5:7f:a4:9b:26:2a:5a:43:b2:cb:d4:
+         0f:ea:ce:7b:da:e9:f7:0c:10:1b:02:ac:62:4b:03:56:3f:a7:
+         29:d1:93:89:45:2f:24:d0:52:54:a6:56:5a:76:e3:06:b1:12:
+         49:78:cd:a9:30:a0:9c:48:18:35:7f:28:5d:e9:00:8f:f7:69:
+         1a:93:aa:1c:1a:bf:2a:79:68:11:1b:c1:fb:7f:bf:8b:2b:df:
+         09:32:69:d5:19:32:bf:ce:12:09:7b:39:57:75:c7:15:9f:b3:
+         f4:f6:f2:3c:c0:bd:99:c3:57:ab:55:db:55:01:cd:73:f9:52:
+         4c:ae:15:86:24:ad:85:57:a8:a5:2c:80:9a:7a:ed:f6:e8:20:
+         18:34:8f:bf:b9:00:3d:8e:0c:4b:dc:59:3d:86:62:dc:09:f2:
+         03:cd:c0:8c:cd:b9:1d:17:88:ea:44:2c:52:40:89:19:0f:d4:
+         a7:15:ae:67
 -----BEGIN CERTIFICATE-----
-MIIDvzCCAqegAwIBAgIBBDANBgkqhkiG9w0BAQsFADAMMQowCAYDVQQDDAFJMB4X
+MIID0jCCArqgAwIBAgIBBDANBgkqhkiG9w0BAQsFADAMMQowCAYDVQQDDAFJMB4X
 DTE1MDEwMTEyMDAwMFoXDTIxMDEwMTEyMDAwMFowETEPMA0GA1UEAwwGdGFyZ2V0
-MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzg8GkOCLnzuFuPT8c2xc
-io25Hc8DNzbsxtrmw3v/WYs7x++d5G9SCMmJy/ahmHDFcqBJqJJ7pP5/TucE3RRc
-ZO29buBrit3/rDe6bSRECwpRNK5RojxQkOWOJiLwk8CuZd6ky1hQTAHu62TQMVx8
-OtV01Vm3Xbt6v5NGqP1mrYFdr2ks80LUe3acEouQyFI42NV0t2XCrs/UeHgZ5s4s
-3CvFL5akchghhi53ZRCoR4vgKgHk0mLfYXEGBOMedj9VoXnWEe0keTvzEwiZ2IhP
-JTnZG9Eq55OkugHr8fykyMOL2ZEtZEhcmh7RNfmgZ30hihqgWHWkMRdzGsDjHKWz
-GQIDAQABo4IBJTCCASEwHQYDVR0OBBYEFBtUn5uou183GdlmrrMKZVgEgSmNMB8G
-A1UdIwQYMBaAFECRKCGdk/OcGBv/AJyyCKCjgX0qMIGEBggrBgEFBQcBAQR4MHYw
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAq22nq1yjBPgYRFrmFjs3
+vuwT2m5cVU4Z6RTZ9Q4uVrtSu1jw94noqIVHAvdRHLgpzhssCk7ejsXZoaoPo/1R
+Yft/5OkFSbJYbRD+EWATJJhpF9FWYJPaayaL18Pc5U/A0c3lgCE8aLAu/L8Gni4N
+Jr8S80rwmJ3YsCQ7J0a/ykUplnEASIMIKSJoqC26kDhLUNmrX/KJCO5DrODKKypF
+cAgjO77+bx2BpmvfGTHSoliyh4yD//9dR01Qpwc6tx7wsG1XW9BFBqUOl/3/1WJx
+nw27NfC40ZIJQsndZMgXjz+zNt3qXFiO1qTtwY6fAR79FaRFl7hW24WEpTOCwdqC
+FQIDAQABo4IBODCCATQwHQYDVR0OBBYEFBPJ0Ktf7wxeI4j1xEQsCj87EyHCMB8G
+A1UdIwQYMBaAFIS6BQZOM50Rqnrxdx+kaX5MLdQ/MIGEBggrBgEFBQcBAQR4MHYw
 JAYIKwYBBQUHMAKGGGh0dHA6Ly91cmwtZm9yLWFpYS9JLmNlcjAmBggrBgEFBQcw
 AoYaaHR0cDovL3VybC1mb3ItYWlhMi9JMi5mb28wJgYIKwYBBQUHMAKGGmh0dHA6
 Ly91cmwtZm9yLWFpYTMvSTMuZm9vMCkGA1UdHwQiMCAwHqAcoBqGGGh0dHA6Ly91
 cmwtZm9yLWNybC9JLmNybDAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYB
-BQUHAwEGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQABmDvuTE6R55e/HRgr
-vfSlunX98Z9zDiXcTXvoaQoiVU+WMGTlBXPv7+9aUEhQqOXlxqM7DuhIt28N1K5e
-KhXlhkUCg/gasC0PGd/t3V375DG3GF7eimLNU3ewzxygmvwglG83KjuvNmXhmMTh
-9rT81wjFbZC6ZywG/xxir5ny9kBBMGxKZvuuXysOM/SaNGJNyqG52vkUev+Hx4nV
-wNodbV5/gYR3U8sk2dwlUVF6hcOcIp+5TxfPgLchfG1tFd0RI2b3WHcyw4grbOPb
-18jLqFIC9oU/ACJeMz/WW/x9QTzeDW7Eg6gy5SlA18QPUCKfW1XYTwyTCMvFt/yw
-8SQU
+BQUHAwEGCCsGAQUFBwMCMBEGA1UdEQQKMAiCBnRhcmdldDANBgkqhkiG9w0BAQsF
+AAOCAQEAEYjKS+qShCgoIf+mItPDq9DNsW2820wKgND58DZrQZ0e/HVaYVZmYpOf
+unf14aoNchTqBzstvX0Y9bWC5ih5scDJQSYkWP1zTmrssrBSWcV/pJsmKlpDssvU
+D+rOe9rp9wwQGwKsYksDVj+nKdGTiUUvJNBSVKZWWnbjBrESSXjNqTCgnEgYNX8o
+XekAj/dpGpOqHBq/KnloERvB+3+/iyvfCTJp1Rkyv84SCXs5V3XHFZ+z9PbyPMC9
+mcNXq1XbVQHNc/lSTK4VhiSthVeopSyAmnrt9uggGDSPv7kAPY4MS9xZPYZi3Any
+A83AjM25HReI6kQsUkCJGQ/UpxWuZw==
 -----END CERTIFICATE-----
diff --git a/net/data/cert_issuer_source_aia_unittest/target_two_aia.pem b/net/data/cert_issuer_source_aia_unittest/target_two_aia.pem
index f7de319..c530ecb2 100644
--- a/net/data/cert_issuer_source_aia_unittest/target_two_aia.pem
+++ b/net/data/cert_issuer_source_aia_unittest/target_two_aia.pem
@@ -12,30 +12,30 @@
             Public Key Algorithm: rsaEncryption
                 Public-Key: (2048 bit)
                 Modulus:
-                    00:ab:cb:9a:c2:db:b8:1c:3d:1a:b7:37:e8:97:9c:
-                    51:f4:8a:61:67:1d:37:8a:88:fe:8a:65:24:54:51:
-                    18:be:9c:13:83:0c:91:0b:52:32:c6:6d:4c:8a:48:
-                    10:06:83:da:81:db:10:2a:77:81:16:d0:85:cd:04:
-                    ce:06:56:3d:53:29:e3:11:6d:25:d9:bd:81:df:50:
-                    bb:42:0c:c4:6a:3b:6c:5c:e5:47:54:25:8b:21:cb:
-                    22:00:8e:31:75:c0:21:29:89:e7:76:5a:2c:97:56:
-                    87:29:ab:35:16:23:41:0d:25:d0:62:7d:91:0e:02:
-                    9c:9a:7b:a3:fa:b6:d9:16:75:36:ea:62:cc:61:ab:
-                    ae:15:9d:71:ff:5a:90:af:b4:a0:b2:d2:99:3b:2d:
-                    92:45:64:44:fd:07:d8:86:c7:47:bf:d4:b5:35:07:
-                    46:a7:93:4f:e9:2b:71:9e:a4:76:78:42:b7:17:1e:
-                    2b:0e:b1:f2:f5:1a:99:d5:ce:d2:9d:f6:99:0a:20:
-                    03:19:4e:f9:e0:45:68:75:e6:08:63:95:f5:34:21:
-                    78:d6:68:06:b4:c8:cb:e3:77:6c:61:ef:c3:12:e8:
-                    71:87:e2:99:2e:5a:2f:b8:d9:d8:51:aa:af:20:47:
-                    c8:cd:eb:73:11:8e:a2:4b:fa:4e:8c:3c:d2:5e:1d:
-                    17:5f
+                    00:c8:62:eb:23:95:cd:33:c8:5e:43:58:e3:1e:90:
+                    82:8d:44:eb:dc:64:d2:cd:fb:09:c2:69:56:11:0f:
+                    d7:8f:cd:20:d7:bc:e3:ae:e9:62:e4:67:3a:d1:31:
+                    14:45:5b:36:e1:33:00:81:2f:f0:c5:ea:1f:57:ff:
+                    fb:99:43:5b:9f:09:01:83:e0:07:f1:00:42:23:9b:
+                    ef:b2:c2:5d:0f:0e:59:2d:ef:e4:20:e7:fd:f1:96:
+                    9a:5e:71:7d:db:dd:36:a8:1d:7b:04:bd:74:d9:e5:
+                    86:d2:34:6e:af:8e:77:8e:35:af:2b:4d:8e:e4:93:
+                    01:23:a3:27:cd:a5:ce:e0:bd:53:f2:1b:e6:f1:e9:
+                    d2:fb:20:49:01:81:f7:2f:51:5c:d7:63:35:42:de:
+                    52:f7:bc:1c:1d:6d:af:01:3a:5f:20:59:ee:5d:d6:
+                    77:1d:cb:d7:ef:14:9e:e1:9f:01:97:7b:bc:a3:d1:
+                    d1:05:6c:64:6c:7d:5a:26:38:b2:5f:f0:a5:3b:f4:
+                    b2:3d:8a:85:f0:25:2d:31:1b:b3:a3:4c:a7:95:2f:
+                    ea:bc:6a:4a:9e:61:19:81:4b:b8:8e:a5:88:3b:36:
+                    35:e8:e2:35:76:17:29:d8:4e:1a:4c:6d:7c:1d:b2:
+                    e9:79:5b:f5:75:76:78:55:2f:e1:03:2f:94:d6:aa:
+                    9e:ff
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Subject Key Identifier: 
-                E8:D5:6F:99:50:16:68:CA:BF:06:34:2A:8B:0A:E2:25:88:40:CF:15
+                E5:73:F2:21:4B:9E:B8:BB:3C:57:17:0F:F8:0E:E1:6A:FC:F3:2A:48
             X509v3 Authority Key Identifier: 
-                keyid:40:91:28:21:9D:93:F3:9C:18:1B:FF:00:9C:B2:08:A0:A3:81:7D:2A
+                keyid:84:BA:05:06:4E:33:9D:11:AA:7A:F1:77:1F:A4:69:7E:4C:2D:D4:3F
 
             Authority Information Access: 
                 CA Issuers - URI:http://url-for-aia/I.cer
@@ -50,41 +50,43 @@
                 Digital Signature, Key Encipherment
             X509v3 Extended Key Usage: 
                 TLS Web Server Authentication, TLS Web Client Authentication
+            X509v3 Subject Alternative Name: 
+                DNS:target
     Signature Algorithm: sha256WithRSAEncryption
-         64:0c:e5:4b:4a:6f:ec:3f:49:37:89:ce:54:6b:72:8a:a9:f1:
-         db:1a:c3:d7:84:9f:d5:29:73:12:ba:a3:03:99:5d:45:b5:62:
-         f6:7e:83:74:f9:ff:d8:49:15:76:7d:65:eb:ad:11:bd:b2:b5:
-         77:15:d3:c2:5f:ad:ca:c2:24:e4:92:8b:5d:10:65:07:6e:99:
-         4e:e5:16:f0:8a:62:ba:91:50:bd:a2:1b:12:c9:d8:a1:c0:49:
-         a1:3a:5d:3c:75:87:4e:07:0d:ce:6f:27:90:94:3d:10:cd:aa:
-         b0:6d:37:ac:97:3a:af:45:f3:86:94:b3:d8:ae:d4:49:27:d6:
-         e2:7e:d7:e1:54:1f:e8:85:86:cd:02:d1:83:ae:c4:2a:63:6b:
-         33:87:ad:70:3b:81:87:a8:2c:30:d1:28:04:cc:a3:5c:75:d0:
-         08:86:67:99:10:5f:be:94:5d:4f:ed:d7:2e:eb:bf:85:61:a1:
-         58:be:8a:61:08:a8:43:38:32:b7:33:09:09:03:61:4d:4d:55:
-         dc:e2:1b:f4:be:3d:d0:76:b0:00:df:72:48:57:f9:1c:3e:bd:
-         83:7a:47:fd:09:53:16:f7:00:32:8f:94:16:0a:ef:19:26:4d:
-         b0:b8:6c:02:f8:51:5e:27:6a:c5:1e:62:c2:5b:5e:c2:a1:d4:
-         82:56:90:fe
+         40:67:ce:6d:fa:82:c3:f7:43:ff:8b:04:2e:c8:57:fa:0c:32:
+         16:7c:f4:6a:90:a5:bd:31:ba:2f:a6:d6:6a:fe:a9:c5:a2:03:
+         2b:87:33:c6:1d:0d:2f:10:aa:15:68:62:a3:5d:bd:d4:3e:2e:
+         21:eb:02:36:88:37:6a:47:6a:61:b4:20:db:ba:12:24:3e:5a:
+         65:84:39:b6:07:9b:69:30:04:a3:44:ee:f1:8f:2a:55:fb:fd:
+         bd:bd:76:f2:0f:a8:20:c3:2c:4a:31:94:59:00:2b:d0:ff:a9:
+         98:7a:ae:9d:e6:f3:38:6f:7a:8d:f7:e0:b5:c4:75:8c:5e:6c:
+         92:47:d4:d2:e0:78:c6:c1:56:f2:10:d3:c0:9f:86:b3:7b:ef:
+         0b:20:07:a5:ab:d7:35:ce:d5:48:d6:67:f6:f3:57:72:e6:e5:
+         e7:81:04:61:dc:a2:f9:47:2b:3f:08:c4:55:41:38:9a:0c:7f:
+         d2:5f:05:ff:4d:34:8c:4b:4c:6a:6e:73:d2:c2:c3:d3:1c:b0:
+         08:6e:17:bb:94:e6:65:6e:da:7e:3f:9c:42:2d:cb:d8:2a:7b:
+         c9:03:6f:15:e2:6d:63:e6:5e:a7:fb:7c:5e:b3:fe:6a:87:9b:
+         de:04:91:f6:bb:50:ad:9e:1c:0c:3f:bf:c5:06:99:f0:3f:ad:
+         1d:37:26:f5
 -----BEGIN CERTIFICATE-----
-MIIDlDCCAnygAwIBAgIBAzANBgkqhkiG9w0BAQsFADAMMQowCAYDVQQDDAFJMB4X
+MIIDqTCCApGgAwIBAgIBAzANBgkqhkiG9w0BAQsFADAMMQowCAYDVQQDDAFJMB4X
 DTE1MDEwMTEyMDAwMFoXDTIxMDEwMTEyMDAwMFowETEPMA0GA1UEAwwGdGFyZ2V0
-MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAq8uawtu4HD0atzfol5xR
-9IphZx03ioj+imUkVFEYvpwTgwyRC1Iyxm1MikgQBoPagdsQKneBFtCFzQTOBlY9
-UynjEW0l2b2B31C7QgzEajtsXOVHVCWLIcsiAI4xdcAhKYnndlosl1aHKas1FiNB
-DSXQYn2RDgKcmnuj+rbZFnU26mLMYauuFZ1x/1qQr7SgstKZOy2SRWRE/QfYhsdH
-v9S1NQdGp5NP6StxnqR2eEK3Fx4rDrHy9RqZ1c7SnfaZCiADGU754EVodeYIY5X1
-NCF41mgGtMjL43dsYe/DEuhxh+KZLlovuNnYUaqvIEfIzetzEY6iS/pOjDzSXh0X
-XwIDAQABo4H7MIH4MB0GA1UdDgQWBBTo1W+ZUBZoyr8GNCqLCuIliEDPFTAfBgNV
-HSMEGDAWgBRAkSghnZPznBgb/wCcsgigo4F9KjBcBggrBgEFBQcBAQRQME4wJAYI
-KwYBBQUHMAKGGGh0dHA6Ly91cmwtZm9yLWFpYS9JLmNlcjAmBggrBgEFBQcwAoYa
-aHR0cDovL3VybC1mb3ItYWlhMi9JMi5mb28wKQYDVR0fBCIwIDAeoBygGoYYaHR0
-cDovL3VybC1mb3ItY3JsL0kuY3JsMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAU
-BggrBgEFBQcDAQYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAGQM5UtKb+w/
-STeJzlRrcoqp8dsaw9eEn9UpcxK6owOZXUW1YvZ+g3T5/9hJFXZ9ZeutEb2ytXcV
-08JfrcrCJOSSi10QZQdumU7lFvCKYrqRUL2iGxLJ2KHASaE6XTx1h04HDc5vJ5CU
-PRDNqrBtN6yXOq9F84aUs9iu1Ekn1uJ+1+FUH+iFhs0C0YOuxCpjazOHrXA7gYeo
-LDDRKATMo1x10AiGZ5kQX76UXU/t1y7rv4VhoVi+imEIqEM4MrczCQkDYU1NVdzi
-G/S+PdB2sADfckhX+Rw+vYN6R/0JUxb3ADKPlBYK7xkmTbC4bAL4UV4nasUeYsJb
-XsKh1IJWkP4=
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyGLrI5XNM8heQ1jjHpCC
+jUTr3GTSzfsJwmlWEQ/Xj80g17zjruli5Gc60TEURVs24TMAgS/wxeofV//7mUNb
+nwkBg+AH8QBCI5vvssJdDw5ZLe/kIOf98ZaaXnF92902qB17BL102eWG0jRur453
+jjWvK02O5JMBI6MnzaXO4L1T8hvm8enS+yBJAYH3L1Fc12M1Qt5S97wcHW2vATpf
+IFnuXdZ3HcvX7xSe4Z8Bl3u8o9HRBWxkbH1aJjiyX/ClO/SyPYqF8CUtMRuzo0yn
+lS/qvGpKnmEZgUu4jqWIOzY16OI1dhcp2E4aTG18HbLpeVv1dXZ4VS/hAy+U1qqe
+/wIDAQABo4IBDzCCAQswHQYDVR0OBBYEFOVz8iFLnri7PFcXD/gO4Wr88ypIMB8G
+A1UdIwQYMBaAFIS6BQZOM50Rqnrxdx+kaX5MLdQ/MFwGCCsGAQUFBwEBBFAwTjAk
+BggrBgEFBQcwAoYYaHR0cDovL3VybC1mb3ItYWlhL0kuY2VyMCYGCCsGAQUFBzAC
+hhpodHRwOi8vdXJsLWZvci1haWEyL0kyLmZvbzApBgNVHR8EIjAgMB6gHKAahhho
+dHRwOi8vdXJsLWZvci1jcmwvSS5jcmwwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQW
+MBQGCCsGAQUFBwMBBggrBgEFBQcDAjARBgNVHREECjAIggZ0YXJnZXQwDQYJKoZI
+hvcNAQELBQADggEBAEBnzm36gsP3Q/+LBC7IV/oMMhZ89GqQpb0xui+m1mr+qcWi
+AyuHM8YdDS8QqhVoYqNdvdQ+LiHrAjaIN2pHamG0INu6EiQ+WmWEObYHm2kwBKNE
+7vGPKlX7/b29dvIPqCDDLEoxlFkAK9D/qZh6rp3m8zhveo334LXEdYxebJJH1NLg
+eMbBVvIQ08CfhrN77wsgB6Wr1zXO1UjWZ/bzV3Lm5eeBBGHcovlHKz8IxFVBOJoM
+f9JfBf9NNIxLTGpuc9LCw9McsAhuF7uU5mVu2n4/nEIty9gqe8kDbxXibWPmXqf7
+fF6z/mqHm94Ekfa7UK2eHAw/v8UGmfA/rR03JvU=
 -----END CERTIFICATE-----
diff --git a/net/data/ssl/certificates/aia-cert.pem b/net/data/ssl/certificates/aia-cert.pem
index ab1d33c..e3da938 100644
--- a/net/data/ssl/certificates/aia-cert.pem
+++ b/net/data/ssl/certificates/aia-cert.pem
@@ -5,31 +5,31 @@
     Signature Algorithm: sha256WithRSAEncryption
         Issuer: CN=AIA Test Intermediate CA
         Validity
-            Not Before: Aug 14 02:46:18 2014 GMT
-            Not After : Aug 11 02:46:18 2024 GMT
+            Not Before: Feb 28 23:02:39 2017 GMT
+            Not After : Feb 26 23:02:39 2027 GMT
         Subject: CN=aia-host.invalid
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
                 Public-Key: (2048 bit)
                 Modulus:
-                    00:d7:a8:22:68:e9:32:12:5a:49:cb:cb:47:df:93:
-                    34:0d:2e:0e:a0:e8:30:27:a7:69:47:cc:f4:fe:76:
-                    ad:13:95:d2:dc:39:05:ad:62:f7:8f:23:d6:04:1c:
-                    a3:84:30:a0:0f:37:7d:fa:28:d4:f3:4b:e4:0c:ce:
-                    c0:57:96:c4:40:3d:20:20:b0:78:19:1b:a9:7a:ad:
-                    20:4e:a6:39:42:39:48:f5:18:a4:05:03:1a:9e:f5:
-                    cf:54:e2:3e:5d:38:c7:5d:f8:89:d4:5d:39:f0:15:
-                    db:96:26:bb:12:fe:a4:c5:b0:ff:6d:41:f7:f8:25:
-                    81:6d:99:03:93:20:7d:29:25:bd:15:a9:ea:2d:98:
-                    03:5b:54:88:33:a9:e3:88:1a:de:14:42:f4:42:56:
-                    5c:67:9d:3a:9a:69:2c:d2:17:e5:75:ac:28:73:44:
-                    48:22:08:6b:3f:5a:82:4b:76:8a:59:3b:f9:55:51:
-                    b2:02:94:f2:68:12:13:6a:58:cb:c8:2a:01:15:4d:
-                    ed:f5:0f:03:61:4c:c2:94:bf:37:bf:d0:62:ad:51:
-                    2e:5a:eb:8a:e1:db:68:d7:96:14:7b:09:dd:75:12:
-                    5f:fe:72:40:3b:a0:ae:c2:0b:9d:ae:79:13:81:e1:
-                    cb:47:83:cd:ea:07:a6:00:41:a2:b4:08:16:fb:17:
-                    73:dd
+                    00:e2:a9:b9:44:17:83:cf:57:d4:22:86:54:52:d3:
+                    42:7d:03:84:9a:f9:3f:05:16:73:ad:4e:55:d1:d0:
+                    ad:f3:cf:fd:1a:80:38:73:50:b7:fa:13:c8:c6:69:
+                    38:4c:9c:4a:fb:c6:a0:a2:44:f3:7e:66:76:ec:dd:
+                    ef:e9:5d:2a:16:8b:b5:65:e3:78:e7:b7:e5:d1:88:
+                    c8:d8:e0:3a:8f:1c:bb:8c:b3:8d:8e:52:9f:bc:15:
+                    9f:92:12:8e:d5:56:84:dc:c1:f8:b8:58:d5:e9:be:
+                    72:2b:ad:aa:d4:63:b6:69:da:e0:4d:58:af:8a:3a:
+                    f7:85:2f:62:2b:24:c2:49:6f:1c:65:55:8c:92:bb:
+                    c1:23:47:38:9d:51:17:14:92:86:b7:9e:d0:07:1b:
+                    14:38:36:2c:ca:e6:77:b8:03:ec:53:04:44:29:d5:
+                    ae:91:41:52:48:5d:90:50:b0:63:32:97:f5:62:1a:
+                    08:11:96:2a:b4:97:66:1b:b4:56:b5:7e:c2:a9:5b:
+                    89:d8:fe:de:44:7c:ff:61:6e:f3:02:9f:88:30:eb:
+                    4b:80:14:48:84:33:ff:e4:28:c0:e3:5a:6a:55:dd:
+                    48:75:b2:61:e6:e9:f5:3d:3a:55:45:b4:93:4e:e0:
+                    03:c9:a1:de:8c:eb:30:8a:d3:8f:e7:1f:4a:a9:72:
+                    c2:bf
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Basic Constraints: critical
@@ -39,38 +39,41 @@
             Authority Information Access: 
                 CA Issuers - URI:http://aia-test.invalid
 
+            X509v3 Subject Alternative Name: 
+                DNS:aia-host.invalid
     Signature Algorithm: sha256WithRSAEncryption
-         c2:4f:77:17:5a:0b:78:99:c2:79:06:00:2a:6d:8a:f6:81:a9:
-         85:c4:99:dd:fc:b8:0e:77:20:14:13:bd:7e:f5:f7:79:87:f2:
-         e6:95:f8:68:4c:59:5c:46:9b:d8:f9:08:ee:ae:9d:11:f2:d6:
-         cc:1d:0a:d8:7c:16:fa:36:87:aa:6c:89:74:f0:66:16:9e:99:
-         ca:83:8a:ff:0d:20:3a:bd:05:38:52:98:f0:b6:74:3f:a8:6e:
-         48:02:86:7d:39:ee:7e:34:db:5c:38:1e:88:90:78:55:08:4c:
-         23:5e:e7:3d:e8:2f:66:b3:f1:30:ce:18:94:65:7c:62:08:50:
-         2f:29:db:aa:3c:f0:3a:a9:b3:ee:ee:19:cc:f7:0a:23:ba:0a:
-         51:f3:c5:af:6d:cc:8c:5f:77:d2:d2:32:f1:df:6d:e2:9c:1b:
-         03:b7:81:61:cc:11:09:94:e3:77:86:15:4e:ec:52:f8:d2:8c:
-         a3:31:83:20:f2:72:78:0e:c1:3d:af:6f:3c:7d:47:27:0b:97:
-         54:5f:be:c7:95:09:bd:5d:d6:a9:b7:27:29:58:fd:85:26:d5:
-         c1:c6:ac:63:17:9f:9c:f7:d8:ff:7c:f4:0a:8d:7d:da:8e:fc:
-         42:3b:43:4d:83:37:f8:62:32:e5:45:58:7b:45:11:19:2d:17:
-         68:ce:23:93
+         a1:98:0f:e0:29:2f:bb:f4:5e:56:15:a1:c6:2f:4a:26:1a:31:
+         b2:8e:85:31:aa:7f:96:db:bc:24:d1:10:88:fd:e1:fa:c0:5b:
+         e2:f3:44:0e:4c:ba:d4:46:3d:52:de:39:c2:4c:2e:bf:7c:f9:
+         37:27:99:1b:b9:6b:13:fc:51:df:a0:51:9f:26:c2:4a:03:cd:
+         f0:d9:5c:b8:1e:6e:f2:2c:52:d4:b0:a2:09:c4:c4:9d:b8:be:
+         a3:98:bf:38:b3:9d:78:f3:14:87:71:18:eb:f1:85:f3:37:7d:
+         f8:63:90:24:81:02:ec:04:33:ff:db:2e:f7:33:36:8c:37:ba:
+         89:94:4e:3a:12:0d:29:9f:ab:34:5f:28:0a:de:f5:cb:6e:f1:
+         ca:f2:e7:43:ea:e7:74:18:3c:e5:b1:12:a5:d8:db:66:64:21:
+         19:ac:bf:c1:cb:6b:a4:4a:2c:f0:11:de:a3:4c:1e:7b:82:f1:
+         28:44:b4:f7:44:06:69:de:cc:bd:88:ef:04:1d:27:57:5e:e4:
+         2f:ba:51:e8:43:50:f1:50:18:9b:7c:84:0e:cd:ac:f3:63:d5:
+         f0:68:39:3b:04:a5:7e:e4:51:17:95:24:7c:b9:31:50:ec:ed:
+         99:ef:a8:9a:02:36:b1:10:46:ea:0b:e1:d2:75:e7:93:7d:a5:
+         07:b1:47:93
 -----BEGIN CERTIFICATE-----
-MIIDHTCCAgWgAwIBAgIBATANBgkqhkiG9w0BAQsFADAjMSEwHwYDVQQDDBhBSUEg
-VGVzdCBJbnRlcm1lZGlhdGUgQ0EwHhcNMTQwODE0MDI0NjE4WhcNMjQwODExMDI0
-NjE4WjAbMRkwFwYDVQQDDBBhaWEtaG9zdC5pbnZhbGlkMIIBIjANBgkqhkiG9w0B
-AQEFAAOCAQ8AMIIBCgKCAQEA16giaOkyElpJy8tH35M0DS4OoOgwJ6dpR8z0/nat
-E5XS3DkFrWL3jyPWBByjhDCgDzd9+ijU80vkDM7AV5bEQD0gILB4GRupeq0gTqY5
-QjlI9RikBQManvXPVOI+XTjHXfiJ1F058BXblia7Ev6kxbD/bUH3+CWBbZkDkyB9
-KSW9FanqLZgDW1SIM6njiBreFEL0QlZcZ506mmks0hfldawoc0RIIghrP1qCS3aK
-WTv5VVGyApTyaBITaljLyCoBFU3t9Q8DYUzClL83v9BirVEuWuuK4dto15YUewnd
-dRJf/nJAO6CuwgudrnkTgeHLR4PN6gemAEGitAgW+xdz3QIDAQABo2QwYjAMBgNV
-HRMBAf8EAjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAzBggrBgEF
-BQcBAQQnMCUwIwYIKwYBBQUHMAKGF2h0dHA6Ly9haWEtdGVzdC5pbnZhbGlkMA0G
-CSqGSIb3DQEBCwUAA4IBAQDCT3cXWgt4mcJ5BgAqbYr2gamFxJnd/LgOdyAUE71+
-9fd5h/LmlfhoTFlcRpvY+Qjurp0R8tbMHQrYfBb6NoeqbIl08GYWnpnKg4r/DSA6
-vQU4UpjwtnQ/qG5IAoZ9Oe5+NNtcOB6IkHhVCEwjXuc96C9ms/EwzhiUZXxiCFAv
-KduqPPA6qbPu7hnM9wojugpR88WvbcyMX3fS0jLx323inBsDt4FhzBEJlON3hhVO
-7FL40oyjMYMg8nJ4DsE9r288fUcnC5dUX77HlQm9XdaptycpWP2FJtXBxqxjF5+c
-99j/fPQKjX3ajvxCO0NNgzf4YjLlRVh7RREZLRdoziOT
+MIIDOzCCAiOgAwIBAgIBATANBgkqhkiG9w0BAQsFADAjMSEwHwYDVQQDDBhBSUEg
+VGVzdCBJbnRlcm1lZGlhdGUgQ0EwHhcNMTcwMjI4MjMwMjM5WhcNMjcwMjI2MjMw
+MjM5WjAbMRkwFwYDVQQDDBBhaWEtaG9zdC5pbnZhbGlkMIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEA4qm5RBeDz1fUIoZUUtNCfQOEmvk/BRZzrU5V0dCt
+88/9GoA4c1C3+hPIxmk4TJxK+8agokTzfmZ27N3v6V0qFou1ZeN457fl0YjI2OA6
+jxy7jLONjlKfvBWfkhKO1VaE3MH4uFjV6b5yK62q1GO2adrgTVivijr3hS9iKyTC
+SW8cZVWMkrvBI0c4nVEXFJKGt57QBxsUODYsyuZ3uAPsUwREKdWukUFSSF2QULBj
+Mpf1YhoIEZYqtJdmG7RWtX7CqVuJ2P7eRHz/YW7zAp+IMOtLgBRIhDP/5CjA41pq
+Vd1IdbJh5un1PTpVRbSTTuADyaHejOswitOP5x9KqXLCvwIDAQABo4GBMH8wDAYD
+VR0TAQH/BAIwADAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwMwYIKwYB
+BQUHAQEEJzAlMCMGCCsGAQUFBzAChhdodHRwOi8vYWlhLXRlc3QuaW52YWxpZDAb
+BgNVHREEFDASghBhaWEtaG9zdC5pbnZhbGlkMA0GCSqGSIb3DQEBCwUAA4IBAQCh
+mA/gKS+79F5WFaHGL0omGjGyjoUxqn+W27wk0RCI/eH6wFvi80QOTLrURj1S3jnC
+TC6/fPk3J5kbuWsT/FHfoFGfJsJKA83w2Vy4Hm7yLFLUsKIJxMSduL6jmL84s514
+8xSHcRjr8YXzN334Y5AkgQLsBDP/2y73MzaMN7qJlE46Eg0pn6s0XygK3vXLbvHK
+8udD6ud0GDzlsRKl2NtmZCEZrL/By2ukSizwEd6jTB57gvEoRLT3RAZp3sy9iO8E
+HSdXXuQvulHoQ1DxUBibfIQOzazzY9XwaDk7BKV+5FEXlSR8uTFQ7O2Z76iaAjax
+EEbqC+HSdeeTfaUHsUeT
 -----END CERTIFICATE-----
diff --git a/net/data/ssl/certificates/aia-intermediate.der b/net/data/ssl/certificates/aia-intermediate.der
index f89a1b9..05249254 100644
--- a/net/data/ssl/certificates/aia-intermediate.der
+++ b/net/data/ssl/certificates/aia-intermediate.der
Binary files differ
diff --git a/net/data/ssl/certificates/aia-root.pem b/net/data/ssl/certificates/aia-root.pem
index 866b3ac..a7bee840 100644
--- a/net/data/ssl/certificates/aia-root.pem
+++ b/net/data/ssl/certificates/aia-root.pem
@@ -1,72 +1,72 @@
 Certificate:
     Data:
         Version: 3 (0x2)
-        Serial Number: 16253959350627671104 (0xe191a9e987cd1c40)
-    Signature Algorithm: sha1WithRSAEncryption
+        Serial Number: 9897276640789498169 (0x895a30aab2078939)
+    Signature Algorithm: sha256WithRSAEncryption
         Issuer: CN=AIA Test Root CA
         Validity
-            Not Before: Aug 14 02:46:18 2014 GMT
-            Not After : Aug 11 02:46:18 2024 GMT
+            Not Before: Feb 28 23:02:39 2017 GMT
+            Not After : Feb 26 23:02:39 2027 GMT
         Subject: CN=AIA Test Root CA
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
                 Public-Key: (2048 bit)
                 Modulus:
-                    00:c4:5c:27:f1:69:03:2f:85:94:57:91:3c:21:13:
-                    f9:61:de:be:1c:99:b4:fe:e5:8c:8a:6d:e1:8c:fa:
-                    26:2d:56:a5:7d:81:00:c2:16:e9:14:8e:70:7a:72:
-                    22:25:66:09:14:32:b1:04:ad:74:fb:64:77:dc:42:
-                    73:b0:7f:0f:e6:8d:04:78:27:ec:42:f6:65:e4:b7:
-                    d9:f6:93:ba:64:2e:a8:ed:f8:df:68:c4:57:c0:72:
-                    ac:ab:b4:b5:0d:31:ce:7f:57:59:eb:27:f0:8a:30:
-                    5c:1a:5f:f0:65:a3:02:dc:ff:f6:c0:0f:56:ac:b6:
-                    aa:05:cc:3a:46:5c:ec:5e:db:55:6b:44:8f:05:63:
-                    17:c2:5a:67:87:87:17:35:48:09:ae:cc:a5:a3:c7:
-                    7e:2c:c5:7a:aa:2e:0a:a2:fc:2f:90:5e:0e:de:d5:
-                    4a:bc:c1:91:11:aa:91:a8:63:9c:74:9d:0a:80:81:
-                    30:3c:a5:f3:f8:5e:7a:19:08:b5:1a:a8:99:84:6a:
-                    20:fa:fe:3e:99:77:d0:6e:3e:4c:e4:c2:f6:2c:ec:
-                    ce:53:bd:de:56:bf:d2:be:0f:7a:b8:86:14:69:eb:
-                    a2:7b:53:cd:91:21:fd:b6:89:1c:a3:0f:4a:6a:12:
-                    89:19:70:e6:c8:d7:6c:10:d4:a7:f2:b8:36:e8:24:
-                    5b:e7
+                    00:99:a5:b7:7f:fe:7e:6c:e5:24:55:70:90:45:42:
+                    fc:a8:e6:af:93:f7:9d:a8:ed:a1:fd:92:21:ec:4d:
+                    be:db:08:9a:65:2a:c8:3e:5d:ec:bc:c9:47:af:43:
+                    f7:20:b1:4f:ee:51:58:23:c2:82:88:85:68:a3:d0:
+                    f2:77:68:ea:c7:64:b1:79:40:07:ac:69:2e:bd:9e:
+                    6d:1d:ec:52:89:df:2e:20:59:e5:af:07:da:8f:8c:
+                    74:d5:84:88:9b:e9:c1:63:68:34:50:85:22:e6:0d:
+                    39:60:83:c8:4d:fd:39:b2:fd:d3:57:68:dc:18:ae:
+                    b1:b7:51:4a:e6:02:9b:56:16:21:0e:a4:06:17:c9:
+                    91:ee:c1:34:ea:36:1e:b0:e9:d4:e5:02:48:29:dd:
+                    e2:6e:c7:5f:28:ef:3a:67:32:04:9e:9e:91:d2:15:
+                    7e:e9:3a:4c:5d:52:9c:72:09:59:a0:b3:36:8c:6a:
+                    c1:86:81:3b:e8:54:f4:35:77:f6:31:b6:6a:ca:60:
+                    fb:5b:34:38:a4:ca:6e:f2:a2:6f:e6:96:83:08:6b:
+                    bf:d5:37:e8:f7:db:60:06:eb:7a:76:cb:00:e8:de:
+                    2a:c0:ad:36:dc:7d:b7:63:f7:e7:b0:b4:a2:2a:7b:
+                    3f:03:d0:70:30:92:f3:f7:00:ca:d2:53:30:b8:a4:
+                    b7:73
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Basic Constraints: critical
                 CA:TRUE
             X509v3 Key Usage: critical
                 Certificate Sign, CRL Sign
-    Signature Algorithm: sha1WithRSAEncryption
-         6d:5e:d4:ec:95:4c:ea:ae:0e:d6:02:23:f7:6c:09:62:dd:71:
-         8d:37:83:0d:d0:9f:0c:02:6f:52:63:4a:75:df:d4:02:fd:d9:
-         4c:2b:f3:91:99:b5:08:96:f9:72:fa:95:63:1a:45:20:8c:3b:
-         75:30:6b:cf:b7:b4:15:60:da:8d:74:82:32:b9:58:15:df:b0:
-         85:5d:cf:ac:2e:bb:35:2e:29:92:90:cf:8d:ae:e8:59:74:00:
-         2f:74:1d:12:43:f8:2b:50:66:5e:05:5b:35:e2:86:a1:f2:ea:
-         a7:2d:5f:e8:52:4a:e2:78:be:e3:26:c3:36:55:98:6e:f0:6c:
-         6f:e0:3a:d3:77:17:4f:a8:a8:c4:9a:2b:cb:c8:31:1b:15:1c:
-         a5:b2:2a:2d:5f:06:61:cd:44:90:89:f4:24:32:b8:d4:39:46:
-         f6:c4:6f:de:06:c9:06:b7:62:fc:c1:49:be:85:ed:9d:5f:39:
-         2c:db:b3:25:6b:12:a6:ff:ea:27:72:53:16:b8:0b:63:a3:d1:
-         b9:6c:b5:df:51:af:23:70:21:76:a9:ad:ca:36:b6:bd:3b:0a:
-         96:f7:19:4c:0a:06:89:ef:74:ca:54:b8:ba:52:f9:f8:a1:06:
-         c2:e4:0c:56:26:19:f9:82:50:58:91:2d:87:6b:a2:19:4b:96:
-         c4:b9:c9:0b
+    Signature Algorithm: sha256WithRSAEncryption
+         0d:c5:f4:18:aa:e4:08:e9:9a:d5:99:6c:ab:e3:6c:3a:f7:22:
+         86:67:48:52:91:4b:55:18:e4:ce:c4:bb:2c:43:fe:67:d1:31:
+         ea:3e:29:00:ed:f7:ea:1a:5b:9c:9d:9c:fe:98:ac:9a:22:e2:
+         e2:af:86:90:3c:d0:f0:fa:e4:9d:1e:6f:a1:ad:18:4e:59:bf:
+         fb:d3:00:f7:aa:51:31:cb:b5:8e:79:fc:09:74:6c:aa:04:02:
+         d8:ed:69:22:62:b7:c8:ea:45:64:55:30:71:c2:fe:bd:02:c1:
+         a0:f6:40:aa:f8:ad:cf:d2:02:88:f1:69:fe:65:90:a9:5d:82:
+         8c:57:4c:f1:91:84:9e:c5:0f:5e:90:0d:4e:f1:0d:cf:b4:d4:
+         42:b4:68:78:29:2d:f2:da:5a:0d:7a:1d:16:97:68:54:1c:de:
+         30:04:a2:7a:a4:b7:b6:27:1f:98:94:bf:d6:82:16:fd:75:b2:
+         d5:2c:45:71:75:38:01:4e:8b:92:bb:70:b1:e1:10:37:b8:e0:
+         4d:64:a5:2c:29:9a:57:d9:df:14:95:64:58:a9:87:4e:7c:3f:
+         49:cc:f2:b9:6c:d0:76:fc:1b:2e:83:d9:43:40:87:fd:0f:d5:
+         26:04:fa:a9:cd:a7:07:ac:e2:d3:bc:2a:75:4e:c3:e9:2a:f1:
+         21:b2:62:d6
 -----BEGIN CERTIFICATE-----
-MIIC3DCCAcSgAwIBAgIJAOGRqemHzRxAMA0GCSqGSIb3DQEBBQUAMBsxGTAXBgNV
-BAMMEEFJQSBUZXN0IFJvb3QgQ0EwHhcNMTQwODE0MDI0NjE4WhcNMjQwODExMDI0
-NjE4WjAbMRkwFwYDVQQDDBBBSUEgVGVzdCBSb290IENBMIIBIjANBgkqhkiG9w0B
-AQEFAAOCAQ8AMIIBCgKCAQEAxFwn8WkDL4WUV5E8IRP5Yd6+HJm0/uWMim3hjPom
-LValfYEAwhbpFI5wenIiJWYJFDKxBK10+2R33EJzsH8P5o0EeCfsQvZl5LfZ9pO6
-ZC6o7fjfaMRXwHKsq7S1DTHOf1dZ6yfwijBcGl/wZaMC3P/2wA9WrLaqBcw6Rlzs
-XttVa0SPBWMXwlpnh4cXNUgJrsylo8d+LMV6qi4KovwvkF4O3tVKvMGREaqRqGOc
-dJ0KgIEwPKXz+F56GQi1GqiZhGog+v4+mXfQbj5M5ML2LOzOU73eVr/Svg96uIYU
-aeuie1PNkSH9tokcow9KahKJGXDmyNdsENSn8rg26CRb5wIDAQABoyMwITAPBgNV
-HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEA
-bV7U7JVM6q4O1gIj92wJYt1xjTeDDdCfDAJvUmNKdd/UAv3ZTCvzkZm1CJb5cvqV
-YxpFIIw7dTBrz7e0FWDajXSCMrlYFd+whV3PrC67NS4pkpDPja7oWXQAL3QdEkP4
-K1BmXgVbNeKGofLqpy1f6FJK4ni+4ybDNlWYbvBsb+A603cXT6ioxJory8gxGxUc
-pbIqLV8GYc1EkIn0JDK41DlG9sRv3gbJBrdi/MFJvoXtnV85LNuzJWsSpv/qJ3JT
-FrgLY6PRuWy131GvI3Ahdqmtyja2vTsKlvcZTAoGie90ylS4ulL5+KEGwuQMViYZ
-+YJQWJEth2uiGUuWxLnJCw==
+MIIC3DCCAcSgAwIBAgIJAIlaMKqyB4k5MA0GCSqGSIb3DQEBCwUAMBsxGTAXBgNV
+BAMMEEFJQSBUZXN0IFJvb3QgQ0EwHhcNMTcwMjI4MjMwMjM5WhcNMjcwMjI2MjMw
+MjM5WjAbMRkwFwYDVQQDDBBBSUEgVGVzdCBSb290IENBMIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEAmaW3f/5+bOUkVXCQRUL8qOavk/edqO2h/ZIh7E2+
+2wiaZSrIPl3svMlHr0P3ILFP7lFYI8KCiIVoo9Dyd2jqx2SxeUAHrGkuvZ5tHexS
+id8uIFnlrwfaj4x01YSIm+nBY2g0UIUi5g05YIPITf05sv3TV2jcGK6xt1FK5gKb
+VhYhDqQGF8mR7sE06jYesOnU5QJIKd3ibsdfKO86ZzIEnp6R0hV+6TpMXVKccglZ
+oLM2jGrBhoE76FT0NXf2MbZqymD7WzQ4pMpu8qJv5paDCGu/1Tfo99tgBut6dssA
+6N4qwK023H23Y/fnsLSiKns/A9BwMJLz9wDK0lMwuKS3cwIDAQABoyMwITAPBgNV
+HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEA
+DcX0GKrkCOma1Zlsq+NsOvcihmdIUpFLVRjkzsS7LEP+Z9Ex6j4pAO336hpbnJ2c
+/pismiLi4q+GkDzQ8PrknR5voa0YTlm/+9MA96pRMcu1jnn8CXRsqgQC2O1pImK3
+yOpFZFUwccL+vQLBoPZAqvitz9ICiPFp/mWQqV2CjFdM8ZGEnsUPXpANTvENz7TU
+QrRoeCkt8tpaDXodFpdoVBzeMASieqS3ticfmJS/1oIW/XWy1SxFcXU4AU6Lkrtw
+seEQN7jgTWSlLCmaV9nfFJVkWKmHTnw/SczyuWzQdvwbLoPZQ0CH/Q/VJgT6qc2n
+B6zi07wqdU7D6SrxIbJi1g==
 -----END CERTIFICATE-----
diff --git a/net/data/ssl/certificates/explicit-policy-chain.pem b/net/data/ssl/certificates/explicit-policy-chain.pem
index e8e76e2..5f6c143e 100644
--- a/net/data/ssl/certificates/explicit-policy-chain.pem
+++ b/net/data/ssl/certificates/explicit-policy-chain.pem
@@ -5,31 +5,31 @@
     Signature Algorithm: sha256WithRSAEncryption
         Issuer: CN=Policy Test Intermediate CA
         Validity
-            Not Before: Aug 14 02:47:04 2014 GMT
-            Not After : Aug 11 02:47:04 2024 GMT
+            Not Before: Feb 28 23:52:34 2017 GMT
+            Not After : Feb 26 23:52:34 2027 GMT
         Subject: CN=policy_test.example
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
                 Public-Key: (2048 bit)
                 Modulus:
-                    00:d0:68:ed:42:48:45:60:62:ba:1a:cd:d1:9a:a0:
-                    fc:4d:3a:a9:d3:dd:29:84:0b:4b:7f:c6:81:d1:a6:
-                    7c:27:4c:35:ab:81:4d:60:2c:98:94:82:2c:50:50:
-                    27:a5:53:c9:c4:82:99:30:60:5e:87:73:03:d8:b0:
-                    f0:7b:a4:45:28:8f:82:b4:d8:4d:8d:e0:1b:b7:38:
-                    1c:50:54:2a:fe:59:2e:b7:ca:14:5b:0b:5c:5c:40:
-                    fc:87:08:87:37:b7:a4:6c:56:fa:fe:26:98:30:92:
-                    f9:c1:ca:aa:32:b2:61:9e:2c:50:62:4d:b1:78:fe:
-                    0e:a9:fb:91:e6:6b:f7:d0:ac:12:4a:e9:f4:9e:00:
-                    37:9f:6a:9c:d4:b1:05:8e:07:b2:e2:6d:ac:4e:b9:
-                    7a:5a:26:c2:f5:5b:8a:29:52:bd:1d:04:fc:07:38:
-                    e8:f4:d1:18:c5:97:1e:cc:46:35:d7:0f:9d:0d:3e:
-                    98:c4:d9:18:15:46:82:79:78:21:1b:73:17:35:dd:
-                    b9:fb:8c:b7:d4:f7:08:2f:cb:43:c6:2f:25:c7:fc:
-                    22:1e:49:cd:59:dd:a1:0f:53:bf:8e:92:f4:25:5e:
-                    fd:de:f4:98:de:c2:c1:8b:ce:a3:3a:0e:48:94:2a:
-                    b3:c3:b0:48:cf:5f:16:14:83:b1:7b:0f:30:68:83:
-                    d1:37
+                    00:b3:2a:fe:85:4f:88:af:bb:62:62:b7:03:a7:c4:
+                    d7:29:37:d6:73:31:22:93:d1:5f:33:f6:8f:bf:33:
+                    00:a6:ae:72:da:cb:3d:86:3b:f8:22:29:32:a7:4f:
+                    aa:21:fd:43:47:83:18:96:c2:5c:76:f2:9a:6a:e1:
+                    49:84:22:1f:a7:d6:d6:a9:ce:d5:06:17:e3:67:65:
+                    1b:9a:05:38:2b:ee:e5:7b:ed:4e:69:b8:13:78:bc:
+                    41:b5:19:30:6a:13:d7:94:a9:d6:63:96:54:fb:61:
+                    a6:64:3a:ec:2a:83:27:c7:85:6d:57:1b:0a:67:aa:
+                    a2:ac:56:ef:24:24:62:df:46:4d:cc:75:25:db:19:
+                    7c:75:29:41:cc:88:c1:4d:a8:cc:ec:d5:23:a0:34:
+                    e7:96:57:6a:92:f8:34:ce:26:0c:41:29:99:be:54:
+                    db:d9:6f:45:5d:f7:f2:6d:c2:8b:fe:e6:4a:29:4f:
+                    74:8b:70:d5:8f:7f:64:b7:70:c6:2c:5a:01:d5:1d:
+                    6b:bb:ad:9f:3f:44:33:fe:dc:60:9a:79:a6:dc:ac:
+                    fb:79:f9:b5:f0:7f:e0:ea:96:e5:1a:bf:24:3c:e4:
+                    4f:55:3c:64:c0:d2:28:ee:b3:8d:c4:9b:a4:63:60:
+                    eb:ca:28:54:7e:d1:61:e9:cb:f6:14:d1:77:f5:f3:
+                    aa:89
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Basic Constraints: critical
@@ -39,40 +39,42 @@
             X509v3 Certificate Policies: 
                 Policy: 1.2.3.4
 
+            X509v3 Subject Alternative Name: 
+                DNS:policy_test.example
     Signature Algorithm: sha256WithRSAEncryption
-         55:fc:fd:62:cd:93:0f:09:1e:6c:d8:ef:95:8c:d9:0c:a9:de:
-         3e:d2:2b:70:83:33:e1:da:b1:72:c0:13:b5:4a:ef:bf:94:38:
-         c3:b3:df:40:52:74:5a:1b:ae:4b:d3:c9:1f:c2:6c:c6:3d:43:
-         fd:03:31:9d:45:a6:26:c2:56:b1:79:36:26:11:c5:dd:23:e1:
-         1b:62:a4:c3:0f:9a:d9:ab:f5:94:53:e2:7a:53:ea:96:48:55:
-         8c:da:e0:11:2a:cc:46:7f:05:e6:90:cb:c8:54:50:38:d2:c8:
-         f9:96:40:65:02:96:7b:2e:6a:46:c2:79:6d:d6:3e:63:2e:77:
-         e8:19:72:94:8a:a2:f4:cd:2a:9f:3d:63:1b:00:c7:57:89:3f:
-         e5:06:a5:ae:b7:f4:5f:3a:20:96:11:5f:2e:fc:7a:61:23:c1:
-         15:b2:8f:07:74:69:4f:74:23:1d:7a:77:02:33:79:47:8c:c4:
-         46:f7:4f:57:16:33:44:13:1d:b5:6d:4f:77:a1:97:41:e9:29:
-         8b:49:f4:38:e3:42:21:10:c5:9c:a2:84:fa:0b:04:5c:2d:30:
-         ab:4e:0a:9c:30:50:a7:62:9b:c1:5c:6d:06:38:34:1a:cc:2b:
-         7f:20:9d:8f:ad:59:8e:4a:da:b8:88:e2:0d:de:cb:65:37:0c:
-         cc:8f:c4:c1
+         c4:94:39:60:06:55:5d:2e:af:55:e2:ab:e5:b5:fc:96:fd:24:
+         c2:08:80:fd:55:e4:d1:5c:c8:44:d2:9f:0c:0f:1a:47:2f:da:
+         33:f9:1b:11:aa:27:1c:81:e0:ba:0e:77:26:97:08:6b:80:2e:
+         81:d6:e2:37:22:33:75:31:33:41:0e:40:1a:bd:b7:8a:3e:95:
+         b6:d4:1f:bf:30:ae:75:e5:45:32:85:67:33:56:c1:42:30:7f:
+         bf:9c:ad:bc:69:91:a9:71:f9:96:1e:85:b9:7b:ea:45:ee:85:
+         1a:50:8e:05:04:69:fc:86:2b:52:54:9b:5e:f6:a0:8f:49:0d:
+         f9:d0:63:94:4e:04:e3:eb:fb:47:17:79:76:00:0c:d1:da:2c:
+         1e:8c:11:04:92:9b:01:a5:38:fb:3f:8b:7f:27:04:07:af:40:
+         8b:f3:62:e0:7e:d2:37:e5:ea:ef:98:ef:92:d7:06:59:ee:e5:
+         83:e0:f5:4a:9a:9e:cf:38:11:e1:f8:f3:9d:3d:21:4c:ea:6b:
+         34:44:e1:2c:5e:eb:0e:cd:77:8a:5a:a8:40:f9:03:ff:f4:47:
+         a7:f8:1d:d0:43:38:b6:06:c2:67:2a:42:92:44:ad:6d:c9:e7:
+         d0:60:89:82:21:fc:c5:ea:e6:21:94:26:a3:76:02:05:c5:4c:
+         34:d3:5f:2d
 -----BEGIN CERTIFICATE-----
-MIIDADCCAeigAwIBAgIBATANBgkqhkiG9w0BAQsFADAmMSQwIgYDVQQDDBtQb2xp
-Y3kgVGVzdCBJbnRlcm1lZGlhdGUgQ0EwHhcNMTQwODE0MDI0NzA0WhcNMjQwODEx
-MDI0NzA0WjAeMRwwGgYDVQQDDBNwb2xpY3lfdGVzdC5leGFtcGxlMIIBIjANBgkq
-hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0GjtQkhFYGK6Gs3RmqD8TTqp090phAtL
-f8aB0aZ8J0w1q4FNYCyYlIIsUFAnpVPJxIKZMGBeh3MD2LDwe6RFKI+CtNhNjeAb
-tzgcUFQq/lkut8oUWwtcXED8hwiHN7ekbFb6/iaYMJL5wcqqMrJhnixQYk2xeP4O
-qfuR5mv30KwSSun0ngA3n2qc1LEFjgey4m2sTrl6WibC9VuKKVK9HQT8Bzjo9NEY
-xZcezEY11w+dDT6YxNkYFUaCeXghG3MXNd25+4y31PcIL8tDxi8lx/wiHknNWd2h
-D1O/jpL0JV793vSY3sLBi86jOg5IlCqzw7BIz18WFIOxew8waIPRNwIDAQABo0Ew
-PzAMBgNVHRMBAf8EAjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAQ
-BgNVHSAECTAHMAUGAyoDBDANBgkqhkiG9w0BAQsFAAOCAQEAVfz9Ys2TDwkebNjv
-lYzZDKnePtIrcIMz4dqxcsATtUrvv5Q4w7PfQFJ0WhuuS9PJH8Jsxj1D/QMxnUWm
-JsJWsXk2JhHF3SPhG2Kkww+a2av1lFPielPqlkhVjNrgESrMRn8F5pDLyFRQONLI
-+ZZAZQKWey5qRsJ5bdY+Yy536BlylIqi9M0qnz1jGwDHV4k/5Qalrrf0XzoglhFf
-Lvx6YSPBFbKPB3RpT3QjHXp3AjN5R4zERvdPVxYzRBMdtW1Pd6GXQekpi0n0OONC
-IRDFnKKE+gsEXC0wq04KnDBQp2KbwVxtBjg0GswrfyCdj61ZjkrauIjiDd7LZTcM
-zI/EwQ==
+MIIDIDCCAgigAwIBAgIBATANBgkqhkiG9w0BAQsFADAmMSQwIgYDVQQDDBtQb2xp
+Y3kgVGVzdCBJbnRlcm1lZGlhdGUgQ0EwHhcNMTcwMjI4MjM1MjM0WhcNMjcwMjI2
+MjM1MjM0WjAeMRwwGgYDVQQDDBNwb2xpY3lfdGVzdC5leGFtcGxlMIIBIjANBgkq
+hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsyr+hU+Ir7tiYrcDp8TXKTfWczEik9Ff
+M/aPvzMApq5y2ss9hjv4Iikyp0+qIf1DR4MYlsJcdvKaauFJhCIfp9bWqc7VBhfj
+Z2UbmgU4K+7le+1OabgTeLxBtRkwahPXlKnWY5ZU+2GmZDrsKoMnx4VtVxsKZ6qi
+rFbvJCRi30ZNzHUl2xl8dSlBzIjBTajM7NUjoDTnlldqkvg0ziYMQSmZvlTb2W9F
+XffybcKL/uZKKU90i3DVj39kt3DGLFoB1R1ru62fP0Qz/txgmnmm3Kz7efm18H/g
+6pblGr8kPORPVTxkwNIo7rONxJukY2DryihUftFh6cv2FNF39fOqiQIDAQABo2Ew
+XzAMBgNVHRMBAf8EAjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAQ
+BgNVHSAECTAHMAUGAyoDBDAeBgNVHREEFzAVghNwb2xpY3lfdGVzdC5leGFtcGxl
+MA0GCSqGSIb3DQEBCwUAA4IBAQDElDlgBlVdLq9V4qvltfyW/STCCID9VeTRXMhE
+0p8MDxpHL9oz+RsRqiccgeC6DncmlwhrgC6B1uI3IjN1MTNBDkAavbeKPpW21B+/
+MK515UUyhWczVsFCMH+/nK28aZGpcfmWHoW5e+pF7oUaUI4FBGn8hitSVJte9qCP
+SQ350GOUTgTj6/tHF3l2AAzR2iwejBEEkpsBpTj7P4t/JwQHr0CL82LgftI35erv
+mO+S1wZZ7uWD4PVKmp7POBHh+POdPSFM6ms0ROEsXusOzXeKWqhA+QP/9Een+B3Q
+Qzi2BsJnKkKSRK1tyefQYImCIfzF6uYhlCajdgIFxUw0018t
 -----END CERTIFICATE-----
 Certificate:
     Data:
@@ -81,31 +83,31 @@
     Signature Algorithm: sha256WithRSAEncryption
         Issuer: CN=Policy Test Root CA
         Validity
-            Not Before: Aug 14 02:47:04 2014 GMT
-            Not After : Aug 11 02:47:04 2024 GMT
+            Not Before: Feb 28 23:52:34 2017 GMT
+            Not After : Feb 26 23:52:34 2027 GMT
         Subject: CN=Policy Test Intermediate CA
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
                 Public-Key: (2048 bit)
                 Modulus:
-                    00:ce:aa:c0:cb:1f:fa:f0:d9:e0:a3:69:f6:94:02:
-                    86:7b:89:ce:37:85:c4:df:35:36:cf:24:57:d2:b6:
-                    7a:f5:0b:a6:37:ab:6c:4a:2e:6a:87:c2:d4:64:53:
-                    74:fa:01:42:4c:ee:a5:79:eb:61:fe:9d:47:1f:65:
-                    27:9f:b8:ca:4a:06:92:fa:a7:49:47:51:32:48:7d:
-                    5d:1e:ac:b4:03:33:87:6b:d4:5a:ae:05:45:3e:cc:
-                    10:2d:e5:dc:31:56:cd:1f:22:3b:b8:84:ff:6d:e2:
-                    26:ec:6f:ef:18:7f:8b:a3:fe:d7:7c:81:8a:bf:bb:
-                    0e:63:09:1a:0b:89:02:be:e9:c6:59:c7:28:d8:6d:
-                    41:c2:2a:d2:c2:d5:03:6d:cd:3d:62:47:78:95:36:
-                    67:a2:5e:ae:0a:0c:da:75:df:dc:6d:04:42:0a:f2:
-                    88:70:a9:29:d1:c3:db:17:b7:62:f1:e7:a4:29:a7:
-                    78:de:8a:c1:51:64:5e:39:21:e6:75:40:bf:7c:2e:
-                    bf:c8:8e:c2:86:23:b9:f4:67:80:7e:59:d1:a1:77:
-                    7c:da:ec:ed:37:e9:e8:b9:98:7f:c1:5d:29:9f:c7:
-                    c2:c5:68:89:b7:0f:f1:ec:30:96:72:bf:b0:a0:fd:
-                    0e:ce:92:d2:54:2d:ca:d6:6b:4c:c6:95:60:4e:bd:
-                    25:f9
+                    00:c9:2b:9e:41:e1:bd:db:2c:15:20:25:6b:02:2f:
+                    9d:f5:10:12:22:2e:c4:93:ee:99:1c:92:50:02:d4:
+                    70:49:cc:bf:92:54:e0:04:5a:52:d8:c9:5e:74:1a:
+                    74:57:22:20:7a:8e:d8:bc:d2:02:bb:85:ec:9b:6b:
+                    80:51:d2:a4:47:6e:f6:fb:16:e2:d8:7b:58:5e:e5:
+                    22:62:68:e9:c9:f6:ff:0a:f9:ca:65:da:12:da:24:
+                    55:de:43:ef:51:54:d2:ac:db:ec:d6:13:5b:29:e1:
+                    6e:66:a1:71:f0:88:9b:23:d6:e1:79:aa:b6:76:7d:
+                    63:f6:19:63:14:5e:db:9f:28:1d:07:92:db:69:8f:
+                    fb:d5:4c:de:eb:3a:8b:df:5c:77:26:5e:f4:3f:a2:
+                    ed:19:ad:76:f0:8c:71:9c:cd:d7:c6:0c:95:6a:9b:
+                    ec:4a:e0:50:68:61:19:17:44:09:6c:93:22:03:4a:
+                    f6:e9:4c:ca:88:4d:cd:e1:a6:20:8c:a6:dc:43:f7:
+                    c3:4c:61:89:2d:db:12:74:57:00:8a:a6:e2:0e:1a:
+                    1b:93:12:f9:63:b5:01:12:07:a1:b4:4a:2a:7f:8d:
+                    c8:ab:25:fb:0a:cd:ed:18:ba:32:94:50:b9:6d:3c:
+                    f2:67:45:61:73:84:25:0d:43:86:78:b9:11:e9:51:
+                    e7:95
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Basic Constraints: critical
@@ -120,109 +122,109 @@
                 Policy: 1.2.3.5
 
     Signature Algorithm: sha256WithRSAEncryption
-         97:3a:32:09:ae:fd:00:bc:17:22:f5:d0:17:e9:c0:0f:60:af:
-         3c:3d:8e:53:6b:92:80:4d:0f:bc:9c:7e:96:6f:63:c8:7e:d6:
-         f7:68:6d:b6:5f:64:09:fd:03:27:37:1e:0b:b1:ad:e6:7b:14:
-         a6:d5:8c:0b:a2:83:3b:82:1c:db:8d:d8:53:f7:17:22:ef:d8:
-         fd:89:bc:19:b3:f0:fa:cc:bc:9f:47:e8:5d:27:4f:a3:c5:fc:
-         bc:28:6c:ff:12:81:10:0d:10:9b:3b:29:ee:9b:8f:78:01:29:
-         25:0e:97:61:93:1b:68:d2:be:b2:9a:45:c8:e6:34:f2:de:c1:
-         74:c2:21:b8:44:57:41:f6:5c:c1:87:0b:f3:2c:fe:6d:28:8d:
-         fe:e2:6b:95:19:89:27:9a:6e:b9:de:d3:65:7f:85:7c:18:80:
-         d3:ad:48:cc:ed:5f:a2:b4:ee:ef:54:6b:e2:32:b9:b8:1e:34:
-         e4:38:f2:1d:79:fa:2c:d8:cc:6b:3f:bb:65:e1:c1:46:54:86:
-         9f:99:08:6f:65:bd:dc:e3:20:f4:b2:01:80:ee:66:85:d4:4e:
-         66:46:db:45:00:26:e5:16:3f:69:88:04:48:cf:9b:4e:f8:49:
-         e7:ed:26:47:3d:28:72:6c:ae:bc:70:e9:8a:d9:1e:67:84:f6:
-         2c:20:73:0e
+         67:fd:e1:e8:91:20:ed:e6:f6:b3:41:27:07:b8:cc:55:ea:90:
+         7e:cc:11:6a:e9:02:24:95:86:8d:68:72:50:a3:d5:9c:bd:34:
+         78:3b:65:73:78:5c:9a:b6:da:5f:78:01:65:ed:da:5d:fe:fb:
+         cb:ef:a4:22:75:c0:cb:3b:c8:e0:ca:91:08:4d:f4:d9:cf:73:
+         16:09:e9:cc:09:96:6f:97:a6:4f:cb:72:c9:5d:ea:3b:21:bf:
+         e2:0e:18:ac:97:51:b1:81:02:1f:f5:a6:26:25:76:2b:8c:c7:
+         2c:66:be:03:b2:de:5a:6f:c6:bb:44:9f:b2:1a:75:76:4f:bb:
+         d0:2a:67:e3:51:69:9d:1d:6f:0a:8c:f1:d9:1d:16:aa:c3:7d:
+         b8:38:fa:a1:90:2b:15:dc:81:b2:80:66:6e:b6:69:83:03:88:
+         c6:2e:03:2a:ea:9c:5e:ea:98:9c:b3:93:21:d8:f9:6d:2e:ec:
+         40:d3:bf:f5:53:69:b0:0f:4d:d9:6b:6c:ac:bc:f8:e8:12:13:
+         d1:58:16:0a:7f:13:14:31:72:69:90:d3:2f:d1:2e:d0:b2:f7:
+         14:c9:4f:0c:d8:95:21:9f:9d:b8:4d:ae:80:75:3c:92:f9:a7:
+         5a:4a:1c:6c:b2:19:a5:e6:1a:7b:a6:5d:c3:e9:a9:ae:c9:2e:
+         7a:8b:a3:6c
 -----BEGIN CERTIFICATE-----
 MIIDETCCAfmgAwIBAgIBATANBgkqhkiG9w0BAQsFADAeMRwwGgYDVQQDDBNQb2xp
-Y3kgVGVzdCBSb290IENBMB4XDTE0MDgxNDAyNDcwNFoXDTI0MDgxMTAyNDcwNFow
+Y3kgVGVzdCBSb290IENBMB4XDTE3MDIyODIzNTIzNFoXDTI3MDIyNjIzNTIzNFow
 JjEkMCIGA1UEAwwbUG9saWN5IFRlc3QgSW50ZXJtZWRpYXRlIENBMIIBIjANBgkq
-hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzqrAyx/68Nngo2n2lAKGe4nON4XE3zU2
-zyRX0rZ69QumN6tsSi5qh8LUZFN0+gFCTO6leeth/p1HH2Unn7jKSgaS+qdJR1Ey
-SH1dHqy0AzOHa9RargVFPswQLeXcMVbNHyI7uIT/beIm7G/vGH+Lo/7XfIGKv7sO
-YwkaC4kCvunGWcco2G1BwirSwtUDbc09Ykd4lTZnol6uCgzadd/cbQRCCvKIcKkp
-0cPbF7di8eekKad43orBUWReOSHmdUC/fC6/yI7ChiO59GeAflnRoXd82uztN+no
-uZh/wV0pn8fCxWiJtw/x7DCWcr+woP0OzpLSVC3K1mtMxpVgTr0l+QIDAQABo1Iw
+hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAySueQeG92ywVICVrAi+d9RASIi7Ek+6Z
+HJJQAtRwScy/klTgBFpS2MledBp0VyIgeo7YvNICu4Xsm2uAUdKkR272+xbi2HtY
+XuUiYmjpyfb/CvnKZdoS2iRV3kPvUVTSrNvs1hNbKeFuZqFx8IibI9bheaq2dn1j
+9hljFF7bnygdB5LbaY/71Uze6zqL31x3Jl70P6LtGa128IxxnM3XxgyVapvsSuBQ
+aGEZF0QJbJMiA0r26UzKiE3N4aYgjKbcQ/fDTGGJLdsSdFcAiqbiDhobkxL5Y7UB
+EgehtEoqf43IqyX7Cs3tGLoylFC5bTzyZ0Vhc4QlDUOGeLkR6VHnlQIDAQABo1Iw
 UDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAMBgNVHSQEBTADgAEA
 MB8GA1UdIAQYMBYwBQYDKgMEMAYGBCoDBAUwBQYDKgMFMA0GCSqGSIb3DQEBCwUA
-A4IBAQCXOjIJrv0AvBci9dAX6cAPYK88PY5Ta5KATQ+8nH6Wb2PIftb3aG22X2QJ
-/QMnNx4Lsa3mexSm1YwLooM7ghzbjdhT9xci79j9ibwZs/D6zLyfR+hdJ0+jxfy8
-KGz/EoEQDRCbOynum494ASklDpdhkxto0r6ymkXI5jTy3sF0wiG4RFdB9lzBhwvz
-LP5tKI3+4muVGYknmm653tNlf4V8GIDTrUjM7V+itO7vVGviMrm4HjTkOPIdefos
-2MxrP7tl4cFGVIafmQhvZb3c4yD0sgGA7maF1E5mRttFACblFj9piARIz5tO+Enn
-7SZHPShybK68cOmK2R5nhPYsIHMO
+A4IBAQBn/eHokSDt5vazQScHuMxV6pB+zBFq6QIklYaNaHJQo9WcvTR4O2VzeFya
+ttpfeAFl7dpd/vvL76QidcDLO8jgypEITfTZz3MWCenMCZZvl6ZPy3LJXeo7Ib/i
+Dhisl1GxgQIf9aYmJXYrjMcsZr4Dst5ab8a7RJ+yGnV2T7vQKmfjUWmdHW8KjPHZ
+HRaqw324OPqhkCsV3IGygGZutmmDA4jGLgMq6pxe6pics5Mh2PltLuxA07/1U2mw
+D03Za2ysvPjoEhPRWBYKfxMUMXJpkNMv0S7QsvcUyU8M2JUhn524Ta6AdTyS+ada
+Shxsshml5hp7pl3D6amuyS56i6Ns
 -----END CERTIFICATE-----
 Certificate:
     Data:
         Version: 3 (0x2)
-        Serial Number: 14176371491008760447 (0xc4bc96c2ed8d4a7f)
-    Signature Algorithm: sha1WithRSAEncryption
+        Serial Number: 14437560522667520790 (0xc85c84cd48ccf316)
+    Signature Algorithm: sha256WithRSAEncryption
         Issuer: CN=Policy Test Root CA
         Validity
-            Not Before: Aug 14 02:47:04 2014 GMT
-            Not After : Aug 11 02:47:04 2024 GMT
+            Not Before: Feb 28 23:52:34 2017 GMT
+            Not After : Feb 26 23:52:34 2027 GMT
         Subject: CN=Policy Test Root CA
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
                 Public-Key: (2048 bit)
                 Modulus:
-                    00:be:69:b6:16:0b:d4:be:8d:b3:98:4f:b8:64:64:
-                    5c:2f:37:5a:e7:a8:56:01:19:b0:46:91:b7:1d:05:
-                    51:57:73:c7:cb:68:24:98:26:e6:b6:39:db:bb:4d:
-                    d0:06:6b:03:bc:06:e4:7b:43:2d:48:6a:28:3e:75:
-                    c8:82:f8:27:86:fb:84:a8:b1:90:fe:b9:2a:07:d1:
-                    15:ca:be:0a:a4:e1:88:6a:01:0c:57:27:a3:d1:ad:
-                    f6:00:3b:15:98:e9:80:04:08:ac:26:be:0c:38:28:
-                    44:b5:2c:f1:75:c5:03:de:81:ec:d9:da:60:38:fb:
-                    04:7f:36:df:72:bd:2b:c4:bb:37:88:d5:88:14:73:
-                    51:f8:7f:d6:f4:40:a4:05:0b:26:9a:c9:23:3e:ba:
-                    e0:fc:76:6e:81:69:65:33:c0:d4:8d:78:d4:45:c9:
-                    90:14:60:cb:71:88:21:0c:a9:94:09:45:48:4a:29:
-                    f2:f2:5e:37:34:85:38:35:75:a9:52:06:d3:58:ed:
-                    b8:09:ab:5c:4d:1a:e9:61:79:a0:97:64:99:58:97:
-                    79:70:25:4d:ca:bf:01:6d:e0:6c:29:51:17:79:46:
-                    fd:31:44:be:e6:6a:47:be:1d:4e:75:72:08:5f:b2:
-                    e0:49:e2:54:57:d5:e9:f7:72:b1:ee:aa:ee:41:4b:
-                    e9:f5
+                    00:a0:e3:a7:af:b8:fa:3b:ee:47:d2:5a:ad:21:a2:
+                    71:42:4e:a6:a3:c7:82:94:b9:32:3c:6d:14:39:67:
+                    19:65:64:1f:8b:b5:c4:6d:88:12:2c:85:e2:ef:97:
+                    04:f5:9f:ee:13:65:a7:f5:86:c7:5b:20:1d:fe:47:
+                    71:a7:ab:04:69:52:0f:ea:6c:42:58:7b:89:32:49:
+                    54:14:da:d3:ad:ef:b8:7a:cc:8c:7f:16:0e:2a:b6:
+                    0e:7b:df:a5:ee:26:ff:b0:c9:6b:65:6e:15:02:b5:
+                    f4:4f:e5:6a:e1:b8:45:63:55:f9:61:0d:f6:27:cf:
+                    f3:10:ae:4a:0a:57:25:5c:de:b1:c5:8e:b2:bc:f1:
+                    b9:f2:99:c4:27:1d:53:0b:2b:7c:2a:fd:fc:73:7e:
+                    f4:ad:44:bc:8b:47:23:bd:c1:54:f3:ed:0b:ee:53:
+                    a7:9c:50:bd:32:0a:67:e2:b6:04:3e:c8:5e:da:fb:
+                    ab:7c:5c:c9:68:3c:5a:f2:c6:5e:b9:22:38:f3:10:
+                    b4:2d:e2:87:12:3a:4a:53:54:6b:92:e6:f1:eb:ba:
+                    47:b8:f1:80:3e:2c:2f:87:13:1e:dc:09:bc:a4:0c:
+                    4f:e2:df:db:53:e0:af:5d:34:b1:39:06:7f:8a:7b:
+                    12:e8:6c:01:e7:ce:d7:b7:a6:ac:3d:b7:ba:af:3f:
+                    46:93
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Basic Constraints: critical
                 CA:TRUE
             X509v3 Key Usage: critical
                 Digital Signature, Certificate Sign, CRL Sign
-    Signature Algorithm: sha1WithRSAEncryption
-         12:68:0b:48:46:69:a0:cc:08:f0:16:c0:b8:2a:66:7a:a8:9d:
-         98:c4:9a:c5:07:02:5c:14:4a:75:3a:36:1f:47:6e:21:c4:6a:
-         cd:05:e6:76:b8:f2:f6:37:34:42:14:88:02:35:f9:69:a5:1e:
-         05:ad:8f:98:8e:32:fb:6d:6b:bf:c4:a3:a0:96:d5:b3:92:ec:
-         48:54:34:fe:92:2f:6a:e7:7c:ad:85:66:3e:bc:4c:07:c1:23:
-         08:a8:7d:b1:7e:3c:b0:e1:f1:9a:00:7b:e8:11:b8:c3:46:55:
-         6a:37:b5:be:25:be:02:79:ed:03:59:3f:25:2d:a5:e1:36:a9:
-         10:d7:7e:53:f9:ea:9d:bf:1e:b8:cb:b1:78:54:1f:34:a8:df:
-         af:75:0b:39:d0:96:c9:65:0c:05:df:7f:78:35:19:51:f5:15:
-         13:35:58:fb:2c:78:53:5a:c9:4d:e2:3b:1b:6e:68:57:59:1b:
-         4d:f4:c0:d7:b4:dc:6c:a3:cd:1f:b4:b8:ce:d1:70:f7:cf:15:
-         e7:9b:c9:35:db:30:8e:ce:4b:f6:58:4e:8c:1f:cb:7f:90:fa:
-         5a:40:70:b7:fb:a0:9c:13:d7:7b:45:f4:7f:3f:ea:79:29:da:
-         15:bb:94:dd:d3:a3:11:95:00:8b:2c:32:a9:33:66:59:50:5a:
-         e9:68:32:b4
+    Signature Algorithm: sha256WithRSAEncryption
+         6c:7f:d4:57:18:85:22:1d:87:15:45:3a:16:0d:df:06:3e:9c:
+         ed:1d:99:7b:78:75:90:5c:8f:d2:38:58:46:3e:2b:d2:69:bc:
+         ba:dd:13:7a:96:15:1f:af:3f:e0:a7:b1:3f:5c:f5:ab:af:ac:
+         65:a0:c3:e3:6b:70:25:53:57:46:3d:f6:c0:78:dc:1f:4c:d2:
+         03:42:d4:32:d0:cd:16:38:06:d1:89:1a:c4:37:2c:15:d9:6b:
+         c2:0e:8d:55:3a:a1:57:99:c7:57:18:d4:c5:13:ca:f7:25:92:
+         85:bc:5d:bb:20:8f:ee:52:8c:6e:61:aa:22:3e:37:a1:71:d9:
+         59:e3:e6:5c:de:71:f8:2a:e8:05:f5:b0:ca:40:9d:6a:24:87:
+         9f:48:69:26:65:ef:ad:6a:fd:2f:b2:38:36:f5:1a:5b:f1:5a:
+         ec:35:7a:a5:08:f7:c8:b7:78:90:e2:b9:32:24:6c:e8:cc:b0:
+         57:9e:ab:a7:06:22:c5:0e:cf:22:73:2f:dc:c7:30:eb:83:5d:
+         81:a4:00:ab:a0:01:3b:ce:7f:d9:c3:cc:28:fc:6b:74:cc:be:
+         62:d2:25:b8:a8:3b:c4:15:c4:bb:71:79:4f:df:7d:73:45:e6:
+         16:a4:41:1a:b5:3c:27:61:62:cf:86:1c:6e:d1:4b:f6:49:0a:
+         bd:3f:15:d0
 -----BEGIN CERTIFICATE-----
-MIIC4jCCAcqgAwIBAgIJAMS8lsLtjUp/MA0GCSqGSIb3DQEBBQUAMB4xHDAaBgNV
-BAMME1BvbGljeSBUZXN0IFJvb3QgQ0EwHhcNMTQwODE0MDI0NzA0WhcNMjQwODEx
-MDI0NzA0WjAeMRwwGgYDVQQDDBNQb2xpY3kgVGVzdCBSb290IENBMIIBIjANBgkq
-hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvmm2FgvUvo2zmE+4ZGRcLzda56hWARmw
-RpG3HQVRV3PHy2gkmCbmtjnbu03QBmsDvAbke0MtSGooPnXIgvgnhvuEqLGQ/rkq
-B9EVyr4KpOGIagEMVyej0a32ADsVmOmABAisJr4MOChEtSzxdcUD3oHs2dpgOPsE
-fzbfcr0rxLs3iNWIFHNR+H/W9ECkBQsmmskjPrrg/HZugWllM8DUjXjURcmQFGDL
-cYghDKmUCUVISiny8l43NIU4NXWpUgbTWO24CatcTRrpYXmgl2SZWJd5cCVNyr8B
-beBsKVEXeUb9MUS+5mpHvh1OdXIIX7LgSeJUV9Xp93Kx7qruQUvp9QIDAQABoyMw
-ITAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQUF
-AAOCAQEAEmgLSEZpoMwI8BbAuCpmeqidmMSaxQcCXBRKdTo2H0duIcRqzQXmdrjy
-9jc0QhSIAjX5aaUeBa2PmI4y+21rv8SjoJbVs5LsSFQ0/pIvaud8rYVmPrxMB8Ej
-CKh9sX48sOHxmgB76BG4w0ZVaje1viW+AnntA1k/JS2l4TapENd+U/nqnb8euMux
-eFQfNKjfr3ULOdCWyWUMBd9/eDUZUfUVEzVY+yx4U1rJTeI7G25oV1kbTfTA17Tc
-bKPNH7S4ztFw988V55vJNdswjs5L9lhOjB/Lf5D6WkBwt/ugnBPXe0X0fz/qeSna
-FbuU3dOjEZUAiywyqTNmWVBa6WgytA==
+MIIC4jCCAcqgAwIBAgIJAMhchM1IzPMWMA0GCSqGSIb3DQEBCwUAMB4xHDAaBgNV
+BAMME1BvbGljeSBUZXN0IFJvb3QgQ0EwHhcNMTcwMjI4MjM1MjM0WhcNMjcwMjI2
+MjM1MjM0WjAeMRwwGgYDVQQDDBNQb2xpY3kgVGVzdCBSb290IENBMIIBIjANBgkq
+hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoOOnr7j6O+5H0lqtIaJxQk6mo8eClLky
+PG0UOWcZZWQfi7XEbYgSLIXi75cE9Z/uE2Wn9YbHWyAd/kdxp6sEaVIP6mxCWHuJ
+MklUFNrTre+4esyMfxYOKrYOe9+l7ib/sMlrZW4VArX0T+Vq4bhFY1X5YQ32J8/z
+EK5KClclXN6xxY6yvPG58pnEJx1TCyt8Kv38c370rUS8i0cjvcFU8+0L7lOnnFC9
+Mgpn4rYEPshe2vurfFzJaDxa8sZeuSI48xC0LeKHEjpKU1Rrkubx67pHuPGAPiwv
+hxMe3Am8pAxP4t/bU+CvXTSxOQZ/insS6GwB587Xt6asPbe6rz9GkwIDAQABoyMw
+ITAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsF
+AAOCAQEAbH/UVxiFIh2HFUU6Fg3fBj6c7R2Ze3h1kFyP0jhYRj4r0mm8ut0TepYV
+H68/4KexP1z1q6+sZaDD42twJVNXRj32wHjcH0zSA0LUMtDNFjgG0YkaxDcsFdlr
+wg6NVTqhV5nHVxjUxRPK9yWShbxduyCP7lKMbmGqIj43oXHZWePmXN5x+CroBfWw
+ykCdaiSHn0hpJmXvrWr9L7I4NvUaW/Fa7DV6pQj3yLd4kOK5MiRs6MywV56rpwYi
+xQ7PInMv3Mcw64NdgaQAq6ABO85/2cPMKPxrdMy+YtIluKg7xBXEu3F5T999c0Xm
+FqRBGrU8J2Fiz4YcbtFL9kkKvT8V0A==
 -----END CERTIFICATE-----
diff --git a/net/data/ssl/certificates/multi-root-A-by-B.pem b/net/data/ssl/certificates/multi-root-A-by-B.pem
index 01f99c2..451345d 100644
--- a/net/data/ssl/certificates/multi-root-A-by-B.pem
+++ b/net/data/ssl/certificates/multi-root-A-by-B.pem
@@ -1,29 +1,29 @@
 -----BEGIN RSA PRIVATE KEY-----
-MIIEowIBAAKCAQEAyCccGYHApzCTAxz4IbgviiK0iQ/asUCV39xGU/xvNiZmWlNt
-RXjCORaaP4KLusWweKgYvNWnkqXmrOIMgdCU5QzsXgMMF8U1Knurhuu/6GIKj7Al
-snD1EYwWT8F2ROV16JNP6efE5EIKCL5zLMuPc2pAd+szYKy+xSf9sU+ISxWvmP0y
-U66wKgyy9QXzOgYNblz+g/zjYK6ZjqEhwnIC5vRJV+aRMS6+kqGt+HExZHQQM9Cn
-DO0Yx7JQcfy5tq6VoI2sHzzVeaepiFC2As1oYCRFm7bpggjZnNR+KX0r2a5Xf2Jq
-VpaLSjOeX5OCsNEFAybNFfSHf2qa3+kBtdTJEQIDAQABAoIBAHadrupy2fB7OfSz
-W13oYMwVazZ7HdjD9M45JbiqNmI5+Zh4Lp7oRPo+KeWPgS2L8NxgimCGogunpAA6
-6ryYF1VzBjVkyurfZXWq2ulXl2Cpkaa79ms8xA/FHIfhmCyWa/0MKGTvhODdPkMW
-Uv1uGbKFenVW/xjA50HCRHerMZOE1yBaBzrAOGqLm4E/7snbZJ3K5Sx88mu9vAnA
-LBHMiqYwf4E9TJW+2AzDtlTI02/UbcQc4MDgRJc1YQSPz4pdtKbA3IvdDhXdsDCr
-Tum2gCpeUZS4zmXW6NcOBAHvrLdU8sEsodALCZ58hwkTU9YlqKyYE+DbuDd+3H5a
-3WIQbb0CgYEA6ZoLha/chlExbXr/5VcmiDfX/IRjAebG7uHMGC+QlSMxNxUGCuge
-kvw5+AkSsKdwHeSgr426SF3gPAwafK5KiTO4NoaD2pXFOvu5Z0Mpw4iT3kdTk/iO
-o2zTz4abEA0kQaqlhIbD5RrI5zU3K49BH8CkS+Kr5mCqtPu2b1aDac8CgYEA21gH
-/R1eTo4/0lBt+P4+4w8RMtt5Ky6rsZzSC87zJKznAKoGmo2rWCQKcxbZntznsuW3
-LN5MPYXXKqugp3fXebnRJYwBBE9HO39Cl5vb3l2EIYVRwspVeUs9KeTlt2FaiqQ1
-yE+s75bXFh9e3ztj4vOAWKGXi/KI2PHTdfo4tx8CgYEA5eX3BQDIdWAe1vJAOYMF
-pvXemOPpVIu8qIiMBhl5n2zdGKqWIdHDlUCqBFNZk4WVr7W79knzVRkef7ohrycQ
-r+q4luDXjx3q11u5YckVpxwY+p8TwALUzj1iT1DX9noYfo/lCYJf9G/h3Lngq/v2
-SbubdhuEtdvY5Pj82KI5/r0CgYAKDBxBkejR/F4cCicfcrX6vKPzCm6gdcDTn/VX
-KSGmGm1ycFdhGQAyR2RbJT7OshvC7BbZ7UzcvJbAk6AGS80I/GQCLkmVovQGW6v3
-OeJ2ax40UuEN5SrJJZMlqiCDp+f31dHI3S10xBoSH1m/K/9FVBYa+Tvx4yg1l84x
-50ZVzQKBgB6sEgCK7Q4HwOrSVyLvGjABZC41fuZSl58DB1bKdTtXq2ASP1igzmbR
-KEvawdUFqysM1TSz2F+QL4X393VVlSKi69w3LeORcMdOtbew2Rn7msBAHR4JO9sP
-dIdM/ccKebf1tgaTgI+c12yg+e+w7dey1Og0iPtcuMg3TumFX5q3
+MIIEowIBAAKCAQEApBiGPwljnNTABkWlkX/np7g9x/8N6Dn1QyenRCo7UwPjzRMj
+Rl/gJ/CjeiWCsFK7A0+Z4ywbb1QFD39PdPmtsoiFQ2MGrJHxGbfaekJoamil4AJE
+I+vRBQ09WDHuuiCeFhH1rrXDIcyE5xrSwox+RJM2vWwMBzXyTlc/s88hWv8WAulh
+9MxKWiTaVfzG2kTWtypOMb+ggCRV7Vy8a4QSpAPMssLb7x4IvaO/7/w9Uzi5AIrW
+QBrM8mqr50tnHK7/bUMSCMaXS3Pfhc8qpW7OIgLLY2w/AKo7sIeb1RMJMky9cXn/
+BLGajS2gCmXVHlPE6w4UwLnzj29ktB0Rp0DnYQIDAQABAoIBAGRqPXxFmpdV+Uvd
+QrwOsQuJSwUfprr8/IDjuw+TaEocj0Hm/CcMdHb8Yo1Uduy/M4GLLHg/fWpa193r
+4guK3ifqMuJRrrvbctZyE1fNW2gCMb8qo9f3bijROUDHDXcIjrSiuNz4jTgZlxp0
+55P1tS7xhwXTIGkpMeWOroSxs4+incyXj7yD5Wr9xk/01A+W463jPZM69aRzvOAb
+mfxh67PYu6InLbTkNm3iWo7jXSEQbIFv6bPeboOXaxsa9Beo5NTPMaV7ex2mR0m0
+yvZStCXtvwu9wkgvyameX9L2eBJWaMdL9LM9S5LVNrkFngJTbCd+qSYBd4axQ1dP
+nYhuv4ECgYEA2sSzTLywORnUyM4mRZnrQVakqaPy9AuZLIHHcs5mQifgezb99qm+
+GBQTV+xQwwPPPLLxuBICIlYUVl4TP82EUffRog0+eAPkqRuUv9jX8MTLFVzjicD/
+O2LTRW9wyvpu7wOKL2f6Tf+kYjBxKmHAxAZTncBsFkXOyjZDS4DIwdUCgYEAwAXZ
+kpAtavvCmpwKXRFMVhMCRpmXthxXeSmm/piY/O16mHLQfR5zBJ3DNyKUKlyaX1YM
+DNgZKXLiREJZtbgT+Z1aHAybRMFyr37VU0nSMGU5G/I6ysLYsc3iCI/gk6YHM7Xc
+OgqZleJ0s+EGwDx9DeWhLrYWN4W6e0kudrB6CV0CgYBAaI8ddaQwe5FxOXh9H27r
+ArZiF5ntDgkf2Gm/PFNRAOqPfEZTO/ByqF51kWbJs7Js/YY7Glo0f8FnGDV0oG5n
+r52xp1KQBR1qSGuH/DC/e0ELXhjDsuWyN0tacw/zQr4sco9Zm7RPCIf+PKLkxnj5
+fZ9an49zE0RptoYjkZwJrQKBgE29EIxJWlnJestlCL0M176xC2bRn53Wc4NV3YmM
+9cLP0aYONWGyBhaEWBfmI93Sh5y5FT/N7MHfBMNlqTPsRgn0LhrU77cyKd/qlSqW
+5EU7dZdexXZ404mINE4LEXw05w2EPpgw2mTXvS9llnoVAvuxT0O969imhwyKYAkl
+AQLxAoGBAKHMhs0tYdyWuH2J1zokddjOH0uGFkoZxhQmgVPC/WlTg05ClPVSNX5p
+pZcX9Ouk+kvSb8UCWf/ovAwSN66Ri6AmbLt+W8Ibt9+Q9NMeb6XVppWaRTa2b9PX
+WKNuu7TLrunx6XJw9NqXhAecreu7s4FMyn9GnhQ2H5LeJTb1C80D
 -----END RSA PRIVATE KEY-----
 Certificate:
     Data:
@@ -32,76 +32,78 @@
     Signature Algorithm: sha256WithRSAEncryption
         Issuer: CN=B CA - Multi-root
         Validity
-            Not Before: Mar 11 01:37:16 2016 GMT
-            Not After : Mar  9 01:37:16 2026 GMT
+            Not Before: Feb 28 23:46:47 2017 GMT
+            Not After : Feb 26 23:46:47 2027 GMT
         Subject: C=US, ST=California, L=Mountain View, O=Test CA, CN=127.0.0.1
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
                 Public-Key: (2048 bit)
                 Modulus:
-                    00:c8:27:1c:19:81:c0:a7:30:93:03:1c:f8:21:b8:
-                    2f:8a:22:b4:89:0f:da:b1:40:95:df:dc:46:53:fc:
-                    6f:36:26:66:5a:53:6d:45:78:c2:39:16:9a:3f:82:
-                    8b:ba:c5:b0:78:a8:18:bc:d5:a7:92:a5:e6:ac:e2:
-                    0c:81:d0:94:e5:0c:ec:5e:03:0c:17:c5:35:2a:7b:
-                    ab:86:eb:bf:e8:62:0a:8f:b0:25:b2:70:f5:11:8c:
-                    16:4f:c1:76:44:e5:75:e8:93:4f:e9:e7:c4:e4:42:
-                    0a:08:be:73:2c:cb:8f:73:6a:40:77:eb:33:60:ac:
-                    be:c5:27:fd:b1:4f:88:4b:15:af:98:fd:32:53:ae:
-                    b0:2a:0c:b2:f5:05:f3:3a:06:0d:6e:5c:fe:83:fc:
-                    e3:60:ae:99:8e:a1:21:c2:72:02:e6:f4:49:57:e6:
-                    91:31:2e:be:92:a1:ad:f8:71:31:64:74:10:33:d0:
-                    a7:0c:ed:18:c7:b2:50:71:fc:b9:b6:ae:95:a0:8d:
-                    ac:1f:3c:d5:79:a7:a9:88:50:b6:02:cd:68:60:24:
-                    45:9b:b6:e9:82:08:d9:9c:d4:7e:29:7d:2b:d9:ae:
-                    57:7f:62:6a:56:96:8b:4a:33:9e:5f:93:82:b0:d1:
-                    05:03:26:cd:15:f4:87:7f:6a:9a:df:e9:01:b5:d4:
-                    c9:11
+                    00:a4:18:86:3f:09:63:9c:d4:c0:06:45:a5:91:7f:
+                    e7:a7:b8:3d:c7:ff:0d:e8:39:f5:43:27:a7:44:2a:
+                    3b:53:03:e3:cd:13:23:46:5f:e0:27:f0:a3:7a:25:
+                    82:b0:52:bb:03:4f:99:e3:2c:1b:6f:54:05:0f:7f:
+                    4f:74:f9:ad:b2:88:85:43:63:06:ac:91:f1:19:b7:
+                    da:7a:42:68:6a:68:a5:e0:02:44:23:eb:d1:05:0d:
+                    3d:58:31:ee:ba:20:9e:16:11:f5:ae:b5:c3:21:cc:
+                    84:e7:1a:d2:c2:8c:7e:44:93:36:bd:6c:0c:07:35:
+                    f2:4e:57:3f:b3:cf:21:5a:ff:16:02:e9:61:f4:cc:
+                    4a:5a:24:da:55:fc:c6:da:44:d6:b7:2a:4e:31:bf:
+                    a0:80:24:55:ed:5c:bc:6b:84:12:a4:03:cc:b2:c2:
+                    db:ef:1e:08:bd:a3:bf:ef:fc:3d:53:38:b9:00:8a:
+                    d6:40:1a:cc:f2:6a:ab:e7:4b:67:1c:ae:ff:6d:43:
+                    12:08:c6:97:4b:73:df:85:cf:2a:a5:6e:ce:22:02:
+                    cb:63:6c:3f:00:aa:3b:b0:87:9b:d5:13:09:32:4c:
+                    bd:71:79:ff:04:b1:9a:8d:2d:a0:0a:65:d5:1e:53:
+                    c4:eb:0e:14:c0:b9:f3:8f:6f:64:b4:1d:11:a7:40:
+                    e7:61
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Basic Constraints: critical
                 CA:FALSE
             X509v3 Subject Key Identifier: 
-                FB:91:A9:5F:BC:27:81:98:55:30:BF:57:32:4D:B9:DA:56:DD:52:2C
+                28:6F:58:36:8F:1B:C5:99:18:5B:DC:A5:86:AF:89:F2:B4:3E:AF:51
             X509v3 Authority Key Identifier: 
-                keyid:90:CB:53:EE:36:0A:5A:B0:93:38:C9:11:B7:AC:FD:27:71:99:DC:81
+                keyid:D0:8D:1F:B2:BC:29:96:73:EF:0C:7A:C2:A4:06:96:CF:D5:8C:31:DB
 
             X509v3 Extended Key Usage: 
                 TLS Web Server Authentication, TLS Web Client Authentication
+            X509v3 Subject Alternative Name: 
+                IP Address:127.0.0.1
     Signature Algorithm: sha256WithRSAEncryption
-         b9:31:7a:95:b2:ba:3a:b4:f1:16:76:df:eb:d5:b9:af:67:b1:
-         9d:8a:27:04:9b:61:6f:42:3f:c2:b3:cd:65:c4:86:cb:90:fb:
-         9d:3a:ed:fc:b8:74:da:d7:6a:6c:2f:17:68:d1:73:58:f1:a2:
-         bb:8f:d6:b0:a8:7f:b6:a8:b0:74:d1:ea:c4:62:ed:bc:1e:ef:
-         02:6b:d5:e8:2d:15:78:16:1e:90:fa:f4:29:5a:a8:43:ad:d2:
-         58:40:b4:1c:60:4e:cd:bc:6f:1a:39:e4:46:b2:58:93:96:5a:
-         a8:a4:c4:31:73:ed:89:c4:81:27:e1:4c:66:20:7c:27:c4:f9:
-         61:ff:d1:d5:a5:02:93:4c:06:fa:15:33:7a:1f:5f:eb:29:b2:
-         b5:6a:cd:7e:d6:d7:b7:51:a7:01:2f:22:9f:9e:7e:81:98:c4:
-         72:11:36:2c:e7:c6:d0:f0:7d:98:36:ea:b7:a0:aa:13:8f:6e:
-         ae:41:59:9b:e6:c9:bc:9c:e8:93:f5:0c:4e:ca:b4:dd:e3:01:
-         fe:23:6e:fb:fa:b3:61:66:58:f5:fc:07:16:1d:a9:52:ec:a0:
-         29:61:a4:39:ed:41:50:a3:a2:33:72:0e:3c:03:e1:0a:1a:1a:
-         cf:22:73:09:d7:ea:e8:15:fc:73:3c:d4:4e:34:6c:b4:18:94:
-         c4:d3:6e:12
+         07:8f:f9:c6:33:3c:bc:74:20:21:92:46:7a:c5:df:76:18:47:
+         63:0c:5e:e8:f3:97:ec:37:83:0b:4d:a4:1c:6b:0b:a2:28:db:
+         5c:17:d9:91:77:00:4a:db:46:f9:68:ec:2a:f8:b5:82:0c:00:
+         d1:88:0c:7c:b4:2d:e9:48:f5:a2:9d:a9:d5:bb:db:9d:56:96:
+         c5:6c:46:da:23:a3:66:80:a5:9b:93:d0:df:9c:00:75:ac:48:
+         ea:48:b4:22:ee:ff:db:eb:bb:8f:f0:de:16:a1:99:98:85:4c:
+         b3:66:dd:22:96:96:97:48:ae:8a:2d:e9:a5:1c:5c:d9:dd:31:
+         3f:58:7c:bb:2b:db:86:6a:53:e5:af:6d:85:3a:ca:92:5d:56:
+         e2:02:90:d7:eb:98:0f:d8:ba:2a:d1:26:bb:82:5b:80:d5:2d:
+         52:d7:40:4d:0d:0d:1e:fe:c2:89:be:e2:80:4d:cd:91:dc:f3:
+         fa:19:25:3e:ba:a8:cf:48:d3:b6:35:a5:96:6e:a5:12:d1:65:
+         65:a9:92:6b:d0:fc:05:25:7c:fb:76:48:38:15:7e:4f:95:03:
+         b0:c3:55:89:bc:59:be:de:3c:fb:4b:5a:f1:3b:00:c1:03:59:
+         6c:b3:8b:21:7e:84:75:30:19:8c:19:f6:99:40:ec:87:43:3b:
+         89:d0:f5:6d
 -----BEGIN CERTIFICATE-----
-MIIDZzCCAk+gAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwHDEaMBgGA1UEAwwRQiBD
-QSAtIE11bHRpLXJvb3QwHhcNMTYwMzExMDEzNzE2WhcNMjYwMzA5MDEzNzE2WjBg
+MIIDeTCCAmGgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwHDEaMBgGA1UEAwwRQiBD
+QSAtIE11bHRpLXJvb3QwHhcNMTcwMjI4MjM0NjQ3WhcNMjcwMjI2MjM0NjQ3WjBg
 MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91
 bnRhaW4gVmlldzEQMA4GA1UECgwHVGVzdCBDQTESMBAGA1UEAwwJMTI3LjAuMC4x
-MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyCccGYHApzCTAxz4Ibgv
-iiK0iQ/asUCV39xGU/xvNiZmWlNtRXjCORaaP4KLusWweKgYvNWnkqXmrOIMgdCU
-5QzsXgMMF8U1Knurhuu/6GIKj7AlsnD1EYwWT8F2ROV16JNP6efE5EIKCL5zLMuP
-c2pAd+szYKy+xSf9sU+ISxWvmP0yU66wKgyy9QXzOgYNblz+g/zjYK6ZjqEhwnIC
-5vRJV+aRMS6+kqGt+HExZHQQM9CnDO0Yx7JQcfy5tq6VoI2sHzzVeaepiFC2As1o
-YCRFm7bpggjZnNR+KX0r2a5Xf2JqVpaLSjOeX5OCsNEFAybNFfSHf2qa3+kBtdTJ
-EQIDAQABo28wbTAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBT7kalfvCeBmFUwv1cy
-TbnaVt1SLDAfBgNVHSMEGDAWgBSQy1PuNgpasJM4yRG3rP0ncZncgTAdBgNVHSUE
-FjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBALkxepWy
-ujq08RZ23+vVua9nsZ2KJwSbYW9CP8KzzWXEhsuQ+5067fy4dNrXamwvF2jRc1jx
-oruP1rCof7aosHTR6sRi7bwe7wJr1egtFXgWHpD69ClaqEOt0lhAtBxgTs28bxo5
-5EayWJOWWqikxDFz7YnEgSfhTGYgfCfE+WH/0dWlApNMBvoVM3ofX+spsrVqzX7W
-17dRpwEvIp+efoGYxHIRNiznxtDwfZg26regqhOPbq5BWZvmybyc6JP1DE7KtN3j
-Af4jbvv6s2FmWPX8BxYdqVLsoClhpDntQVCjojNyDjwD4QoaGs8icwnX6ugV/HM8
-1E40bLQYlMTTbhI=
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApBiGPwljnNTABkWlkX/n
+p7g9x/8N6Dn1QyenRCo7UwPjzRMjRl/gJ/CjeiWCsFK7A0+Z4ywbb1QFD39PdPmt
+soiFQ2MGrJHxGbfaekJoamil4AJEI+vRBQ09WDHuuiCeFhH1rrXDIcyE5xrSwox+
+RJM2vWwMBzXyTlc/s88hWv8WAulh9MxKWiTaVfzG2kTWtypOMb+ggCRV7Vy8a4QS
+pAPMssLb7x4IvaO/7/w9Uzi5AIrWQBrM8mqr50tnHK7/bUMSCMaXS3Pfhc8qpW7O
+IgLLY2w/AKo7sIeb1RMJMky9cXn/BLGajS2gCmXVHlPE6w4UwLnzj29ktB0Rp0Dn
+YQIDAQABo4GAMH4wDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUKG9YNo8bxZkYW9yl
+hq+J8rQ+r1EwHwYDVR0jBBgwFoAU0I0fsrwplnPvDHrCpAaWz9WMMdswHQYDVR0l
+BBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA8GA1UdEQQIMAaHBH8AAAEwDQYJKoZI
+hvcNAQELBQADggEBAAeP+cYzPLx0ICGSRnrF33YYR2MMXujzl+w3gwtNpBxrC6Io
+21wX2ZF3AErbRvlo7Cr4tYIMANGIDHy0LelI9aKdqdW7251WlsVsRtojo2aApZuT
+0N+cAHWsSOpItCLu/9vru4/w3hahmZiFTLNm3SKWlpdIroot6aUcXNndMT9YfLsr
+24ZqU+WvbYU6ypJdVuICkNfrmA/YuirRJruCW4DVLVLXQE0NDR7+wom+4oBNzZHc
+8/oZJT66qM9I07Y1pZZupRLRZWWpkmvQ/AUlfPt2SDgVfk+VA7DDVYm8Wb7ePPtL
+WvE7AMEDWWyziyF+hHUwGYwZ9plA7IdDO4nQ9W0=
 -----END CERTIFICATE-----
diff --git a/net/data/ssl/certificates/multi-root-B-by-C.pem b/net/data/ssl/certificates/multi-root-B-by-C.pem
index 5731bb1..98685b3 100644
--- a/net/data/ssl/certificates/multi-root-B-by-C.pem
+++ b/net/data/ssl/certificates/multi-root-B-by-C.pem
@@ -12,63 +12,63 @@
             Public Key Algorithm: rsaEncryption
                 Public-Key: (2048 bit)
                 Modulus:
-                    00:ca:e9:f3:21:f4:a0:e7:ba:82:8c:7f:b3:98:44:
-                    20:4a:9a:8b:f9:e5:0c:99:c4:22:72:f7:57:7c:1e:
-                    cc:56:4c:c3:f5:fd:1e:90:a5:1c:bf:2c:c4:c4:29:
-                    29:38:cc:26:9e:1a:1d:e3:e4:db:97:58:35:14:e8:
-                    e2:db:37:05:1c:32:f7:bb:19:22:c2:37:3f:01:76:
-                    8c:17:23:ca:fc:10:69:b4:d1:74:27:b6:10:7e:b7:
-                    c1:07:a2:a1:af:18:4d:5c:2e:13:72:a9:fb:64:b1:
-                    e7:9f:49:41:3c:dc:b8:5f:94:e6:68:05:a5:1f:c8:
-                    56:84:e2:e5:6a:84:71:9c:b8:ac:3e:ec:8e:0c:d2:
-                    f2:5f:11:fd:f4:7f:40:a7:3b:08:01:bb:fd:6f:d0:
-                    a9:16:1d:14:a1:28:20:30:98:ba:1e:22:4e:5b:09:
-                    b9:c1:df:17:60:1b:80:43:97:49:69:cd:6a:4e:58:
-                    08:9c:dc:29:57:3f:1b:bf:d8:5f:32:94:ae:97:b2:
-                    d4:8d:50:1a:d1:8b:03:84:00:fd:87:d9:2e:ed:91:
-                    3d:3f:b7:89:54:46:0a:cd:db:10:62:80:47:60:21:
-                    b3:1d:0e:bc:41:4d:86:d4:9d:52:1b:53:82:1a:9f:
-                    46:91:98:1e:ed:9f:da:69:16:64:24:1c:de:f8:b3:
-                    34:69
+                    00:ca:6c:54:ab:3c:54:33:6c:d7:04:c4:4b:c4:39:
+                    32:db:7a:49:e4:e1:e7:60:c7:35:33:08:59:ba:62:
+                    bf:49:d6:05:1f:07:b8:b6:bd:38:2f:6b:a7:e5:8d:
+                    de:79:27:d8:36:58:92:69:cc:db:8e:6a:89:b4:79:
+                    ab:cf:98:53:08:12:17:9e:51:15:bc:e7:8f:e5:93:
+                    d9:1a:2e:68:a9:93:3c:d3:7a:75:a4:5c:c2:fc:16:
+                    9b:ba:df:49:5d:73:65:ec:b0:cc:1e:ba:cc:98:39:
+                    d1:4e:b2:d6:5f:e8:7f:24:1a:fa:56:b0:0d:33:46:
+                    22:56:4f:5c:f3:16:ad:55:8a:62:3c:bc:50:c2:3a:
+                    58:3e:70:4d:5a:df:99:ec:c7:a6:2c:8f:2a:a5:2e:
+                    11:b8:58:c5:d5:e8:43:2f:40:a5:20:80:32:2a:76:
+                    5e:06:07:48:6d:44:60:ba:21:72:61:e2:1a:ec:64:
+                    5d:72:72:f1:21:9d:04:2f:61:35:0b:2f:f0:c0:fe:
+                    52:b8:c4:41:9c:b6:13:58:21:81:e3:28:27:4d:6c:
+                    24:a3:20:fb:0f:9c:d4:4f:34:3a:d0:d1:08:84:c4:
+                    40:71:44:4f:e8:be:c5:1f:5d:1c:34:64:0b:6c:1c:
+                    24:fa:a9:83:49:c6:f5:4d:7f:63:c0:1a:a9:77:8a:
+                    c0:43
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Basic Constraints: critical
                 CA:TRUE
             X509v3 Subject Key Identifier: 
-                90:CB:53:EE:36:0A:5A:B0:93:38:C9:11:B7:AC:FD:27:71:99:DC:81
+                D0:8D:1F:B2:BC:29:96:73:EF:0C:7A:C2:A4:06:96:CF:D5:8C:31:DB
             X509v3 Key Usage: critical
                 Certificate Sign, CRL Sign
     Signature Algorithm: sha256WithRSAEncryption
-         97:cd:ae:5a:26:f4:25:f6:c0:8b:08:d8:df:82:35:d8:76:f3:
-         5d:cc:99:bd:ac:70:c9:41:e0:24:c8:fd:e6:4e:41:2c:d4:69:
-         8d:08:25:fd:f3:32:3a:58:0b:d3:58:9c:81:51:bf:97:a4:bc:
-         00:18:1c:4f:1c:54:04:63:e3:72:87:f4:dc:9e:7b:dc:da:5d:
-         e1:ef:59:6b:f0:1f:3d:0c:11:55:1e:9a:1a:d8:8d:bc:7b:18:
-         b7:4f:92:1c:68:73:82:ec:f3:69:48:0a:86:40:4a:a5:6f:ae:
-         8f:10:2e:12:0b:e8:7e:b9:bc:d7:26:f0:cf:f4:0f:5b:77:f2:
-         ff:77:28:b4:5f:5e:ef:65:08:21:b8:f9:1e:56:b9:69:3b:c4:
-         7f:01:88:c9:7c:ca:d0:e2:df:e5:5e:8d:e9:2e:7d:4a:78:04:
-         8b:c1:dc:d4:58:ac:90:fc:5c:8e:48:2b:60:99:63:37:3f:e5:
-         61:da:8f:58:9f:4d:0a:ee:6c:8d:bc:1f:7e:c4:be:0f:32:4b:
-         11:7a:28:bf:dd:d0:a0:40:42:a8:43:4d:0b:2f:01:0e:73:de:
-         1b:a6:df:49:57:58:89:57:c0:23:76:83:f0:9a:0e:83:d9:9b:
-         cb:eb:ac:3f:89:d1:e8:3c:3e:f1:d5:80:0c:38:18:02:5c:5f:
-         e5:68:5e:cf
+         1e:16:7c:d7:d1:ee:63:a9:a2:b1:87:2c:8b:1e:d3:cf:51:14:
+         ed:12:0b:ec:67:2b:7f:3b:0e:8e:3c:50:bb:d1:dc:3b:40:1a:
+         ec:44:30:c4:f6:65:c2:c3:5d:d8:cb:c2:6c:13:2e:5a:2d:76:
+         c6:6b:5d:65:a5:7e:c2:bf:cb:fc:b1:50:b0:43:47:fc:a3:7b:
+         07:d1:77:50:4f:d2:53:98:8f:a2:00:97:13:d9:b7:83:2e:d9:
+         c4:2a:e6:b1:fc:2d:6c:ce:d1:61:73:aa:40:e0:ce:87:74:43:
+         a2:f7:b5:d9:5f:46:79:97:28:c4:de:15:60:3b:3e:3f:3d:1d:
+         14:f4:87:ef:b9:08:09:2a:fb:d0:d5:1b:4f:77:f9:0d:c9:4b:
+         23:32:1c:06:04:a6:83:aa:00:9c:70:c2:2b:01:42:1e:f6:d6:
+         d3:5c:f9:a8:b7:84:9e:44:12:9a:9f:a8:2a:89:56:69:a6:2f:
+         e9:ee:67:e9:7e:32:b5:ef:6b:4e:f0:12:23:fa:85:3e:03:59:
+         94:db:88:99:04:55:c4:d1:df:df:c6:e2:fd:61:c5:f6:af:dc:
+         4c:e4:52:8f:f2:c8:07:39:dd:99:33:49:85:1e:df:e1:1f:08:
+         6b:e0:d2:1b:93:db:32:05:4b:39:ee:b3:f1:b6:af:18:07:a7:
+         24:9c:1e:75
 -----BEGIN CERTIFICATE-----
 MIIC9jCCAd6gAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwHDEaMBgGA1UEAwwRQyBD
 QSAtIE11bHRpLXJvb3QwHhcNMTYwMTA0MDAwMDAwWhcNMjYwMTAyMDAwMDAwWjAc
 MRowGAYDVQQDDBFCIENBIC0gTXVsdGktcm9vdDCCASIwDQYJKoZIhvcNAQEBBQAD
-ggEPADCCAQoCggEBAMrp8yH0oOe6gox/s5hEIEqai/nlDJnEInL3V3wezFZMw/X9
-HpClHL8sxMQpKTjMJp4aHePk25dYNRTo4ts3BRwy97sZIsI3PwF2jBcjyvwQabTR
-dCe2EH63wQeioa8YTVwuE3Kp+2Sx559JQTzcuF+U5mgFpR/IVoTi5WqEcZy4rD7s
-jgzS8l8R/fR/QKc7CAG7/W/QqRYdFKEoIDCYuh4iTlsJucHfF2AbgEOXSWnNak5Y
-CJzcKVc/G7/YXzKUrpey1I1QGtGLA4QA/YfZLu2RPT+3iVRGCs3bEGKAR2Ahsx0O
-vEFNhtSdUhtTghqfRpGYHu2f2mkWZCQc3vizNGkCAwEAAaNCMEAwDwYDVR0TAQH/
-BAUwAwEB/zAdBgNVHQ4EFgQUkMtT7jYKWrCTOMkRt6z9J3GZ3IEwDgYDVR0PAQH/
-BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IBAQCXza5aJvQl9sCLCNjfgjXYdvNdzJm9
-rHDJQeAkyP3mTkEs1GmNCCX98zI6WAvTWJyBUb+XpLwAGBxPHFQEY+Nyh/Tcnnvc
-2l3h71lr8B89DBFVHpoa2I28exi3T5IcaHOC7PNpSAqGQEqlb66PEC4SC+h+ubzX
-JvDP9A9bd/L/dyi0X17vZQghuPkeVrlpO8R/AYjJfMrQ4t/lXo3pLn1KeASLwdzU
-WKyQ/FyOSCtgmWM3P+Vh2o9Yn00K7myNvB9+xL4PMksReii/3dCgQEKoQ00LLwEO
-c94bpt9JV1iJV8AjdoPwmg6D2ZvL66w/idHoPD7x1YAMOBgCXF/laF7P
+ggEPADCCAQoCggEBAMpsVKs8VDNs1wTES8Q5Mtt6SeTh52DHNTMIWbpiv0nWBR8H
+uLa9OC9rp+WN3nkn2DZYkmnM245qibR5q8+YUwgSF55RFbznj+WT2RouaKmTPNN6
+daRcwvwWm7rfSV1zZeywzB66zJg50U6y1l/ofyQa+lawDTNGIlZPXPMWrVWKYjy8
+UMI6WD5wTVrfmezHpiyPKqUuEbhYxdXoQy9ApSCAMip2XgYHSG1EYLohcmHiGuxk
+XXJy8SGdBC9hNQsv8MD+UrjEQZy2E1ghgeMoJ01sJKMg+w+c1E80OtDRCITEQHFE
+T+i+xR9dHDRkC2wcJPqpg0nG9U1/Y8AaqXeKwEMCAwEAAaNCMEAwDwYDVR0TAQH/
+BAUwAwEB/zAdBgNVHQ4EFgQU0I0fsrwplnPvDHrCpAaWz9WMMdswDgYDVR0PAQH/
+BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IBAQAeFnzX0e5jqaKxhyyLHtPPURTtEgvs
+Zyt/Ow6OPFC70dw7QBrsRDDE9mXCw13Yy8JsEy5aLXbGa11lpX7Cv8v8sVCwQ0f8
+o3sH0XdQT9JTmI+iAJcT2beDLtnEKuax/C1sztFhc6pA4M6HdEOi97XZX0Z5lyjE
+3hVgOz4/PR0U9IfvuQgJKvvQ1RtPd/kNyUsjMhwGBKaDqgCccMIrAUIe9tbTXPmo
+t4SeRBKan6gqiVZppi/p7mfpfjK172tO8BIj+oU+A1mU24iZBFXE0d/fxuL9YcX2
+r9xM5FKP8sgHOd2ZM0mFHt/hHwhr4NIbk9syBUs57rPxtq8YB6cknB51
 -----END CERTIFICATE-----
diff --git a/net/data/ssl/certificates/multi-root-B-by-F.pem b/net/data/ssl/certificates/multi-root-B-by-F.pem
index d760580..bcaa0da 100644
--- a/net/data/ssl/certificates/multi-root-B-by-F.pem
+++ b/net/data/ssl/certificates/multi-root-B-by-F.pem
@@ -12,63 +12,63 @@
             Public Key Algorithm: rsaEncryption
                 Public-Key: (2048 bit)
                 Modulus:
-                    00:ca:e9:f3:21:f4:a0:e7:ba:82:8c:7f:b3:98:44:
-                    20:4a:9a:8b:f9:e5:0c:99:c4:22:72:f7:57:7c:1e:
-                    cc:56:4c:c3:f5:fd:1e:90:a5:1c:bf:2c:c4:c4:29:
-                    29:38:cc:26:9e:1a:1d:e3:e4:db:97:58:35:14:e8:
-                    e2:db:37:05:1c:32:f7:bb:19:22:c2:37:3f:01:76:
-                    8c:17:23:ca:fc:10:69:b4:d1:74:27:b6:10:7e:b7:
-                    c1:07:a2:a1:af:18:4d:5c:2e:13:72:a9:fb:64:b1:
-                    e7:9f:49:41:3c:dc:b8:5f:94:e6:68:05:a5:1f:c8:
-                    56:84:e2:e5:6a:84:71:9c:b8:ac:3e:ec:8e:0c:d2:
-                    f2:5f:11:fd:f4:7f:40:a7:3b:08:01:bb:fd:6f:d0:
-                    a9:16:1d:14:a1:28:20:30:98:ba:1e:22:4e:5b:09:
-                    b9:c1:df:17:60:1b:80:43:97:49:69:cd:6a:4e:58:
-                    08:9c:dc:29:57:3f:1b:bf:d8:5f:32:94:ae:97:b2:
-                    d4:8d:50:1a:d1:8b:03:84:00:fd:87:d9:2e:ed:91:
-                    3d:3f:b7:89:54:46:0a:cd:db:10:62:80:47:60:21:
-                    b3:1d:0e:bc:41:4d:86:d4:9d:52:1b:53:82:1a:9f:
-                    46:91:98:1e:ed:9f:da:69:16:64:24:1c:de:f8:b3:
-                    34:69
+                    00:ca:6c:54:ab:3c:54:33:6c:d7:04:c4:4b:c4:39:
+                    32:db:7a:49:e4:e1:e7:60:c7:35:33:08:59:ba:62:
+                    bf:49:d6:05:1f:07:b8:b6:bd:38:2f:6b:a7:e5:8d:
+                    de:79:27:d8:36:58:92:69:cc:db:8e:6a:89:b4:79:
+                    ab:cf:98:53:08:12:17:9e:51:15:bc:e7:8f:e5:93:
+                    d9:1a:2e:68:a9:93:3c:d3:7a:75:a4:5c:c2:fc:16:
+                    9b:ba:df:49:5d:73:65:ec:b0:cc:1e:ba:cc:98:39:
+                    d1:4e:b2:d6:5f:e8:7f:24:1a:fa:56:b0:0d:33:46:
+                    22:56:4f:5c:f3:16:ad:55:8a:62:3c:bc:50:c2:3a:
+                    58:3e:70:4d:5a:df:99:ec:c7:a6:2c:8f:2a:a5:2e:
+                    11:b8:58:c5:d5:e8:43:2f:40:a5:20:80:32:2a:76:
+                    5e:06:07:48:6d:44:60:ba:21:72:61:e2:1a:ec:64:
+                    5d:72:72:f1:21:9d:04:2f:61:35:0b:2f:f0:c0:fe:
+                    52:b8:c4:41:9c:b6:13:58:21:81:e3:28:27:4d:6c:
+                    24:a3:20:fb:0f:9c:d4:4f:34:3a:d0:d1:08:84:c4:
+                    40:71:44:4f:e8:be:c5:1f:5d:1c:34:64:0b:6c:1c:
+                    24:fa:a9:83:49:c6:f5:4d:7f:63:c0:1a:a9:77:8a:
+                    c0:43
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Basic Constraints: critical
                 CA:TRUE
             X509v3 Subject Key Identifier: 
-                90:CB:53:EE:36:0A:5A:B0:93:38:C9:11:B7:AC:FD:27:71:99:DC:81
+                D0:8D:1F:B2:BC:29:96:73:EF:0C:7A:C2:A4:06:96:CF:D5:8C:31:DB
             X509v3 Key Usage: critical
                 Certificate Sign, CRL Sign
     Signature Algorithm: sha256WithRSAEncryption
-         64:09:43:15:ae:ac:dc:ad:23:99:24:cb:3a:39:4b:ad:2b:83:
-         f2:69:c3:f8:7e:e8:79:1e:8f:b1:09:0c:17:e6:44:5f:47:33:
-         14:fa:d4:f2:d8:d2:94:a9:75:58:4e:a8:44:8f:71:d0:53:c0:
-         76:5d:8e:39:1c:23:95:3d:89:c7:18:0a:0e:80:37:3d:8d:a6:
-         6d:60:c9:ad:08:a3:7a:8a:e8:00:3e:bf:67:e0:b6:09:b2:3b:
-         55:a6:b8:36:24:00:5e:8d:89:89:53:df:ea:2d:a9:f8:d2:60:
-         5a:e1:7b:f6:6c:a1:29:95:13:75:fe:62:57:cd:b4:0e:50:dc:
-         b5:41:3d:e9:19:0b:33:62:43:af:14:4d:40:c2:48:eb:72:88:
-         65:d3:89:11:f4:98:e8:f7:13:b4:7a:11:8e:39:01:80:a5:2e:
-         27:4a:98:3c:c8:d4:4f:31:70:3f:c2:de:e0:69:6b:59:54:d7:
-         66:07:68:74:72:9c:c2:1c:1c:0c:0d:b9:65:90:47:41:93:2c:
-         ec:d1:f0:51:b7:69:7b:e6:88:d8:f7:f7:0f:f1:4e:8c:e1:e9:
-         50:5d:7a:c3:62:1d:32:76:8e:df:7f:87:34:e4:57:bf:9c:1d:
-         45:4b:3b:07:f2:d1:8b:d6:d0:e6:72:de:7b:4b:23:bf:ee:1b:
-         c7:40:d0:a7
+         b3:af:8e:08:79:4f:56:93:22:e0:3b:9e:1f:22:0d:5d:12:69:
+         3c:13:26:4c:bb:41:9f:89:4b:b6:28:0d:85:37:75:c7:dc:e5:
+         b4:56:ba:3a:34:a7:40:30:ea:dc:7f:36:25:69:b9:c6:be:dd:
+         04:89:6a:f0:5e:14:42:45:bb:fc:fc:be:e6:c3:a2:0d:80:26:
+         30:11:df:21:54:cd:ea:59:25:5e:20:e8:2d:9d:97:64:fc:46:
+         1e:cb:f8:47:9c:90:d9:8e:db:f6:92:ec:76:ff:33:a4:28:16:
+         69:60:94:96:5b:e0:a0:32:ef:6f:8d:2a:06:65:67:6e:06:6a:
+         35:9f:10:04:37:2d:67:ad:9e:c3:2b:2a:fd:cb:1e:0f:d6:6b:
+         25:9d:11:eb:ae:a7:36:8b:b7:1c:11:7d:41:44:8e:37:07:03:
+         54:8d:43:ef:19:af:48:75:9d:78:2c:24:32:ba:72:c6:29:fa:
+         45:f9:9a:3b:59:9a:c9:2e:01:b5:9f:13:70:c9:dd:59:cf:8f:
+         7b:a9:24:c9:dc:c9:b6:52:62:7a:66:7b:2a:60:ee:a4:36:e9:
+         3b:95:04:31:fe:6a:74:e4:e2:3a:98:bc:70:26:1e:6e:03:9d:
+         f6:5c:3b:1b:5e:77:7a:01:71:56:1c:f9:98:e6:3e:ec:aa:c1:
+         e3:bd:35:36
 -----BEGIN CERTIFICATE-----
 MIIC9jCCAd6gAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwHDEaMBgGA1UEAwwRRiBD
 QSAtIE11bHRpLXJvb3QwHhcNMTYwMTA1MDAwMDAwWhcNMjYwMTAyMDAwMDAwWjAc
 MRowGAYDVQQDDBFCIENBIC0gTXVsdGktcm9vdDCCASIwDQYJKoZIhvcNAQEBBQAD
-ggEPADCCAQoCggEBAMrp8yH0oOe6gox/s5hEIEqai/nlDJnEInL3V3wezFZMw/X9
-HpClHL8sxMQpKTjMJp4aHePk25dYNRTo4ts3BRwy97sZIsI3PwF2jBcjyvwQabTR
-dCe2EH63wQeioa8YTVwuE3Kp+2Sx559JQTzcuF+U5mgFpR/IVoTi5WqEcZy4rD7s
-jgzS8l8R/fR/QKc7CAG7/W/QqRYdFKEoIDCYuh4iTlsJucHfF2AbgEOXSWnNak5Y
-CJzcKVc/G7/YXzKUrpey1I1QGtGLA4QA/YfZLu2RPT+3iVRGCs3bEGKAR2Ahsx0O
-vEFNhtSdUhtTghqfRpGYHu2f2mkWZCQc3vizNGkCAwEAAaNCMEAwDwYDVR0TAQH/
-BAUwAwEB/zAdBgNVHQ4EFgQUkMtT7jYKWrCTOMkRt6z9J3GZ3IEwDgYDVR0PAQH/
-BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IBAQBkCUMVrqzcrSOZJMs6OUutK4PyacP4
-fuh5Ho+xCQwX5kRfRzMU+tTy2NKUqXVYTqhEj3HQU8B2XY45HCOVPYnHGAoOgDc9
-jaZtYMmtCKN6iugAPr9n4LYJsjtVprg2JABejYmJU9/qLan40mBa4Xv2bKEplRN1
-/mJXzbQOUNy1QT3pGQszYkOvFE1Awkjrcohl04kR9Jjo9xO0ehGOOQGApS4nSpg8
-yNRPMXA/wt7gaWtZVNdmB2h0cpzCHBwMDbllkEdBkyzs0fBRt2l75ojY9/cP8U6M
-4elQXXrDYh0ydo7ff4c05Fe/nB1FSzsH8tGL1tDmct57SyO/7hvHQNCn
+ggEPADCCAQoCggEBAMpsVKs8VDNs1wTES8Q5Mtt6SeTh52DHNTMIWbpiv0nWBR8H
+uLa9OC9rp+WN3nkn2DZYkmnM245qibR5q8+YUwgSF55RFbznj+WT2RouaKmTPNN6
+daRcwvwWm7rfSV1zZeywzB66zJg50U6y1l/ofyQa+lawDTNGIlZPXPMWrVWKYjy8
+UMI6WD5wTVrfmezHpiyPKqUuEbhYxdXoQy9ApSCAMip2XgYHSG1EYLohcmHiGuxk
+XXJy8SGdBC9hNQsv8MD+UrjEQZy2E1ghgeMoJ01sJKMg+w+c1E80OtDRCITEQHFE
+T+i+xR9dHDRkC2wcJPqpg0nG9U1/Y8AaqXeKwEMCAwEAAaNCMEAwDwYDVR0TAQH/
+BAUwAwEB/zAdBgNVHQ4EFgQU0I0fsrwplnPvDHrCpAaWz9WMMdswDgYDVR0PAQH/
+BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IBAQCzr44IeU9WkyLgO54fIg1dEmk8EyZM
+u0GfiUu2KA2FN3XH3OW0Vro6NKdAMOrcfzYlabnGvt0EiWrwXhRCRbv8/L7mw6IN
+gCYwEd8hVM3qWSVeIOgtnZdk/EYey/hHnJDZjtv2kux2/zOkKBZpYJSWW+CgMu9v
+jSoGZWduBmo1nxAENy1nrZ7DKyr9yx4P1mslnRHrrqc2i7ccEX1BRI43BwNUjUPv
+Ga9IdZ14LCQyunLGKfpF+Zo7WZrJLgG1nxNwyd1Zz497qSTJ3Mm2UmJ6ZnsqYO6k
+Nuk7lQQx/mp05OI6mLxwJh5uA532XDsbXnd6AXFWHPmY5j7sqsHjvTU2
 -----END CERTIFICATE-----
diff --git a/net/data/ssl/certificates/multi-root-BFE.keychain b/net/data/ssl/certificates/multi-root-BFE.keychain
index 80976aa..acb819bf 100644
--- a/net/data/ssl/certificates/multi-root-BFE.keychain
+++ b/net/data/ssl/certificates/multi-root-BFE.keychain
Binary files differ
diff --git a/net/data/ssl/certificates/multi-root-C-by-D.pem b/net/data/ssl/certificates/multi-root-C-by-D.pem
index bab6142..ea171e2 100644
--- a/net/data/ssl/certificates/multi-root-C-by-D.pem
+++ b/net/data/ssl/certificates/multi-root-C-by-D.pem
@@ -12,63 +12,63 @@
             Public Key Algorithm: rsaEncryption
                 Public-Key: (2048 bit)
                 Modulus:
-                    00:b6:1f:67:e4:9e:db:e0:ff:eb:29:75:ee:68:a2:
-                    4e:95:6e:d2:f6:9d:c9:b6:dc:08:18:70:b5:76:bf:
-                    b7:14:8b:cb:46:c6:6a:2c:fa:43:f9:54:93:fa:bd:
-                    aa:f0:ee:a3:20:5b:2a:cd:08:f7:be:95:36:e4:88:
-                    f8:fd:43:7d:b8:f9:38:b4:d2:4e:22:0b:8b:85:de:
-                    6a:fe:6f:da:3b:4b:0f:26:c1:f8:31:22:36:19:96:
-                    0c:ef:85:7c:72:67:ac:4c:5c:f9:23:a4:29:d8:a5:
-                    1c:b6:ec:95:eb:d3:c2:8d:cb:ae:9a:d7:08:c8:b7:
-                    f7:a0:c6:28:44:5f:24:97:bd:ca:d9:6d:99:9b:17:
-                    47:1f:38:b3:e3:67:6a:b4:75:d6:92:cd:67:62:20:
-                    58:f0:a7:46:85:94:72:76:98:c5:ec:4c:75:1b:a1:
-                    76:67:4b:1f:c8:23:6c:2a:78:66:c2:a7:6b:af:ef:
-                    97:30:34:60:0a:db:98:94:3b:9f:95:3c:34:b6:35:
-                    40:12:fa:1d:bf:66:f4:7b:fd:66:1a:2a:49:8c:24:
-                    60:91:08:f9:61:39:f9:3b:29:98:64:7b:35:04:a9:
-                    f5:af:8d:0f:1e:e7:28:b6:30:32:b4:5f:d4:29:16:
-                    7a:70:8d:db:b9:ba:bf:eb:22:98:5d:94:c8:47:e3:
-                    4b:11
+                    00:b2:c4:16:dc:07:88:ec:7e:a6:b3:25:c8:7b:9c:
+                    e0:07:1e:40:a9:40:c0:4d:c8:73:27:ea:88:d8:58:
+                    1a:1a:12:e3:9a:62:41:4c:a1:e9:b1:ce:c6:b2:f6:
+                    3a:f6:89:3f:40:e6:0f:fb:15:4b:cb:d2:8d:8e:b6:
+                    44:aa:63:fa:3b:c5:cc:af:86:05:70:aa:ec:f4:b3:
+                    79:04:e6:3e:25:ec:ec:29:d6:c9:8b:7b:13:05:a7:
+                    ff:51:5b:ab:4c:bc:d0:e4:bd:61:1a:d2:27:f1:2e:
+                    5f:f4:51:81:c4:23:ba:20:c3:14:08:b4:be:78:49:
+                    b5:13:1f:69:fd:f6:a7:59:91:84:a9:99:10:c8:9c:
+                    63:9e:99:c2:f2:3d:61:9d:6a:6e:d4:26:9b:88:aa:
+                    da:66:b3:0d:c6:99:03:16:13:3a:a4:9a:ff:08:3e:
+                    59:df:a7:44:b7:17:99:3f:63:7f:3a:05:7e:ce:64:
+                    78:34:e6:00:77:69:e6:03:24:a7:12:f3:e8:a8:50:
+                    2b:55:16:fa:6e:65:c6:28:58:82:a4:20:7e:68:22:
+                    e9:81:9e:a2:e8:0f:d6:87:c2:73:dd:c2:0c:cc:a3:
+                    47:54:11:f5:3d:dc:51:52:57:b2:ce:77:8b:7a:ac:
+                    a7:f0:2a:26:36:e6:26:b9:6a:83:da:b2:6f:c0:f6:
+                    1e:f3
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Basic Constraints: critical
                 CA:TRUE
             X509v3 Subject Key Identifier: 
-                90:53:F5:80:11:F6:3F:1B:A8:9D:8D:75:0D:56:3B:F2:2B:C5:9C:44
+                E3:D1:05:98:4C:68:53:C2:DC:00:EE:AC:E5:A8:B8:FC:B9:72:D9:67
             X509v3 Key Usage: critical
                 Certificate Sign, CRL Sign
     Signature Algorithm: sha256WithRSAEncryption
-         67:11:95:f4:b9:cb:47:e6:50:da:fd:a0:13:78:d7:e1:be:59:
-         ec:86:32:e5:56:3e:9b:8f:db:b0:3b:93:fb:d0:6e:b3:de:7e:
-         10:5b:b4:30:f7:02:e8:3f:ff:4e:91:3a:e8:b8:4a:94:5e:14:
-         7b:f8:84:e5:1f:63:2c:b4:7f:4f:ee:b1:d5:ee:92:79:7d:63:
-         87:a0:e9:57:14:57:11:59:18:54:8b:e3:d1:51:80:a7:2f:51:
-         f2:6f:43:d2:87:e1:59:23:2c:fe:83:38:e1:25:da:b5:34:af:
-         33:17:64:80:08:b6:bd:5f:92:05:2c:81:b0:c3:d3:80:cd:e1:
-         5c:95:d2:ea:1e:d3:af:d9:93:c2:f4:23:ae:51:b0:a4:82:49:
-         2d:ec:fe:d1:18:e3:a3:53:9f:63:4b:38:dc:54:25:ce:4c:90:
-         37:02:e4:67:41:31:ba:7a:13:1a:68:1e:ed:34:0c:3d:66:ba:
-         a3:3a:71:76:5f:5f:89:a1:cd:95:50:f6:5d:1f:c0:91:31:93:
-         5b:58:af:e7:9b:21:e6:57:b1:f4:d7:dd:c1:84:25:5b:83:f7:
-         5f:c9:89:17:5b:6f:54:f2:8b:ed:47:de:27:57:9e:e9:8c:b3:
-         58:2c:c2:77:25:e1:eb:22:06:d1:f6:c5:f4:d7:1a:3d:00:1c:
-         2e:85:e9:70
+         7e:5b:a7:f2:c7:15:33:73:ce:e4:1e:77:ba:35:8b:44:01:57:
+         b1:db:55:d3:54:95:c6:44:27:89:3f:e5:46:98:de:4a:7e:d9:
+         e7:6c:e8:0d:d5:e2:98:31:07:21:9c:bd:01:47:be:0c:e1:b3:
+         22:1e:ea:da:d4:fc:b5:37:5d:94:de:06:9b:69:a5:77:22:d0:
+         96:80:35:9f:02:a0:cd:41:35:b3:21:94:ca:9b:03:4f:68:18:
+         5e:6d:0d:95:95:17:ab:bd:00:9b:d0:78:f7:38:5e:37:df:33:
+         15:2f:3e:64:27:c8:67:5e:c4:14:92:08:90:55:34:8d:73:d9:
+         66:0c:30:dd:42:ab:71:73:b4:26:28:b1:13:90:7b:0a:10:f2:
+         7c:75:07:36:1f:a5:b6:a5:97:ac:20:c7:83:0c:15:cf:5c:34:
+         df:3f:8d:81:3e:c0:43:2a:ca:6f:c4:86:cc:2f:93:e1:5d:18:
+         68:a4:bd:cc:5b:39:fa:40:fa:d4:a7:8b:7a:5d:b7:59:77:48:
+         9b:ab:e0:71:b2:04:1f:79:ea:d1:cd:d3:24:52:5b:4b:21:2f:
+         84:2e:b4:d6:87:1d:4f:fe:e7:6c:94:ff:d0:02:50:6b:bc:2a:
+         1e:21:a5:ac:3e:73:b5:2f:ba:11:c5:6f:8f:f7:8e:eb:08:11:
+         00:cb:e3:2d
 -----BEGIN CERTIFICATE-----
 MIIC+zCCAeOgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwITEfMB0GA1UEAwwWRCBS
 b290IENBIC0gTXVsdGktcm9vdDAeFw0xNjAxMDMwMDAwMDBaFw0yNjAxMDIwMDAw
 MDBaMBwxGjAYBgNVBAMMEUMgQ0EgLSBNdWx0aS1yb290MIIBIjANBgkqhkiG9w0B
-AQEFAAOCAQ8AMIIBCgKCAQEAth9n5J7b4P/rKXXuaKJOlW7S9p3JttwIGHC1dr+3
-FIvLRsZqLPpD+VST+r2q8O6jIFsqzQj3vpU25Ij4/UN9uPk4tNJOIguLhd5q/m/a
-O0sPJsH4MSI2GZYM74V8cmesTFz5I6Qp2KUctuyV69PCjcuumtcIyLf3oMYoRF8k
-l73K2W2ZmxdHHziz42dqtHXWks1nYiBY8KdGhZRydpjF7Ex1G6F2Z0sfyCNsKnhm
-wqdrr++XMDRgCtuYlDuflTw0tjVAEvodv2b0e/1mGipJjCRgkQj5YTn5OymYZHs1
-BKn1r40PHucotjAytF/UKRZ6cI3bubq/6yKYXZTIR+NLEQIDAQABo0IwQDAPBgNV
-HRMBAf8EBTADAQH/MB0GA1UdDgQWBBSQU/WAEfY/G6idjXUNVjvyK8WcRDAOBgNV
-HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAGcRlfS5y0fmUNr9oBN41+G+
-WeyGMuVWPpuP27A7k/vQbrPefhBbtDD3Aug//06ROui4SpReFHv4hOUfYyy0f0/u
-sdXuknl9Y4eg6VcUVxFZGFSL49FRgKcvUfJvQ9KH4VkjLP6DOOEl2rU0rzMXZIAI
-tr1fkgUsgbDD04DN4VyV0uoe06/Zk8L0I65RsKSCSS3s/tEY46NTn2NLONxUJc5M
-kDcC5GdBMbp6ExpoHu00DD1muqM6cXZfX4mhzZVQ9l0fwJExk1tYr+ebIeZXsfTX
-3cGEJVuD91/JiRdbb1Tyi+1H3idXnumMs1gswncl4esiBtH2xfTXGj0AHC6F6XA=
+AQEFAAOCAQ8AMIIBCgKCAQEAssQW3AeI7H6msyXIe5zgBx5AqUDATchzJ+qI2Fga
+GhLjmmJBTKHpsc7GsvY69ok/QOYP+xVLy9KNjrZEqmP6O8XMr4YFcKrs9LN5BOY+
+JezsKdbJi3sTBaf/UVurTLzQ5L1hGtIn8S5f9FGBxCO6IMMUCLS+eEm1Ex9p/fan
+WZGEqZkQyJxjnpnC8j1hnWpu1CabiKraZrMNxpkDFhM6pJr/CD5Z36dEtxeZP2N/
+OgV+zmR4NOYAd2nmAySnEvPoqFArVRb6bmXGKFiCpCB+aCLpgZ6i6A/Wh8Jz3cIM
+zKNHVBH1PdxRUleyzneLeqyn8ComNuYmuWqD2rJvwPYe8wIDAQABo0IwQDAPBgNV
+HRMBAf8EBTADAQH/MB0GA1UdDgQWBBTj0QWYTGhTwtwA7qzlqLj8uXLZZzAOBgNV
+HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAH5bp/LHFTNzzuQed7o1i0QB
+V7HbVdNUlcZEJ4k/5UaY3kp+2eds6A3V4pgxByGcvQFHvgzhsyIe6trU/LU3XZTe
+BptppXci0JaANZ8CoM1BNbMhlMqbA09oGF5tDZWVF6u9AJvQePc4XjffMxUvPmQn
+yGdexBSSCJBVNI1z2WYMMN1Cq3FztCYosROQewoQ8nx1BzYfpball6wgx4MMFc9c
+NN8/jYE+wEMqym/Ehswvk+FdGGikvcxbOfpA+tSni3pdt1l3SJur4HGyBB956tHN
+0yRSW0shL4QutNaHHU/+52yU/9ACUGu8Kh4hpaw+c7UvuhHFb4/3jusIEQDL4y0=
 -----END CERTIFICATE-----
diff --git a/net/data/ssl/certificates/multi-root-C-by-E.pem b/net/data/ssl/certificates/multi-root-C-by-E.pem
index 5ecc8b262..1f8b76c 100644
--- a/net/data/ssl/certificates/multi-root-C-by-E.pem
+++ b/net/data/ssl/certificates/multi-root-C-by-E.pem
@@ -12,63 +12,63 @@
             Public Key Algorithm: rsaEncryption
                 Public-Key: (2048 bit)
                 Modulus:
-                    00:b6:1f:67:e4:9e:db:e0:ff:eb:29:75:ee:68:a2:
-                    4e:95:6e:d2:f6:9d:c9:b6:dc:08:18:70:b5:76:bf:
-                    b7:14:8b:cb:46:c6:6a:2c:fa:43:f9:54:93:fa:bd:
-                    aa:f0:ee:a3:20:5b:2a:cd:08:f7:be:95:36:e4:88:
-                    f8:fd:43:7d:b8:f9:38:b4:d2:4e:22:0b:8b:85:de:
-                    6a:fe:6f:da:3b:4b:0f:26:c1:f8:31:22:36:19:96:
-                    0c:ef:85:7c:72:67:ac:4c:5c:f9:23:a4:29:d8:a5:
-                    1c:b6:ec:95:eb:d3:c2:8d:cb:ae:9a:d7:08:c8:b7:
-                    f7:a0:c6:28:44:5f:24:97:bd:ca:d9:6d:99:9b:17:
-                    47:1f:38:b3:e3:67:6a:b4:75:d6:92:cd:67:62:20:
-                    58:f0:a7:46:85:94:72:76:98:c5:ec:4c:75:1b:a1:
-                    76:67:4b:1f:c8:23:6c:2a:78:66:c2:a7:6b:af:ef:
-                    97:30:34:60:0a:db:98:94:3b:9f:95:3c:34:b6:35:
-                    40:12:fa:1d:bf:66:f4:7b:fd:66:1a:2a:49:8c:24:
-                    60:91:08:f9:61:39:f9:3b:29:98:64:7b:35:04:a9:
-                    f5:af:8d:0f:1e:e7:28:b6:30:32:b4:5f:d4:29:16:
-                    7a:70:8d:db:b9:ba:bf:eb:22:98:5d:94:c8:47:e3:
-                    4b:11
+                    00:b2:c4:16:dc:07:88:ec:7e:a6:b3:25:c8:7b:9c:
+                    e0:07:1e:40:a9:40:c0:4d:c8:73:27:ea:88:d8:58:
+                    1a:1a:12:e3:9a:62:41:4c:a1:e9:b1:ce:c6:b2:f6:
+                    3a:f6:89:3f:40:e6:0f:fb:15:4b:cb:d2:8d:8e:b6:
+                    44:aa:63:fa:3b:c5:cc:af:86:05:70:aa:ec:f4:b3:
+                    79:04:e6:3e:25:ec:ec:29:d6:c9:8b:7b:13:05:a7:
+                    ff:51:5b:ab:4c:bc:d0:e4:bd:61:1a:d2:27:f1:2e:
+                    5f:f4:51:81:c4:23:ba:20:c3:14:08:b4:be:78:49:
+                    b5:13:1f:69:fd:f6:a7:59:91:84:a9:99:10:c8:9c:
+                    63:9e:99:c2:f2:3d:61:9d:6a:6e:d4:26:9b:88:aa:
+                    da:66:b3:0d:c6:99:03:16:13:3a:a4:9a:ff:08:3e:
+                    59:df:a7:44:b7:17:99:3f:63:7f:3a:05:7e:ce:64:
+                    78:34:e6:00:77:69:e6:03:24:a7:12:f3:e8:a8:50:
+                    2b:55:16:fa:6e:65:c6:28:58:82:a4:20:7e:68:22:
+                    e9:81:9e:a2:e8:0f:d6:87:c2:73:dd:c2:0c:cc:a3:
+                    47:54:11:f5:3d:dc:51:52:57:b2:ce:77:8b:7a:ac:
+                    a7:f0:2a:26:36:e6:26:b9:6a:83:da:b2:6f:c0:f6:
+                    1e:f3
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Basic Constraints: critical
                 CA:TRUE
             X509v3 Subject Key Identifier: 
-                90:53:F5:80:11:F6:3F:1B:A8:9D:8D:75:0D:56:3B:F2:2B:C5:9C:44
+                E3:D1:05:98:4C:68:53:C2:DC:00:EE:AC:E5:A8:B8:FC:B9:72:D9:67
             X509v3 Key Usage: critical
                 Certificate Sign, CRL Sign
     Signature Algorithm: sha256WithRSAEncryption
-         43:35:08:cc:aa:f8:10:9f:9e:fa:ab:24:dc:c6:e6:9a:23:52:
-         c9:4c:81:33:ba:64:b2:86:a8:29:f4:1f:5a:fa:5a:c4:91:56:
-         16:d1:f9:84:96:89:8c:ac:1f:b6:ea:2f:cb:12:f4:92:ed:3b:
-         85:09:eb:f3:7a:2e:09:39:ec:ee:09:4b:fa:86:3e:62:40:0e:
-         57:72:07:de:fa:53:45:ac:40:1c:0d:0b:4a:67:9a:f7:39:ce:
-         33:5e:d0:17:0b:8a:83:ae:33:6f:96:c0:f0:7a:ac:07:36:c5:
-         86:a9:db:93:aa:2e:fa:71:d1:1a:dd:82:2a:f8:1c:30:2a:b9:
-         7d:29:fa:75:62:76:7c:15:15:75:af:78:6c:7c:53:ae:2e:80:
-         14:0d:0b:eb:0f:b1:6d:fa:df:72:0b:6f:f0:90:96:18:71:df:
-         76:1d:8c:f1:d5:c0:4f:ab:38:1a:eb:e6:a1:dd:1d:dc:60:d4:
-         da:7f:40:db:17:fc:4a:56:65:3a:86:60:83:87:b3:f6:3b:a8:
-         85:ac:2b:14:c2:26:77:8f:ee:a4:6f:11:f2:27:08:3f:bf:86:
-         4a:e3:bd:ef:6b:51:ec:72:a7:51:08:47:16:f8:d3:d7:b1:8d:
-         a1:b1:ca:d3:cd:fd:56:0a:2c:2f:62:27:8c:e1:ff:88:83:ff:
-         83:ab:87:70
+         0d:37:a8:9e:12:c9:fb:45:a2:b9:82:07:4a:2a:34:d2:3b:1d:
+         84:70:b1:4a:85:37:7e:64:31:45:c3:02:9d:32:4e:92:a4:97:
+         72:ed:1d:f2:c3:26:c8:3f:90:e4:24:f4:6e:4b:33:71:98:bc:
+         68:25:26:cc:de:c1:46:a6:a8:83:60:fc:6e:c0:72:98:8f:ce:
+         38:6e:69:9d:ab:d1:5a:f0:a6:c8:07:a1:09:b3:8c:03:09:7b:
+         44:62:73:15:85:71:5f:2c:0a:33:78:f2:a3:10:85:1e:6b:46:
+         d1:a5:f1:9c:13:ba:f7:95:41:a0:fb:de:c9:09:e1:72:a4:92:
+         ff:33:e4:81:25:10:af:90:17:79:df:54:ea:b9:87:0e:f8:6d:
+         09:55:10:46:4c:87:36:37:2f:c0:86:03:ee:7a:b4:d3:27:22:
+         22:d5:9c:2e:e6:38:f0:f4:84:5c:ca:b7:9b:4d:6a:1c:57:7e:
+         24:07:35:13:a0:f9:d6:a3:aa:29:cb:e0:8a:b0:86:1c:41:24:
+         b1:ed:04:30:71:2b:99:d7:0a:a4:51:53:b1:76:2e:be:63:5b:
+         7c:8e:d5:8f:fa:f3:99:58:7d:ce:30:07:5d:1e:ed:e6:bc:0a:
+         d1:a7:cc:17:94:e7:d1:67:07:7c:37:6d:3f:c2:8b:04:9e:77:
+         fb:5b:9c:2d
 -----BEGIN CERTIFICATE-----
 MIIC+zCCAeOgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwITEfMB0GA1UEAwwWRSBS
 b290IENBIC0gTXVsdGktcm9vdDAeFw0xNjAxMDUwMDAwMDBaFw0yNjAxMDIwMDAw
 MDBaMBwxGjAYBgNVBAMMEUMgQ0EgLSBNdWx0aS1yb290MIIBIjANBgkqhkiG9w0B
-AQEFAAOCAQ8AMIIBCgKCAQEAth9n5J7b4P/rKXXuaKJOlW7S9p3JttwIGHC1dr+3
-FIvLRsZqLPpD+VST+r2q8O6jIFsqzQj3vpU25Ij4/UN9uPk4tNJOIguLhd5q/m/a
-O0sPJsH4MSI2GZYM74V8cmesTFz5I6Qp2KUctuyV69PCjcuumtcIyLf3oMYoRF8k
-l73K2W2ZmxdHHziz42dqtHXWks1nYiBY8KdGhZRydpjF7Ex1G6F2Z0sfyCNsKnhm
-wqdrr++XMDRgCtuYlDuflTw0tjVAEvodv2b0e/1mGipJjCRgkQj5YTn5OymYZHs1
-BKn1r40PHucotjAytF/UKRZ6cI3bubq/6yKYXZTIR+NLEQIDAQABo0IwQDAPBgNV
-HRMBAf8EBTADAQH/MB0GA1UdDgQWBBSQU/WAEfY/G6idjXUNVjvyK8WcRDAOBgNV
-HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAEM1CMyq+BCfnvqrJNzG5poj
-UslMgTO6ZLKGqCn0H1r6WsSRVhbR+YSWiYysH7bqL8sS9JLtO4UJ6/N6Lgk57O4J
-S/qGPmJADldyB976U0WsQBwNC0pnmvc5zjNe0BcLioOuM2+WwPB6rAc2xYap25Oq
-Lvpx0Rrdgir4HDAquX0p+nVidnwVFXWveGx8U64ugBQNC+sPsW3633ILb/CQlhhx
-33YdjPHVwE+rOBrr5qHdHdxg1Np/QNsX/EpWZTqGYIOHs/Y7qIWsKxTCJneP7qRv
-EfInCD+/hkrjve9rUexyp1EIRxb409exjaGxytPN/VYKLC9iJ4zh/4iD/4Orh3A=
+AQEFAAOCAQ8AMIIBCgKCAQEAssQW3AeI7H6msyXIe5zgBx5AqUDATchzJ+qI2Fga
+GhLjmmJBTKHpsc7GsvY69ok/QOYP+xVLy9KNjrZEqmP6O8XMr4YFcKrs9LN5BOY+
+JezsKdbJi3sTBaf/UVurTLzQ5L1hGtIn8S5f9FGBxCO6IMMUCLS+eEm1Ex9p/fan
+WZGEqZkQyJxjnpnC8j1hnWpu1CabiKraZrMNxpkDFhM6pJr/CD5Z36dEtxeZP2N/
+OgV+zmR4NOYAd2nmAySnEvPoqFArVRb6bmXGKFiCpCB+aCLpgZ6i6A/Wh8Jz3cIM
+zKNHVBH1PdxRUleyzneLeqyn8ComNuYmuWqD2rJvwPYe8wIDAQABo0IwQDAPBgNV
+HRMBAf8EBTADAQH/MB0GA1UdDgQWBBTj0QWYTGhTwtwA7qzlqLj8uXLZZzAOBgNV
+HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAA03qJ4SyftFormCB0oqNNI7
+HYRwsUqFN35kMUXDAp0yTpKkl3LtHfLDJsg/kOQk9G5LM3GYvGglJszewUamqINg
+/G7AcpiPzjhuaZ2r0VrwpsgHoQmzjAMJe0RicxWFcV8sCjN48qMQhR5rRtGl8ZwT
+uveVQaD73skJ4XKkkv8z5IElEK+QF3nfVOq5hw74bQlVEEZMhzY3L8CGA+56tNMn
+IiLVnC7mOPD0hFzKt5tNahxXfiQHNROg+dajqinL4IqwhhxBJLHtBDBxK5nXCqRR
+U7F2Lr5jW3yO1Y/685lYfc4wB10e7ea8CtGnzBeU59FnB3w3bT/CiwSed/tbnC0=
 -----END CERTIFICATE-----
diff --git a/net/data/ssl/certificates/multi-root-D-by-D.pem b/net/data/ssl/certificates/multi-root-D-by-D.pem
index 3030167..7fd6fa9a 100644
--- a/net/data/ssl/certificates/multi-root-D-by-D.pem
+++ b/net/data/ssl/certificates/multi-root-D-by-D.pem
@@ -12,64 +12,64 @@
             Public Key Algorithm: rsaEncryption
                 Public-Key: (2048 bit)
                 Modulus:
-                    00:cd:cf:d9:70:03:4f:4f:f1:9f:93:a1:2c:6e:cb:
-                    2f:20:d7:67:29:ce:99:02:4e:db:7d:6b:5e:6a:3a:
-                    a1:d2:7f:cd:f9:58:bd:34:fe:af:8d:8a:05:34:a2:
-                    67:16:ae:94:88:3b:77:3f:f2:a0:a5:46:2e:05:2e:
-                    b8:a7:2f:ff:e0:df:1d:b8:1e:31:6f:57:f9:aa:55:
-                    9c:83:aa:04:94:cd:e4:0f:99:f4:74:c1:38:8d:4c:
-                    90:67:ba:7e:92:42:59:ff:14:d6:4e:22:31:78:04:
-                    89:63:7d:84:fa:60:e7:d2:0d:61:0b:d8:a5:20:b3:
-                    8a:ce:f1:ef:b7:b0:b5:a6:81:d0:47:50:fb:5a:09:
-                    34:e1:a0:e3:6b:cf:e8:26:38:4d:cb:70:ae:4c:96:
-                    2c:9e:46:18:0c:e3:11:9f:8d:8a:65:c5:b1:03:5c:
-                    61:d9:35:a8:5d:29:08:7c:45:2e:38:13:dc:b0:72:
-                    a6:e6:29:04:85:6a:6d:fd:74:af:60:6c:24:51:e2:
-                    3a:58:38:c1:0f:b2:4e:ac:8e:63:81:36:01:9f:02:
-                    04:de:54:53:4c:fa:5f:67:44:db:f0:ed:ce:3f:f0:
-                    5b:e7:75:b3:72:d5:e8:76:9c:24:73:2b:0c:d9:7c:
-                    dd:85:a8:61:b9:42:d1:69:35:04:88:03:8a:c2:aa:
-                    10:cb
+                    00:b4:b2:8e:83:7f:3b:8b:0f:9f:71:37:18:78:d0:
+                    f5:bc:07:ac:d8:eb:bf:f6:7c:c0:65:dc:00:bf:83:
+                    f7:e4:5e:97:9f:db:24:e4:c1:f9:31:70:b2:51:44:
+                    2c:27:05:6a:1f:1e:35:9c:ea:c4:eb:f8:0a:c4:4b:
+                    14:30:89:e8:75:93:fb:96:32:bc:0e:64:ca:11:74:
+                    4a:ac:26:a0:9c:09:cd:6e:43:cf:6c:56:03:44:ab:
+                    53:81:66:8d:5a:ad:75:1b:31:23:9f:fd:5e:8c:10:
+                    cd:e9:e9:05:80:41:5e:b8:f1:96:3d:5b:17:b2:e1:
+                    a8:47:44:eb:82:30:5e:7a:fe:8f:11:bb:b8:31:8e:
+                    98:4c:a9:f3:2c:91:59:78:f4:63:1c:47:ad:6a:96:
+                    5e:87:39:f3:17:9b:d6:9c:e9:e1:3c:0e:ef:8a:d8:
+                    7e:c3:2d:33:d9:eb:26:29:1d:8a:66:ef:b9:8d:c3:
+                    b1:51:3a:75:56:1b:b8:a9:08:e7:10:db:37:70:c4:
+                    6c:32:c0:e1:2b:f4:84:12:a5:cf:49:83:e1:5a:40:
+                    ab:db:f9:23:c5:7d:c0:03:ac:0e:3e:be:7c:42:92:
+                    fb:b7:71:91:37:04:92:4e:d5:92:31:cf:1b:cd:e4:
+                    27:e5:85:98:ac:20:95:5d:6d:4e:90:fa:c7:6c:2b:
+                    fd:41
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Basic Constraints: critical
                 CA:TRUE
             X509v3 Subject Key Identifier: 
-                FA:45:82:63:D1:67:F2:93:F4:6A:6B:44:44:74:1A:D2:B0:CD:12:F6
+                69:E7:FF:33:A6:6B:A0:AD:5A:F1:D3:15:4F:9E:F7:C5:16:2E:C4:B6
             X509v3 Key Usage: critical
                 Certificate Sign, CRL Sign
     Signature Algorithm: sha256WithRSAEncryption
-         ac:1c:7c:de:1a:4a:31:54:77:c5:94:7d:6a:0b:9d:c2:c9:d4:
-         3b:2d:71:e4:99:df:ca:02:5c:a0:1c:1c:22:7d:f2:a5:0e:97:
-         7c:91:20:12:c5:b7:f5:56:15:8c:1b:44:b2:32:94:8b:e5:b1:
-         c0:0b:f6:c0:b8:b4:cf:b9:27:d8:49:52:fc:81:9f:48:2a:08:
-         b8:94:a1:3f:78:fe:20:66:f5:ed:3f:61:f6:f7:23:5c:4c:36:
-         49:48:10:07:de:40:62:eb:3b:bb:6b:4b:8e:e4:a7:b3:75:33:
-         2f:4d:11:58:76:1e:1c:d9:b9:dc:1c:33:da:82:2b:5f:fc:51:
-         f1:26:35:7d:5e:eb:67:ba:da:2c:f2:d7:6e:88:b6:a1:34:ed:
-         07:d2:a5:e4:ac:d6:9b:7c:6c:6e:77:aa:11:4e:d0:60:fa:86:
-         94:a0:74:00:60:8b:1c:0b:3e:5d:05:c9:b9:8c:b4:6f:a5:e7:
-         82:c0:6a:ef:60:73:de:1f:74:20:aa:67:c7:d9:c2:81:c7:4c:
-         d7:c9:57:e4:7d:db:80:bd:7d:4f:39:a4:77:d3:2e:65:79:87:
-         ae:05:f7:9c:28:ed:e8:4e:f6:ac:38:3f:8f:36:bb:ae:5e:42:
-         71:d5:a9:5b:a7:df:42:9f:6b:e0:ec:3e:3b:6e:36:11:9b:34:
-         a8:66:ff:d5
+         55:ec:3a:cd:87:dc:96:54:23:68:65:f7:a6:91:3c:37:f0:44:
+         94:2e:2f:3a:af:2c:0d:f4:09:f6:52:69:4f:ad:ac:83:6c:76:
+         76:72:2b:c0:48:ea:c9:76:c0:f5:7a:1e:73:ba:3c:f3:41:93:
+         b4:4b:a5:6a:a3:87:f5:c7:6f:e9:55:ce:e0:8b:8c:83:e6:f0:
+         e0:1c:e8:6a:8f:3b:67:b6:cd:35:6d:0b:1c:16:bf:38:fd:9d:
+         d8:95:a9:3c:b9:4c:05:19:71:f4:a0:2c:1f:83:18:5a:f3:5a:
+         ea:80:49:70:cc:49:84:63:7c:a9:4d:cb:1f:df:96:f2:c4:2c:
+         2c:e8:b0:75:69:8c:a9:71:7e:27:6a:fe:22:c6:77:e0:77:f4:
+         98:05:29:45:18:75:a3:f0:43:40:b2:8d:52:cb:2e:46:fb:37:
+         bb:c6:68:20:c2:2e:01:82:51:f0:00:3a:89:40:9b:ab:9c:c3:
+         5c:f2:a3:3b:f7:00:98:4d:bd:a7:74:37:f6:74:c7:6e:42:4b:
+         aa:8c:cc:c7:85:b2:4b:78:cb:8c:03:7c:e5:85:75:32:a9:89:
+         49:da:ed:3d:9e:5b:a2:c9:b2:2a:08:06:6d:cf:df:83:d4:a9:
+         3d:e9:44:de:70:9c:43:e3:35:24:dd:85:ed:7c:37:4e:02:44:
+         d2:5d:7a:ad
 -----BEGIN CERTIFICATE-----
 MIIDADCCAeigAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwITEfMB0GA1UEAwwWRCBS
 b290IENBIC0gTXVsdGktcm9vdDAeFw0xNjAxMDIwMDAwMDBaFw0yNjAxMDIwMDAw
 MDBaMCExHzAdBgNVBAMMFkQgUm9vdCBDQSAtIE11bHRpLXJvb3QwggEiMA0GCSqG
-SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDNz9lwA09P8Z+ToSxuyy8g12cpzpkCTtt9
-a15qOqHSf835WL00/q+NigU0omcWrpSIO3c/8qClRi4FLrinL//g3x24HjFvV/mq
-VZyDqgSUzeQPmfR0wTiNTJBnun6SQln/FNZOIjF4BIljfYT6YOfSDWEL2KUgs4rO
-8e+3sLWmgdBHUPtaCTThoONrz+gmOE3LcK5MliyeRhgM4xGfjYplxbEDXGHZNahd
-KQh8RS44E9ywcqbmKQSFam39dK9gbCRR4jpYOMEPsk6sjmOBNgGfAgTeVFNM+l9n
-RNvw7c4/8FvndbNy1eh2nCRzKwzZfN2FqGG5QtFpNQSIA4rCqhDLAgMBAAGjQjBA
-MA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFPpFgmPRZ/KT9GprRER0GtKwzRL2
-MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEArBx83hpKMVR3xZR9
-agudwsnUOy1x5JnfygJcoBwcIn3ypQ6XfJEgEsW39VYVjBtEsjKUi+WxwAv2wLi0
-z7kn2ElS/IGfSCoIuJShP3j+IGb17T9h9vcjXEw2SUgQB95AYus7u2tLjuSns3Uz
-L00RWHYeHNm53Bwz2oIrX/xR8SY1fV7rZ7raLPLXboi2oTTtB9Kl5KzWm3xsbneq
-EU7QYPqGlKB0AGCLHAs+XQXJuYy0b6XngsBq72Bz3h90IKpnx9nCgcdM18lX5H3b
-gL19Tzmkd9MuZXmHrgX3nCjt6E72rDg/jza7rl5CcdWpW6ffQp9r4Ow+O242EZs0
-qGb/1Q==
+SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC0so6DfzuLD59xNxh40PW8B6zY67/2fMBl
+3AC/g/fkXpef2yTkwfkxcLJRRCwnBWofHjWc6sTr+ArESxQwieh1k/uWMrwOZMoR
+dEqsJqCcCc1uQ89sVgNEq1OBZo1arXUbMSOf/V6MEM3p6QWAQV648ZY9Wxey4ahH
+ROuCMF56/o8Ru7gxjphMqfMskVl49GMcR61qll6HOfMXm9ac6eE8Du+K2H7DLTPZ
+6yYpHYpm77mNw7FROnVWG7ipCOcQ2zdwxGwywOEr9IQSpc9Jg+FaQKvb+SPFfcAD
+rA4+vnxCkvu3cZE3BJJO1ZIxzxvN5CflhZisIJVdbU6Q+sdsK/1BAgMBAAGjQjBA
+MA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFGnn/zOma6CtWvHTFU+e98UWLsS2
+MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAVew6zYfcllQjaGX3
+ppE8N/BElC4vOq8sDfQJ9lJpT62sg2x2dnIrwEjqyXbA9Xoec7o880GTtEulaqOH
+9cdv6VXO4IuMg+bw4Bzoao87Z7bNNW0LHBa/OP2d2JWpPLlMBRlx9KAsH4MYWvNa
+6oBJcMxJhGN8qU3LH9+W8sQsLOiwdWmMqXF+J2r+IsZ34Hf0mAUpRRh1o/BDQLKN
+UssuRvs3u8ZoIMIuAYJR8AA6iUCbq5zDXPKjO/cAmE29p3Q39nTHbkJLqozMx4Wy
+S3jLjAN85YV1MqmJSdrtPZ5bosmyKggGbc/fg9SpPelE3nCcQ+M1JN2F7Xw3TgJE
+0l16rQ==
 -----END CERTIFICATE-----
diff --git a/net/data/ssl/certificates/multi-root-E-by-E.pem b/net/data/ssl/certificates/multi-root-E-by-E.pem
index 15632dd..4ccd307 100644
--- a/net/data/ssl/certificates/multi-root-E-by-E.pem
+++ b/net/data/ssl/certificates/multi-root-E-by-E.pem
@@ -12,64 +12,64 @@
             Public Key Algorithm: rsaEncryption
                 Public-Key: (2048 bit)
                 Modulus:
-                    00:b5:60:cb:b4:84:ab:6c:ba:59:52:a9:4c:6a:85:
-                    41:f2:41:17:49:40:3f:3e:e8:70:5c:05:df:dd:64:
-                    9e:fc:be:fb:38:ef:5d:67:ab:0e:de:9c:ea:ad:91:
-                    e1:f4:db:8b:f4:c0:e6:d0:ad:e2:83:15:01:aa:49:
-                    42:97:ae:72:7b:78:e3:20:4e:7e:29:ee:b5:35:6b:
-                    c4:af:d4:54:b0:86:2f:a9:09:a7:3b:8c:05:9e:fd:
-                    b4:b8:1f:3a:aa:d5:b5:d2:91:0f:50:e9:d2:1e:62:
-                    1c:c1:30:07:41:aa:bd:c2:11:3f:cc:c8:0f:a9:7e:
-                    81:69:52:96:86:2a:07:63:7b:f0:23:9e:db:27:88:
-                    8c:dc:aa:8c:66:dd:35:3a:08:60:37:36:41:34:f5:
-                    48:69:23:1a:5b:18:a7:ec:df:68:0a:3c:19:fb:92:
-                    b7:fa:53:9b:f3:70:b6:0d:4c:cb:2f:b7:0e:7e:5f:
-                    94:8c:a3:71:66:09:be:0d:af:db:52:f6:82:3f:88:
-                    64:72:cc:19:79:f4:7b:4d:6e:50:dc:93:88:d5:29:
-                    8a:e1:c8:1f:32:71:9f:d9:0e:14:31:f8:94:11:23:
-                    b1:bf:64:eb:27:3a:64:fb:77:ee:40:8c:a7:03:ed:
-                    1d:ec:8f:ee:25:58:f0:26:91:3c:f8:28:a1:7a:45:
-                    9f:13
+                    00:c0:14:71:12:fe:4f:36:78:5f:3a:b4:1e:d5:bb:
+                    22:92:3e:57:bf:4d:e0:cf:1e:a1:fb:19:6d:88:3a:
+                    59:93:79:57:42:bc:ab:7c:a0:0d:73:35:db:db:ba:
+                    80:ef:a9:80:5b:b0:90:f5:2f:ea:17:7d:2b:92:a4:
+                    5e:88:0a:16:f3:dc:f5:25:3d:7a:8d:8e:9b:e9:22:
+                    74:dc:49:6e:87:ff:67:ae:3a:b8:09:63:63:e7:c2:
+                    bd:77:d7:1b:cb:93:c6:4a:1d:7b:51:25:05:31:cb:
+                    32:66:43:ea:2d:54:59:59:cd:de:d2:84:6f:d8:5a:
+                    c1:5b:6c:2d:67:d5:57:23:25:a0:04:dc:45:64:02:
+                    f0:de:1a:4a:62:c9:76:b5:f6:36:46:74:af:1f:18:
+                    6c:f7:38:cf:34:e3:e1:3f:ad:51:41:cf:92:ed:d5:
+                    27:f7:4a:e3:3c:d5:42:26:51:e3:b2:69:20:b1:1f:
+                    0a:f6:fd:19:3c:8e:98:94:64:eb:fe:e6:67:a0:12:
+                    f6:78:98:0f:44:b8:24:60:7c:de:e2:67:b9:0d:6e:
+                    8c:06:80:43:8e:41:76:1d:09:40:0e:3b:e7:8d:0a:
+                    d9:66:d7:34:6c:ce:7e:f9:25:6a:15:cf:9a:3e:ec:
+                    30:e0:a3:b1:d2:a3:b1:31:f1:62:50:5c:b4:fe:dd:
+                    54:61
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Basic Constraints: critical
                 CA:TRUE
             X509v3 Subject Key Identifier: 
-                51:68:BC:D9:1B:1D:7F:8E:0D:4A:33:39:2D:A4:1F:14:29:92:70:8E
+                15:FA:C3:A2:2A:E0:2C:25:C5:BE:D7:BE:91:51:DD:45:F0:F1:5D:64
             X509v3 Key Usage: critical
                 Certificate Sign, CRL Sign
     Signature Algorithm: sha256WithRSAEncryption
-         2d:d4:56:d9:90:bb:62:64:66:78:6d:cd:73:26:cc:42:ce:37:
-         f4:bf:e8:8f:e7:1e:00:cb:c2:bd:54:33:0b:a8:e2:04:e1:5f:
-         59:2a:1a:41:70:0f:d6:32:5f:d0:14:86:fa:e2:a7:19:29:49:
-         77:56:b9:d7:e6:eb:39:61:e4:25:67:22:eb:f8:46:86:b7:6b:
-         7d:44:01:0b:18:cb:ba:e5:af:76:ab:c6:fe:43:6c:d8:f6:33:
-         f7:86:0b:22:da:27:78:91:07:55:3f:b2:c5:1e:10:88:09:b3:
-         cf:22:c6:7e:8f:c6:d0:c5:ec:67:90:72:8b:2b:c4:46:81:2c:
-         82:d1:5c:57:4e:d5:af:c4:d2:d8:b2:a7:91:1a:42:b3:57:bc:
-         4e:81:5e:cf:91:af:da:f1:53:29:de:31:6b:d3:69:a4:4d:a9:
-         14:15:96:51:7d:0d:bd:28:11:03:71:d2:85:11:92:1d:96:1a:
-         12:33:0c:4b:cf:c4:40:19:fb:eb:6a:fe:9b:e7:2d:cd:f7:75:
-         a3:66:4e:a6:7d:8e:8c:2e:5d:b8:2c:a8:5e:d7:42:1b:97:00:
-         ba:12:41:8c:9b:f1:ed:91:49:63:5a:11:0d:e4:7d:f0:dc:36:
-         23:0b:1b:e8:5f:be:1f:6d:a7:aa:bb:30:76:e2:36:b2:5a:68:
-         80:f5:75:7e
+         bb:14:68:d2:09:0e:65:58:4d:d7:35:a0:a3:9b:e6:b4:2a:b4:
+         80:32:3e:61:6d:87:19:a6:a8:d2:01:78:cd:07:0b:09:a9:de:
+         5f:aa:86:43:dd:6f:d6:e0:3b:ab:60:71:d2:f0:aa:8f:14:93:
+         42:37:12:55:02:e1:a7:ed:8e:db:c0:83:10:19:f0:f5:1e:35:
+         77:84:9a:c1:79:9c:60:39:6f:50:00:66:73:6e:f0:b8:f7:75:
+         67:3e:fa:3e:0c:d0:d6:54:4a:ae:da:38:06:92:57:39:cc:d9:
+         b1:fa:60:5e:99:07:e6:97:3b:69:4d:e3:02:50:8d:60:76:8e:
+         7e:e3:60:d4:65:41:9b:6c:b8:cc:b2:c4:7a:61:32:cb:67:49:
+         b4:76:25:0c:7e:20:85:24:74:0a:90:0a:ce:73:f9:8e:ba:ce:
+         de:6e:0a:cf:6d:1c:50:67:fa:a2:4e:32:d0:ad:91:35:5e:aa:
+         b3:75:7e:23:14:29:a8:66:2a:82:ed:6c:ed:a9:9d:f6:77:20:
+         3a:e1:0b:ab:1e:ee:1d:8a:20:ff:7f:4f:36:5a:0a:30:5a:c6:
+         9c:aa:53:eb:3f:04:28:8a:6d:70:97:2a:99:d6:0c:db:a5:22:
+         0b:e5:6b:24:cf:6e:2a:c7:4a:6b:cd:82:8e:13:84:18:b6:47:
+         1b:9d:8b:83
 -----BEGIN CERTIFICATE-----
 MIIDADCCAeigAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwITEfMB0GA1UEAwwWRSBS
 b290IENBIC0gTXVsdGktcm9vdDAeFw0xNjAxMDIwMDAwMDBaFw0yNjAxMDIwMDAw
 MDBaMCExHzAdBgNVBAMMFkUgUm9vdCBDQSAtIE11bHRpLXJvb3QwggEiMA0GCSqG
-SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC1YMu0hKtsullSqUxqhUHyQRdJQD8+6HBc
-Bd/dZJ78vvs4711nqw7enOqtkeH024v0wObQreKDFQGqSUKXrnJ7eOMgTn4p7rU1
-a8Sv1FSwhi+pCac7jAWe/bS4Hzqq1bXSkQ9Q6dIeYhzBMAdBqr3CET/MyA+pfoFp
-UpaGKgdje/AjntsniIzcqoxm3TU6CGA3NkE09UhpIxpbGKfs32gKPBn7krf6U5vz
-cLYNTMsvtw5+X5SMo3FmCb4Nr9tS9oI/iGRyzBl59HtNblDck4jVKYrhyB8ycZ/Z
-DhQx+JQRI7G/ZOsnOmT7d+5AjKcD7R3sj+4lWPAmkTz4KKF6RZ8TAgMBAAGjQjBA
-MA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFFovNkbHX+ODUozOS2kHxQpknCO
-MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEALdRW2ZC7YmRmeG3N
-cybMQs439L/oj+ceAMvCvVQzC6jiBOFfWSoaQXAP1jJf0BSG+uKnGSlJd1a51+br
-OWHkJWci6/hGhrdrfUQBCxjLuuWvdqvG/kNs2PYz94YLItoneJEHVT+yxR4QiAmz
-zyLGfo/G0MXsZ5ByiyvERoEsgtFcV07Vr8TS2LKnkRpCs1e8ToFez5Gv2vFTKd4x
-a9NppE2pFBWWUX0NvSgRA3HShRGSHZYaEjMMS8/EQBn762r+m+ctzfd1o2ZOpn2O
-jC5duCyoXtdCG5cAuhJBjJvx7ZFJY1oRDeR98Nw2Iwsb6F++H22nqrswduI2slpo
-gPV1fg==
+SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDAFHES/k82eF86tB7VuyKSPle/TeDPHqH7
+GW2IOlmTeVdCvKt8oA1zNdvbuoDvqYBbsJD1L+oXfSuSpF6IChbz3PUlPXqNjpvp
+InTcSW6H/2euOrgJY2Pnwr131xvLk8ZKHXtRJQUxyzJmQ+otVFlZzd7ShG/YWsFb
+bC1n1VcjJaAE3EVkAvDeGkpiyXa19jZGdK8fGGz3OM804+E/rVFBz5Lt1Sf3SuM8
+1UImUeOyaSCxHwr2/Rk8jpiUZOv+5megEvZ4mA9EuCRgfN7iZ7kNbowGgEOOQXYd
+CUAOO+eNCtlm1zRszn75JWoVz5o+7DDgo7HSo7Ex8WJQXLT+3VRhAgMBAAGjQjBA
+MA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFBX6w6Iq4Cwlxb7XvpFR3UXw8V1k
+MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAuxRo0gkOZVhN1zWg
+o5vmtCq0gDI+YW2HGaao0gF4zQcLCaneX6qGQ91v1uA7q2Bx0vCqjxSTQjcSVQLh
+p+2O28CDEBnw9R41d4SawXmcYDlvUABmc27wuPd1Zz76PgzQ1lRKrto4BpJXOczZ
+sfpgXpkH5pc7aU3jAlCNYHaOfuNg1GVBm2y4zLLEemEyy2dJtHYlDH4ghSR0CpAK
+znP5jrrO3m4Kz20cUGf6ok4y0K2RNV6qs3V+IxQpqGYqgu1s7amd9ncgOuELqx7u
+HYog/39PNloKMFrGnKpT6z8EKIptcJcqmdYM26UiC+VrJM9uKsdKa82CjhOEGLZH
+G52Lgw==
 -----END CERTIFICATE-----
diff --git a/net/data/ssl/certificates/multi-root-F-by-E.pem b/net/data/ssl/certificates/multi-root-F-by-E.pem
index 86b2bae..2e1124d 100644
--- a/net/data/ssl/certificates/multi-root-F-by-E.pem
+++ b/net/data/ssl/certificates/multi-root-F-by-E.pem
@@ -12,63 +12,63 @@
             Public Key Algorithm: rsaEncryption
                 Public-Key: (2048 bit)
                 Modulus:
-                    00:9d:41:79:88:93:ab:fe:e6:52:28:84:91:9d:c2:
-                    85:a0:2c:97:39:69:25:20:43:85:8c:db:64:8f:41:
-                    f4:b5:25:e6:3e:16:41:fa:40:b7:6c:2c:fc:11:76:
-                    7d:86:b7:47:73:68:ae:e9:2c:7e:5d:8b:21:68:86:
-                    71:11:cd:21:f9:16:a0:20:67:ac:79:40:d0:94:e6:
-                    bf:a2:dd:65:af:da:d3:c5:23:82:0a:a2:1c:a7:bc:
-                    7d:f0:c2:a8:0b:30:ca:20:d6:31:5f:28:c8:74:4b:
-                    09:1e:50:de:d4:51:d9:9c:f5:3d:fe:b0:8d:ee:11:
-                    f2:22:3e:11:09:53:23:77:52:5c:cf:8d:dd:6c:3b:
-                    c4:39:1b:33:c2:00:bc:34:2d:e6:dc:9d:af:e8:36:
-                    ec:ac:c7:e4:73:09:44:ad:59:8d:51:c1:ee:11:60:
-                    5b:b5:c9:d8:cb:48:b0:f9:0a:57:38:d8:e3:be:c5:
-                    4e:38:7e:47:3f:24:66:a1:11:3d:2d:9f:ca:4a:dc:
-                    59:58:fd:cc:56:22:c7:d5:c9:70:2f:ec:66:81:4d:
-                    ee:48:39:97:ef:dd:b6:02:34:b2:90:db:16:a4:60:
-                    9d:18:de:95:87:a1:14:6e:19:ab:88:42:37:57:cf:
-                    20:c4:d8:e3:c6:24:8d:bc:fd:4d:d2:4e:74:06:4a:
-                    c4:3b
+                    00:c3:5d:d7:fd:02:9d:bb:14:27:d9:65:9e:e0:7e:
+                    5c:68:0b:74:71:bb:88:1e:8e:e4:54:57:fd:f6:3f:
+                    06:3a:3c:b1:5c:62:1f:cc:d8:b1:c6:90:c5:22:fc:
+                    f4:2b:47:cf:83:fc:08:d9:fd:f3:aa:b6:e4:22:0c:
+                    88:4a:74:63:2b:13:f1:6a:37:04:0e:de:3b:66:20:
+                    b9:f5:e2:b8:cd:e6:8a:b6:fd:9d:93:b6:6d:8e:72:
+                    71:b3:a1:03:7d:60:7a:94:a5:e9:93:c1:75:99:26:
+                    26:63:3b:33:3a:3e:af:21:96:78:ff:2a:84:55:1d:
+                    21:59:db:6a:cc:ba:d8:c1:cb:8d:ed:e6:ef:b6:67:
+                    aa:85:6d:55:6c:39:8e:32:59:8b:df:ed:f6:40:ce:
+                    46:b7:b6:fe:e6:75:39:ea:59:05:4c:2a:b4:82:95:
+                    db:9e:26:71:71:b5:4c:dc:07:06:6f:31:dd:de:93:
+                    f0:be:eb:55:39:ae:9a:7f:b0:3f:74:06:3c:e6:55:
+                    e5:09:aa:d5:84:56:be:f5:67:c4:3c:47:69:16:a0:
+                    a4:96:72:08:01:28:0b:ce:ba:a8:16:a9:88:79:b9:
+                    ae:40:ed:1a:8b:5e:d8:ab:22:a0:3e:09:08:c5:77:
+                    94:35:af:f5:de:f0:e6:b8:3d:86:02:4e:79:b2:9b:
+                    84:7d
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Basic Constraints: critical
                 CA:TRUE
             X509v3 Subject Key Identifier: 
-                CA:CF:14:CE:08:5C:4B:71:AD:DE:DA:70:78:A9:D1:D6:7F:25:76:E4
+                02:E9:36:9C:1C:59:BF:B9:1B:DE:86:93:68:BB:A6:2B:07:FA:05:B7
             X509v3 Key Usage: critical
                 Certificate Sign, CRL Sign
     Signature Algorithm: sha256WithRSAEncryption
-         31:f4:da:87:3f:e3:55:1a:c6:e4:fc:71:23:9e:51:de:88:89:
-         f2:c7:b3:7c:8b:f7:c1:71:3a:bc:bd:ff:61:43:2a:3b:4c:6c:
-         2c:eb:7c:f6:00:37:e1:0a:fc:2f:01:73:73:d7:b9:b8:dc:fa:
-         6e:10:fc:55:2b:d6:d3:95:09:27:de:97:28:d5:b6:48:19:a5:
-         0b:13:d3:29:cf:80:86:36:39:41:c1:15:17:74:8c:d7:2f:f6:
-         00:63:06:cb:cb:74:9b:2e:35:1c:b7:d8:38:db:a4:d2:63:c0:
-         f1:97:db:be:1d:10:bc:3b:67:59:99:0d:3e:5f:2d:52:38:ca:
-         80:49:6f:b4:f3:e5:0a:d4:b3:96:ef:45:9c:a4:15:35:af:9c:
-         04:fd:5a:22:0f:44:67:32:0e:79:47:37:87:fb:3c:fb:2f:0a:
-         1d:b3:20:cd:f5:fe:71:f6:c8:f1:0e:f2:ed:8d:a4:8c:c3:af:
-         a0:ce:8e:49:a8:af:ec:55:2c:17:4f:03:7e:6a:a9:ff:ae:46:
-         25:89:0c:54:d7:32:7b:9b:8f:a2:df:ac:44:a8:03:cc:56:9e:
-         d6:cb:f6:af:c9:e4:f8:de:68:4d:0c:11:20:ac:5b:d2:e8:07:
-         b2:29:6f:27:b5:29:a8:fa:09:9d:f1:a1:f7:2c:72:05:07:7d:
-         31:1e:98:d4
+         28:0a:35:5a:36:47:b7:fd:96:b0:42:62:5e:0a:fe:f8:10:70:
+         da:65:67:9c:5a:33:68:4c:ba:5c:e8:3f:f3:04:3f:8f:e5:11:
+         5f:0b:e2:70:2f:9f:6e:10:c4:18:cf:ea:a0:10:cf:52:71:08:
+         34:12:b0:ea:77:f8:ec:f3:72:36:6f:c5:34:e7:9e:67:32:96:
+         14:4f:d4:f9:cb:75:34:64:09:78:6e:95:91:f2:af:ef:46:73:
+         42:01:91:49:db:c9:1c:a6:92:89:f4:8f:02:97:15:2e:20:f7:
+         66:71:d9:28:b8:ad:4b:6b:74:e7:33:b6:25:c8:ea:1d:22:2a:
+         2b:bb:ba:d6:77:5f:db:fb:bf:23:ab:7f:6d:97:89:f3:29:f4:
+         68:31:6c:4b:02:75:61:ec:28:4a:fc:b4:3d:eb:88:4f:73:3e:
+         bb:5e:9d:1b:c6:71:7b:2c:09:0b:03:b1:85:4b:fc:8d:4c:c4:
+         96:b1:1c:ec:9a:85:94:4f:f2:14:b8:14:50:d1:21:0d:dd:4b:
+         af:4a:ab:8a:3c:9b:d4:98:08:d3:2d:56:4c:3b:1e:46:cb:2c:
+         f6:04:bc:ff:d7:85:10:6e:3b:5d:30:a3:29:88:a9:cd:17:de:
+         23:92:2f:1f:52:7c:dc:69:5b:8f:b8:e7:0a:9b:f2:cf:0f:1d:
+         94:b4:ff:1b
 -----BEGIN CERTIFICATE-----
 MIIC+zCCAeOgAwIBAgICEAIwDQYJKoZIhvcNAQELBQAwITEfMB0GA1UEAwwWRSBS
 b290IENBIC0gTXVsdGktcm9vdDAeFw0xNjAxMDIwMDAwMDBaFw0yNjAxMDIwMDAw
 MDBaMBwxGjAYBgNVBAMMEUYgQ0EgLSBNdWx0aS1yb290MIIBIjANBgkqhkiG9w0B
-AQEFAAOCAQ8AMIIBCgKCAQEAnUF5iJOr/uZSKISRncKFoCyXOWklIEOFjNtkj0H0
-tSXmPhZB+kC3bCz8EXZ9hrdHc2iu6Sx+XYshaIZxEc0h+RagIGeseUDQlOa/ot1l
-r9rTxSOCCqIcp7x98MKoCzDKINYxXyjIdEsJHlDe1FHZnPU9/rCN7hHyIj4RCVMj
-d1Jcz43dbDvEORszwgC8NC3m3J2v6DbsrMfkcwlErVmNUcHuEWBbtcnYy0iw+QpX
-ONjjvsVOOH5HPyRmoRE9LZ/KStxZWP3MViLH1clwL+xmgU3uSDmX7922AjSykNsW
-pGCdGN6Vh6EUbhmriEI3V88gxNjjxiSNvP1N0k50BkrEOwIDAQABo0IwQDAPBgNV
-HRMBAf8EBTADAQH/MB0GA1UdDgQWBBTKzxTOCFxLca3e2nB4qdHWfyV25DAOBgNV
-HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBADH02oc/41UaxuT8cSOeUd6I
-ifLHs3yL98FxOry9/2FDKjtMbCzrfPYAN+EK/C8Bc3PXubjc+m4Q/FUr1tOVCSfe
-lyjVtkgZpQsT0ynPgIY2OUHBFRd0jNcv9gBjBsvLdJsuNRy32DjbpNJjwPGX274d
-ELw7Z1mZDT5fLVI4yoBJb7Tz5QrUs5bvRZykFTWvnAT9WiIPRGcyDnlHN4f7PPsv
-Ch2zIM31/nH2yPEO8u2NpIzDr6DOjkmor+xVLBdPA35qqf+uRiWJDFTXMnubj6Lf
-rESoA8xWntbL9q/J5PjeaE0MESCsW9LoB7Ipbye1Kaj6CZ3xofcscgUHfTEemNQ=
+AQEFAAOCAQ8AMIIBCgKCAQEAw13X/QKduxQn2WWe4H5caAt0cbuIHo7kVFf99j8G
+OjyxXGIfzNixxpDFIvz0K0fPg/wI2f3zqrbkIgyISnRjKxPxajcEDt47ZiC59eK4
+zeaKtv2dk7ZtjnJxs6EDfWB6lKXpk8F1mSYmYzszOj6vIZZ4/yqEVR0hWdtqzLrY
+wcuN7ebvtmeqhW1VbDmOMlmL3+32QM5Gt7b+5nU56lkFTCq0gpXbniZxcbVM3AcG
+bzHd3pPwvutVOa6af7A/dAY85lXlCarVhFa+9WfEPEdpFqCklnIIASgLzrqoFqmI
+ebmuQO0ai17YqyKgPgkIxXeUNa/13vDmuD2GAk55spuEfQIDAQABo0IwQDAPBgNV
+HRMBAf8EBTADAQH/MB0GA1UdDgQWBBQC6TacHFm/uRvehpNou6YrB/oFtzAOBgNV
+HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBACgKNVo2R7f9lrBCYl4K/vgQ
+cNplZ5xaM2hMulzoP/MEP4/lEV8L4nAvn24QxBjP6qAQz1JxCDQSsOp3+OzzcjZv
+xTTnnmcylhRP1PnLdTRkCXhulZHyr+9Gc0IBkUnbyRymkon0jwKXFS4g92Zx2Si4
+rUtrdOcztiXI6h0iKiu7utZ3X9v7vyOrf22XifMp9GgxbEsCdWHsKEr8tD3riE9z
+PrtenRvGcXssCQsDsYVL/I1MxJaxHOyahZRP8hS4FFDRIQ3dS69Kq4o8m9SYCNMt
+Vkw7HkbLLPYEvP/XhRBuO10woymIqc0X3iOSLx9SfNxpW4+45wqb8s8PHZS0/xs=
 -----END CERTIFICATE-----
diff --git a/net/data/ssl/certificates/multi-root-chain1.pem b/net/data/ssl/certificates/multi-root-chain1.pem
index 9861944b..fb53c33 100644
--- a/net/data/ssl/certificates/multi-root-chain1.pem
+++ b/net/data/ssl/certificates/multi-root-chain1.pem
@@ -5,78 +5,80 @@
     Signature Algorithm: sha256WithRSAEncryption
         Issuer: CN=B CA - Multi-root
         Validity
-            Not Before: Mar 11 01:37:16 2016 GMT
-            Not After : Mar  9 01:37:16 2026 GMT
+            Not Before: Feb 28 23:46:47 2017 GMT
+            Not After : Feb 26 23:46:47 2027 GMT
         Subject: C=US, ST=California, L=Mountain View, O=Test CA, CN=127.0.0.1
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
                 Public-Key: (2048 bit)
                 Modulus:
-                    00:c8:27:1c:19:81:c0:a7:30:93:03:1c:f8:21:b8:
-                    2f:8a:22:b4:89:0f:da:b1:40:95:df:dc:46:53:fc:
-                    6f:36:26:66:5a:53:6d:45:78:c2:39:16:9a:3f:82:
-                    8b:ba:c5:b0:78:a8:18:bc:d5:a7:92:a5:e6:ac:e2:
-                    0c:81:d0:94:e5:0c:ec:5e:03:0c:17:c5:35:2a:7b:
-                    ab:86:eb:bf:e8:62:0a:8f:b0:25:b2:70:f5:11:8c:
-                    16:4f:c1:76:44:e5:75:e8:93:4f:e9:e7:c4:e4:42:
-                    0a:08:be:73:2c:cb:8f:73:6a:40:77:eb:33:60:ac:
-                    be:c5:27:fd:b1:4f:88:4b:15:af:98:fd:32:53:ae:
-                    b0:2a:0c:b2:f5:05:f3:3a:06:0d:6e:5c:fe:83:fc:
-                    e3:60:ae:99:8e:a1:21:c2:72:02:e6:f4:49:57:e6:
-                    91:31:2e:be:92:a1:ad:f8:71:31:64:74:10:33:d0:
-                    a7:0c:ed:18:c7:b2:50:71:fc:b9:b6:ae:95:a0:8d:
-                    ac:1f:3c:d5:79:a7:a9:88:50:b6:02:cd:68:60:24:
-                    45:9b:b6:e9:82:08:d9:9c:d4:7e:29:7d:2b:d9:ae:
-                    57:7f:62:6a:56:96:8b:4a:33:9e:5f:93:82:b0:d1:
-                    05:03:26:cd:15:f4:87:7f:6a:9a:df:e9:01:b5:d4:
-                    c9:11
+                    00:a4:18:86:3f:09:63:9c:d4:c0:06:45:a5:91:7f:
+                    e7:a7:b8:3d:c7:ff:0d:e8:39:f5:43:27:a7:44:2a:
+                    3b:53:03:e3:cd:13:23:46:5f:e0:27:f0:a3:7a:25:
+                    82:b0:52:bb:03:4f:99:e3:2c:1b:6f:54:05:0f:7f:
+                    4f:74:f9:ad:b2:88:85:43:63:06:ac:91:f1:19:b7:
+                    da:7a:42:68:6a:68:a5:e0:02:44:23:eb:d1:05:0d:
+                    3d:58:31:ee:ba:20:9e:16:11:f5:ae:b5:c3:21:cc:
+                    84:e7:1a:d2:c2:8c:7e:44:93:36:bd:6c:0c:07:35:
+                    f2:4e:57:3f:b3:cf:21:5a:ff:16:02:e9:61:f4:cc:
+                    4a:5a:24:da:55:fc:c6:da:44:d6:b7:2a:4e:31:bf:
+                    a0:80:24:55:ed:5c:bc:6b:84:12:a4:03:cc:b2:c2:
+                    db:ef:1e:08:bd:a3:bf:ef:fc:3d:53:38:b9:00:8a:
+                    d6:40:1a:cc:f2:6a:ab:e7:4b:67:1c:ae:ff:6d:43:
+                    12:08:c6:97:4b:73:df:85:cf:2a:a5:6e:ce:22:02:
+                    cb:63:6c:3f:00:aa:3b:b0:87:9b:d5:13:09:32:4c:
+                    bd:71:79:ff:04:b1:9a:8d:2d:a0:0a:65:d5:1e:53:
+                    c4:eb:0e:14:c0:b9:f3:8f:6f:64:b4:1d:11:a7:40:
+                    e7:61
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Basic Constraints: critical
                 CA:FALSE
             X509v3 Subject Key Identifier: 
-                FB:91:A9:5F:BC:27:81:98:55:30:BF:57:32:4D:B9:DA:56:DD:52:2C
+                28:6F:58:36:8F:1B:C5:99:18:5B:DC:A5:86:AF:89:F2:B4:3E:AF:51
             X509v3 Authority Key Identifier: 
-                keyid:90:CB:53:EE:36:0A:5A:B0:93:38:C9:11:B7:AC:FD:27:71:99:DC:81
+                keyid:D0:8D:1F:B2:BC:29:96:73:EF:0C:7A:C2:A4:06:96:CF:D5:8C:31:DB
 
             X509v3 Extended Key Usage: 
                 TLS Web Server Authentication, TLS Web Client Authentication
+            X509v3 Subject Alternative Name: 
+                IP Address:127.0.0.1
     Signature Algorithm: sha256WithRSAEncryption
-         b9:31:7a:95:b2:ba:3a:b4:f1:16:76:df:eb:d5:b9:af:67:b1:
-         9d:8a:27:04:9b:61:6f:42:3f:c2:b3:cd:65:c4:86:cb:90:fb:
-         9d:3a:ed:fc:b8:74:da:d7:6a:6c:2f:17:68:d1:73:58:f1:a2:
-         bb:8f:d6:b0:a8:7f:b6:a8:b0:74:d1:ea:c4:62:ed:bc:1e:ef:
-         02:6b:d5:e8:2d:15:78:16:1e:90:fa:f4:29:5a:a8:43:ad:d2:
-         58:40:b4:1c:60:4e:cd:bc:6f:1a:39:e4:46:b2:58:93:96:5a:
-         a8:a4:c4:31:73:ed:89:c4:81:27:e1:4c:66:20:7c:27:c4:f9:
-         61:ff:d1:d5:a5:02:93:4c:06:fa:15:33:7a:1f:5f:eb:29:b2:
-         b5:6a:cd:7e:d6:d7:b7:51:a7:01:2f:22:9f:9e:7e:81:98:c4:
-         72:11:36:2c:e7:c6:d0:f0:7d:98:36:ea:b7:a0:aa:13:8f:6e:
-         ae:41:59:9b:e6:c9:bc:9c:e8:93:f5:0c:4e:ca:b4:dd:e3:01:
-         fe:23:6e:fb:fa:b3:61:66:58:f5:fc:07:16:1d:a9:52:ec:a0:
-         29:61:a4:39:ed:41:50:a3:a2:33:72:0e:3c:03:e1:0a:1a:1a:
-         cf:22:73:09:d7:ea:e8:15:fc:73:3c:d4:4e:34:6c:b4:18:94:
-         c4:d3:6e:12
+         07:8f:f9:c6:33:3c:bc:74:20:21:92:46:7a:c5:df:76:18:47:
+         63:0c:5e:e8:f3:97:ec:37:83:0b:4d:a4:1c:6b:0b:a2:28:db:
+         5c:17:d9:91:77:00:4a:db:46:f9:68:ec:2a:f8:b5:82:0c:00:
+         d1:88:0c:7c:b4:2d:e9:48:f5:a2:9d:a9:d5:bb:db:9d:56:96:
+         c5:6c:46:da:23:a3:66:80:a5:9b:93:d0:df:9c:00:75:ac:48:
+         ea:48:b4:22:ee:ff:db:eb:bb:8f:f0:de:16:a1:99:98:85:4c:
+         b3:66:dd:22:96:96:97:48:ae:8a:2d:e9:a5:1c:5c:d9:dd:31:
+         3f:58:7c:bb:2b:db:86:6a:53:e5:af:6d:85:3a:ca:92:5d:56:
+         e2:02:90:d7:eb:98:0f:d8:ba:2a:d1:26:bb:82:5b:80:d5:2d:
+         52:d7:40:4d:0d:0d:1e:fe:c2:89:be:e2:80:4d:cd:91:dc:f3:
+         fa:19:25:3e:ba:a8:cf:48:d3:b6:35:a5:96:6e:a5:12:d1:65:
+         65:a9:92:6b:d0:fc:05:25:7c:fb:76:48:38:15:7e:4f:95:03:
+         b0:c3:55:89:bc:59:be:de:3c:fb:4b:5a:f1:3b:00:c1:03:59:
+         6c:b3:8b:21:7e:84:75:30:19:8c:19:f6:99:40:ec:87:43:3b:
+         89:d0:f5:6d
 -----BEGIN CERTIFICATE-----
-MIIDZzCCAk+gAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwHDEaMBgGA1UEAwwRQiBD
-QSAtIE11bHRpLXJvb3QwHhcNMTYwMzExMDEzNzE2WhcNMjYwMzA5MDEzNzE2WjBg
+MIIDeTCCAmGgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwHDEaMBgGA1UEAwwRQiBD
+QSAtIE11bHRpLXJvb3QwHhcNMTcwMjI4MjM0NjQ3WhcNMjcwMjI2MjM0NjQ3WjBg
 MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91
 bnRhaW4gVmlldzEQMA4GA1UECgwHVGVzdCBDQTESMBAGA1UEAwwJMTI3LjAuMC4x
-MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyCccGYHApzCTAxz4Ibgv
-iiK0iQ/asUCV39xGU/xvNiZmWlNtRXjCORaaP4KLusWweKgYvNWnkqXmrOIMgdCU
-5QzsXgMMF8U1Knurhuu/6GIKj7AlsnD1EYwWT8F2ROV16JNP6efE5EIKCL5zLMuP
-c2pAd+szYKy+xSf9sU+ISxWvmP0yU66wKgyy9QXzOgYNblz+g/zjYK6ZjqEhwnIC
-5vRJV+aRMS6+kqGt+HExZHQQM9CnDO0Yx7JQcfy5tq6VoI2sHzzVeaepiFC2As1o
-YCRFm7bpggjZnNR+KX0r2a5Xf2JqVpaLSjOeX5OCsNEFAybNFfSHf2qa3+kBtdTJ
-EQIDAQABo28wbTAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBT7kalfvCeBmFUwv1cy
-TbnaVt1SLDAfBgNVHSMEGDAWgBSQy1PuNgpasJM4yRG3rP0ncZncgTAdBgNVHSUE
-FjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBALkxepWy
-ujq08RZ23+vVua9nsZ2KJwSbYW9CP8KzzWXEhsuQ+5067fy4dNrXamwvF2jRc1jx
-oruP1rCof7aosHTR6sRi7bwe7wJr1egtFXgWHpD69ClaqEOt0lhAtBxgTs28bxo5
-5EayWJOWWqikxDFz7YnEgSfhTGYgfCfE+WH/0dWlApNMBvoVM3ofX+spsrVqzX7W
-17dRpwEvIp+efoGYxHIRNiznxtDwfZg26regqhOPbq5BWZvmybyc6JP1DE7KtN3j
-Af4jbvv6s2FmWPX8BxYdqVLsoClhpDntQVCjojNyDjwD4QoaGs8icwnX6ugV/HM8
-1E40bLQYlMTTbhI=
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApBiGPwljnNTABkWlkX/n
+p7g9x/8N6Dn1QyenRCo7UwPjzRMjRl/gJ/CjeiWCsFK7A0+Z4ywbb1QFD39PdPmt
+soiFQ2MGrJHxGbfaekJoamil4AJEI+vRBQ09WDHuuiCeFhH1rrXDIcyE5xrSwox+
+RJM2vWwMBzXyTlc/s88hWv8WAulh9MxKWiTaVfzG2kTWtypOMb+ggCRV7Vy8a4QS
+pAPMssLb7x4IvaO/7/w9Uzi5AIrWQBrM8mqr50tnHK7/bUMSCMaXS3Pfhc8qpW7O
+IgLLY2w/AKo7sIeb1RMJMky9cXn/BLGajS2gCmXVHlPE6w4UwLnzj29ktB0Rp0Dn
+YQIDAQABo4GAMH4wDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUKG9YNo8bxZkYW9yl
+hq+J8rQ+r1EwHwYDVR0jBBgwFoAU0I0fsrwplnPvDHrCpAaWz9WMMdswHQYDVR0l
+BBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA8GA1UdEQQIMAaHBH8AAAEwDQYJKoZI
+hvcNAQELBQADggEBAAeP+cYzPLx0ICGSRnrF33YYR2MMXujzl+w3gwtNpBxrC6Io
+21wX2ZF3AErbRvlo7Cr4tYIMANGIDHy0LelI9aKdqdW7251WlsVsRtojo2aApZuT
+0N+cAHWsSOpItCLu/9vru4/w3hahmZiFTLNm3SKWlpdIroot6aUcXNndMT9YfLsr
+24ZqU+WvbYU6ypJdVuICkNfrmA/YuirRJruCW4DVLVLXQE0NDR7+wom+4oBNzZHc
+8/oZJT66qM9I07Y1pZZupRLRZWWpkmvQ/AUlfPt2SDgVfk+VA7DDVYm8Wb7ePPtL
+WvE7AMEDWWyziyF+hHUwGYwZ9plA7IdDO4nQ9W0=
 -----END CERTIFICATE-----
 Certificate:
     Data:
@@ -92,65 +94,65 @@
             Public Key Algorithm: rsaEncryption
                 Public-Key: (2048 bit)
                 Modulus:
-                    00:ca:e9:f3:21:f4:a0:e7:ba:82:8c:7f:b3:98:44:
-                    20:4a:9a:8b:f9:e5:0c:99:c4:22:72:f7:57:7c:1e:
-                    cc:56:4c:c3:f5:fd:1e:90:a5:1c:bf:2c:c4:c4:29:
-                    29:38:cc:26:9e:1a:1d:e3:e4:db:97:58:35:14:e8:
-                    e2:db:37:05:1c:32:f7:bb:19:22:c2:37:3f:01:76:
-                    8c:17:23:ca:fc:10:69:b4:d1:74:27:b6:10:7e:b7:
-                    c1:07:a2:a1:af:18:4d:5c:2e:13:72:a9:fb:64:b1:
-                    e7:9f:49:41:3c:dc:b8:5f:94:e6:68:05:a5:1f:c8:
-                    56:84:e2:e5:6a:84:71:9c:b8:ac:3e:ec:8e:0c:d2:
-                    f2:5f:11:fd:f4:7f:40:a7:3b:08:01:bb:fd:6f:d0:
-                    a9:16:1d:14:a1:28:20:30:98:ba:1e:22:4e:5b:09:
-                    b9:c1:df:17:60:1b:80:43:97:49:69:cd:6a:4e:58:
-                    08:9c:dc:29:57:3f:1b:bf:d8:5f:32:94:ae:97:b2:
-                    d4:8d:50:1a:d1:8b:03:84:00:fd:87:d9:2e:ed:91:
-                    3d:3f:b7:89:54:46:0a:cd:db:10:62:80:47:60:21:
-                    b3:1d:0e:bc:41:4d:86:d4:9d:52:1b:53:82:1a:9f:
-                    46:91:98:1e:ed:9f:da:69:16:64:24:1c:de:f8:b3:
-                    34:69
+                    00:ca:6c:54:ab:3c:54:33:6c:d7:04:c4:4b:c4:39:
+                    32:db:7a:49:e4:e1:e7:60:c7:35:33:08:59:ba:62:
+                    bf:49:d6:05:1f:07:b8:b6:bd:38:2f:6b:a7:e5:8d:
+                    de:79:27:d8:36:58:92:69:cc:db:8e:6a:89:b4:79:
+                    ab:cf:98:53:08:12:17:9e:51:15:bc:e7:8f:e5:93:
+                    d9:1a:2e:68:a9:93:3c:d3:7a:75:a4:5c:c2:fc:16:
+                    9b:ba:df:49:5d:73:65:ec:b0:cc:1e:ba:cc:98:39:
+                    d1:4e:b2:d6:5f:e8:7f:24:1a:fa:56:b0:0d:33:46:
+                    22:56:4f:5c:f3:16:ad:55:8a:62:3c:bc:50:c2:3a:
+                    58:3e:70:4d:5a:df:99:ec:c7:a6:2c:8f:2a:a5:2e:
+                    11:b8:58:c5:d5:e8:43:2f:40:a5:20:80:32:2a:76:
+                    5e:06:07:48:6d:44:60:ba:21:72:61:e2:1a:ec:64:
+                    5d:72:72:f1:21:9d:04:2f:61:35:0b:2f:f0:c0:fe:
+                    52:b8:c4:41:9c:b6:13:58:21:81:e3:28:27:4d:6c:
+                    24:a3:20:fb:0f:9c:d4:4f:34:3a:d0:d1:08:84:c4:
+                    40:71:44:4f:e8:be:c5:1f:5d:1c:34:64:0b:6c:1c:
+                    24:fa:a9:83:49:c6:f5:4d:7f:63:c0:1a:a9:77:8a:
+                    c0:43
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Basic Constraints: critical
                 CA:TRUE
             X509v3 Subject Key Identifier: 
-                90:CB:53:EE:36:0A:5A:B0:93:38:C9:11:B7:AC:FD:27:71:99:DC:81
+                D0:8D:1F:B2:BC:29:96:73:EF:0C:7A:C2:A4:06:96:CF:D5:8C:31:DB
             X509v3 Key Usage: critical
                 Certificate Sign, CRL Sign
     Signature Algorithm: sha256WithRSAEncryption
-         97:cd:ae:5a:26:f4:25:f6:c0:8b:08:d8:df:82:35:d8:76:f3:
-         5d:cc:99:bd:ac:70:c9:41:e0:24:c8:fd:e6:4e:41:2c:d4:69:
-         8d:08:25:fd:f3:32:3a:58:0b:d3:58:9c:81:51:bf:97:a4:bc:
-         00:18:1c:4f:1c:54:04:63:e3:72:87:f4:dc:9e:7b:dc:da:5d:
-         e1:ef:59:6b:f0:1f:3d:0c:11:55:1e:9a:1a:d8:8d:bc:7b:18:
-         b7:4f:92:1c:68:73:82:ec:f3:69:48:0a:86:40:4a:a5:6f:ae:
-         8f:10:2e:12:0b:e8:7e:b9:bc:d7:26:f0:cf:f4:0f:5b:77:f2:
-         ff:77:28:b4:5f:5e:ef:65:08:21:b8:f9:1e:56:b9:69:3b:c4:
-         7f:01:88:c9:7c:ca:d0:e2:df:e5:5e:8d:e9:2e:7d:4a:78:04:
-         8b:c1:dc:d4:58:ac:90:fc:5c:8e:48:2b:60:99:63:37:3f:e5:
-         61:da:8f:58:9f:4d:0a:ee:6c:8d:bc:1f:7e:c4:be:0f:32:4b:
-         11:7a:28:bf:dd:d0:a0:40:42:a8:43:4d:0b:2f:01:0e:73:de:
-         1b:a6:df:49:57:58:89:57:c0:23:76:83:f0:9a:0e:83:d9:9b:
-         cb:eb:ac:3f:89:d1:e8:3c:3e:f1:d5:80:0c:38:18:02:5c:5f:
-         e5:68:5e:cf
+         1e:16:7c:d7:d1:ee:63:a9:a2:b1:87:2c:8b:1e:d3:cf:51:14:
+         ed:12:0b:ec:67:2b:7f:3b:0e:8e:3c:50:bb:d1:dc:3b:40:1a:
+         ec:44:30:c4:f6:65:c2:c3:5d:d8:cb:c2:6c:13:2e:5a:2d:76:
+         c6:6b:5d:65:a5:7e:c2:bf:cb:fc:b1:50:b0:43:47:fc:a3:7b:
+         07:d1:77:50:4f:d2:53:98:8f:a2:00:97:13:d9:b7:83:2e:d9:
+         c4:2a:e6:b1:fc:2d:6c:ce:d1:61:73:aa:40:e0:ce:87:74:43:
+         a2:f7:b5:d9:5f:46:79:97:28:c4:de:15:60:3b:3e:3f:3d:1d:
+         14:f4:87:ef:b9:08:09:2a:fb:d0:d5:1b:4f:77:f9:0d:c9:4b:
+         23:32:1c:06:04:a6:83:aa:00:9c:70:c2:2b:01:42:1e:f6:d6:
+         d3:5c:f9:a8:b7:84:9e:44:12:9a:9f:a8:2a:89:56:69:a6:2f:
+         e9:ee:67:e9:7e:32:b5:ef:6b:4e:f0:12:23:fa:85:3e:03:59:
+         94:db:88:99:04:55:c4:d1:df:df:c6:e2:fd:61:c5:f6:af:dc:
+         4c:e4:52:8f:f2:c8:07:39:dd:99:33:49:85:1e:df:e1:1f:08:
+         6b:e0:d2:1b:93:db:32:05:4b:39:ee:b3:f1:b6:af:18:07:a7:
+         24:9c:1e:75
 -----BEGIN CERTIFICATE-----
 MIIC9jCCAd6gAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwHDEaMBgGA1UEAwwRQyBD
 QSAtIE11bHRpLXJvb3QwHhcNMTYwMTA0MDAwMDAwWhcNMjYwMTAyMDAwMDAwWjAc
 MRowGAYDVQQDDBFCIENBIC0gTXVsdGktcm9vdDCCASIwDQYJKoZIhvcNAQEBBQAD
-ggEPADCCAQoCggEBAMrp8yH0oOe6gox/s5hEIEqai/nlDJnEInL3V3wezFZMw/X9
-HpClHL8sxMQpKTjMJp4aHePk25dYNRTo4ts3BRwy97sZIsI3PwF2jBcjyvwQabTR
-dCe2EH63wQeioa8YTVwuE3Kp+2Sx559JQTzcuF+U5mgFpR/IVoTi5WqEcZy4rD7s
-jgzS8l8R/fR/QKc7CAG7/W/QqRYdFKEoIDCYuh4iTlsJucHfF2AbgEOXSWnNak5Y
-CJzcKVc/G7/YXzKUrpey1I1QGtGLA4QA/YfZLu2RPT+3iVRGCs3bEGKAR2Ahsx0O
-vEFNhtSdUhtTghqfRpGYHu2f2mkWZCQc3vizNGkCAwEAAaNCMEAwDwYDVR0TAQH/
-BAUwAwEB/zAdBgNVHQ4EFgQUkMtT7jYKWrCTOMkRt6z9J3GZ3IEwDgYDVR0PAQH/
-BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IBAQCXza5aJvQl9sCLCNjfgjXYdvNdzJm9
-rHDJQeAkyP3mTkEs1GmNCCX98zI6WAvTWJyBUb+XpLwAGBxPHFQEY+Nyh/Tcnnvc
-2l3h71lr8B89DBFVHpoa2I28exi3T5IcaHOC7PNpSAqGQEqlb66PEC4SC+h+ubzX
-JvDP9A9bd/L/dyi0X17vZQghuPkeVrlpO8R/AYjJfMrQ4t/lXo3pLn1KeASLwdzU
-WKyQ/FyOSCtgmWM3P+Vh2o9Yn00K7myNvB9+xL4PMksReii/3dCgQEKoQ00LLwEO
-c94bpt9JV1iJV8AjdoPwmg6D2ZvL66w/idHoPD7x1YAMOBgCXF/laF7P
+ggEPADCCAQoCggEBAMpsVKs8VDNs1wTES8Q5Mtt6SeTh52DHNTMIWbpiv0nWBR8H
+uLa9OC9rp+WN3nkn2DZYkmnM245qibR5q8+YUwgSF55RFbznj+WT2RouaKmTPNN6
+daRcwvwWm7rfSV1zZeywzB66zJg50U6y1l/ofyQa+lawDTNGIlZPXPMWrVWKYjy8
+UMI6WD5wTVrfmezHpiyPKqUuEbhYxdXoQy9ApSCAMip2XgYHSG1EYLohcmHiGuxk
+XXJy8SGdBC9hNQsv8MD+UrjEQZy2E1ghgeMoJ01sJKMg+w+c1E80OtDRCITEQHFE
+T+i+xR9dHDRkC2wcJPqpg0nG9U1/Y8AaqXeKwEMCAwEAAaNCMEAwDwYDVR0TAQH/
+BAUwAwEB/zAdBgNVHQ4EFgQU0I0fsrwplnPvDHrCpAaWz9WMMdswDgYDVR0PAQH/
+BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IBAQAeFnzX0e5jqaKxhyyLHtPPURTtEgvs
+Zyt/Ow6OPFC70dw7QBrsRDDE9mXCw13Yy8JsEy5aLXbGa11lpX7Cv8v8sVCwQ0f8
+o3sH0XdQT9JTmI+iAJcT2beDLtnEKuax/C1sztFhc6pA4M6HdEOi97XZX0Z5lyjE
+3hVgOz4/PR0U9IfvuQgJKvvQ1RtPd/kNyUsjMhwGBKaDqgCccMIrAUIe9tbTXPmo
+t4SeRBKan6gqiVZppi/p7mfpfjK172tO8BIj+oU+A1mU24iZBFXE0d/fxuL9YcX2
+r9xM5FKP8sgHOd2ZM0mFHt/hHwhr4NIbk9syBUs57rPxtq8YB6cknB51
 -----END CERTIFICATE-----
 Certificate:
     Data:
@@ -166,65 +168,65 @@
             Public Key Algorithm: rsaEncryption
                 Public-Key: (2048 bit)
                 Modulus:
-                    00:b6:1f:67:e4:9e:db:e0:ff:eb:29:75:ee:68:a2:
-                    4e:95:6e:d2:f6:9d:c9:b6:dc:08:18:70:b5:76:bf:
-                    b7:14:8b:cb:46:c6:6a:2c:fa:43:f9:54:93:fa:bd:
-                    aa:f0:ee:a3:20:5b:2a:cd:08:f7:be:95:36:e4:88:
-                    f8:fd:43:7d:b8:f9:38:b4:d2:4e:22:0b:8b:85:de:
-                    6a:fe:6f:da:3b:4b:0f:26:c1:f8:31:22:36:19:96:
-                    0c:ef:85:7c:72:67:ac:4c:5c:f9:23:a4:29:d8:a5:
-                    1c:b6:ec:95:eb:d3:c2:8d:cb:ae:9a:d7:08:c8:b7:
-                    f7:a0:c6:28:44:5f:24:97:bd:ca:d9:6d:99:9b:17:
-                    47:1f:38:b3:e3:67:6a:b4:75:d6:92:cd:67:62:20:
-                    58:f0:a7:46:85:94:72:76:98:c5:ec:4c:75:1b:a1:
-                    76:67:4b:1f:c8:23:6c:2a:78:66:c2:a7:6b:af:ef:
-                    97:30:34:60:0a:db:98:94:3b:9f:95:3c:34:b6:35:
-                    40:12:fa:1d:bf:66:f4:7b:fd:66:1a:2a:49:8c:24:
-                    60:91:08:f9:61:39:f9:3b:29:98:64:7b:35:04:a9:
-                    f5:af:8d:0f:1e:e7:28:b6:30:32:b4:5f:d4:29:16:
-                    7a:70:8d:db:b9:ba:bf:eb:22:98:5d:94:c8:47:e3:
-                    4b:11
+                    00:b2:c4:16:dc:07:88:ec:7e:a6:b3:25:c8:7b:9c:
+                    e0:07:1e:40:a9:40:c0:4d:c8:73:27:ea:88:d8:58:
+                    1a:1a:12:e3:9a:62:41:4c:a1:e9:b1:ce:c6:b2:f6:
+                    3a:f6:89:3f:40:e6:0f:fb:15:4b:cb:d2:8d:8e:b6:
+                    44:aa:63:fa:3b:c5:cc:af:86:05:70:aa:ec:f4:b3:
+                    79:04:e6:3e:25:ec:ec:29:d6:c9:8b:7b:13:05:a7:
+                    ff:51:5b:ab:4c:bc:d0:e4:bd:61:1a:d2:27:f1:2e:
+                    5f:f4:51:81:c4:23:ba:20:c3:14:08:b4:be:78:49:
+                    b5:13:1f:69:fd:f6:a7:59:91:84:a9:99:10:c8:9c:
+                    63:9e:99:c2:f2:3d:61:9d:6a:6e:d4:26:9b:88:aa:
+                    da:66:b3:0d:c6:99:03:16:13:3a:a4:9a:ff:08:3e:
+                    59:df:a7:44:b7:17:99:3f:63:7f:3a:05:7e:ce:64:
+                    78:34:e6:00:77:69:e6:03:24:a7:12:f3:e8:a8:50:
+                    2b:55:16:fa:6e:65:c6:28:58:82:a4:20:7e:68:22:
+                    e9:81:9e:a2:e8:0f:d6:87:c2:73:dd:c2:0c:cc:a3:
+                    47:54:11:f5:3d:dc:51:52:57:b2:ce:77:8b:7a:ac:
+                    a7:f0:2a:26:36:e6:26:b9:6a:83:da:b2:6f:c0:f6:
+                    1e:f3
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Basic Constraints: critical
                 CA:TRUE
             X509v3 Subject Key Identifier: 
-                90:53:F5:80:11:F6:3F:1B:A8:9D:8D:75:0D:56:3B:F2:2B:C5:9C:44
+                E3:D1:05:98:4C:68:53:C2:DC:00:EE:AC:E5:A8:B8:FC:B9:72:D9:67
             X509v3 Key Usage: critical
                 Certificate Sign, CRL Sign
     Signature Algorithm: sha256WithRSAEncryption
-         67:11:95:f4:b9:cb:47:e6:50:da:fd:a0:13:78:d7:e1:be:59:
-         ec:86:32:e5:56:3e:9b:8f:db:b0:3b:93:fb:d0:6e:b3:de:7e:
-         10:5b:b4:30:f7:02:e8:3f:ff:4e:91:3a:e8:b8:4a:94:5e:14:
-         7b:f8:84:e5:1f:63:2c:b4:7f:4f:ee:b1:d5:ee:92:79:7d:63:
-         87:a0:e9:57:14:57:11:59:18:54:8b:e3:d1:51:80:a7:2f:51:
-         f2:6f:43:d2:87:e1:59:23:2c:fe:83:38:e1:25:da:b5:34:af:
-         33:17:64:80:08:b6:bd:5f:92:05:2c:81:b0:c3:d3:80:cd:e1:
-         5c:95:d2:ea:1e:d3:af:d9:93:c2:f4:23:ae:51:b0:a4:82:49:
-         2d:ec:fe:d1:18:e3:a3:53:9f:63:4b:38:dc:54:25:ce:4c:90:
-         37:02:e4:67:41:31:ba:7a:13:1a:68:1e:ed:34:0c:3d:66:ba:
-         a3:3a:71:76:5f:5f:89:a1:cd:95:50:f6:5d:1f:c0:91:31:93:
-         5b:58:af:e7:9b:21:e6:57:b1:f4:d7:dd:c1:84:25:5b:83:f7:
-         5f:c9:89:17:5b:6f:54:f2:8b:ed:47:de:27:57:9e:e9:8c:b3:
-         58:2c:c2:77:25:e1:eb:22:06:d1:f6:c5:f4:d7:1a:3d:00:1c:
-         2e:85:e9:70
+         7e:5b:a7:f2:c7:15:33:73:ce:e4:1e:77:ba:35:8b:44:01:57:
+         b1:db:55:d3:54:95:c6:44:27:89:3f:e5:46:98:de:4a:7e:d9:
+         e7:6c:e8:0d:d5:e2:98:31:07:21:9c:bd:01:47:be:0c:e1:b3:
+         22:1e:ea:da:d4:fc:b5:37:5d:94:de:06:9b:69:a5:77:22:d0:
+         96:80:35:9f:02:a0:cd:41:35:b3:21:94:ca:9b:03:4f:68:18:
+         5e:6d:0d:95:95:17:ab:bd:00:9b:d0:78:f7:38:5e:37:df:33:
+         15:2f:3e:64:27:c8:67:5e:c4:14:92:08:90:55:34:8d:73:d9:
+         66:0c:30:dd:42:ab:71:73:b4:26:28:b1:13:90:7b:0a:10:f2:
+         7c:75:07:36:1f:a5:b6:a5:97:ac:20:c7:83:0c:15:cf:5c:34:
+         df:3f:8d:81:3e:c0:43:2a:ca:6f:c4:86:cc:2f:93:e1:5d:18:
+         68:a4:bd:cc:5b:39:fa:40:fa:d4:a7:8b:7a:5d:b7:59:77:48:
+         9b:ab:e0:71:b2:04:1f:79:ea:d1:cd:d3:24:52:5b:4b:21:2f:
+         84:2e:b4:d6:87:1d:4f:fe:e7:6c:94:ff:d0:02:50:6b:bc:2a:
+         1e:21:a5:ac:3e:73:b5:2f:ba:11:c5:6f:8f:f7:8e:eb:08:11:
+         00:cb:e3:2d
 -----BEGIN CERTIFICATE-----
 MIIC+zCCAeOgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwITEfMB0GA1UEAwwWRCBS
 b290IENBIC0gTXVsdGktcm9vdDAeFw0xNjAxMDMwMDAwMDBaFw0yNjAxMDIwMDAw
 MDBaMBwxGjAYBgNVBAMMEUMgQ0EgLSBNdWx0aS1yb290MIIBIjANBgkqhkiG9w0B
-AQEFAAOCAQ8AMIIBCgKCAQEAth9n5J7b4P/rKXXuaKJOlW7S9p3JttwIGHC1dr+3
-FIvLRsZqLPpD+VST+r2q8O6jIFsqzQj3vpU25Ij4/UN9uPk4tNJOIguLhd5q/m/a
-O0sPJsH4MSI2GZYM74V8cmesTFz5I6Qp2KUctuyV69PCjcuumtcIyLf3oMYoRF8k
-l73K2W2ZmxdHHziz42dqtHXWks1nYiBY8KdGhZRydpjF7Ex1G6F2Z0sfyCNsKnhm
-wqdrr++XMDRgCtuYlDuflTw0tjVAEvodv2b0e/1mGipJjCRgkQj5YTn5OymYZHs1
-BKn1r40PHucotjAytF/UKRZ6cI3bubq/6yKYXZTIR+NLEQIDAQABo0IwQDAPBgNV
-HRMBAf8EBTADAQH/MB0GA1UdDgQWBBSQU/WAEfY/G6idjXUNVjvyK8WcRDAOBgNV
-HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAGcRlfS5y0fmUNr9oBN41+G+
-WeyGMuVWPpuP27A7k/vQbrPefhBbtDD3Aug//06ROui4SpReFHv4hOUfYyy0f0/u
-sdXuknl9Y4eg6VcUVxFZGFSL49FRgKcvUfJvQ9KH4VkjLP6DOOEl2rU0rzMXZIAI
-tr1fkgUsgbDD04DN4VyV0uoe06/Zk8L0I65RsKSCSS3s/tEY46NTn2NLONxUJc5M
-kDcC5GdBMbp6ExpoHu00DD1muqM6cXZfX4mhzZVQ9l0fwJExk1tYr+ebIeZXsfTX
-3cGEJVuD91/JiRdbb1Tyi+1H3idXnumMs1gswncl4esiBtH2xfTXGj0AHC6F6XA=
+AQEFAAOCAQ8AMIIBCgKCAQEAssQW3AeI7H6msyXIe5zgBx5AqUDATchzJ+qI2Fga
+GhLjmmJBTKHpsc7GsvY69ok/QOYP+xVLy9KNjrZEqmP6O8XMr4YFcKrs9LN5BOY+
+JezsKdbJi3sTBaf/UVurTLzQ5L1hGtIn8S5f9FGBxCO6IMMUCLS+eEm1Ex9p/fan
+WZGEqZkQyJxjnpnC8j1hnWpu1CabiKraZrMNxpkDFhM6pJr/CD5Z36dEtxeZP2N/
+OgV+zmR4NOYAd2nmAySnEvPoqFArVRb6bmXGKFiCpCB+aCLpgZ6i6A/Wh8Jz3cIM
+zKNHVBH1PdxRUleyzneLeqyn8ComNuYmuWqD2rJvwPYe8wIDAQABo0IwQDAPBgNV
+HRMBAf8EBTADAQH/MB0GA1UdDgQWBBTj0QWYTGhTwtwA7qzlqLj8uXLZZzAOBgNV
+HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAH5bp/LHFTNzzuQed7o1i0QB
+V7HbVdNUlcZEJ4k/5UaY3kp+2eds6A3V4pgxByGcvQFHvgzhsyIe6trU/LU3XZTe
+BptppXci0JaANZ8CoM1BNbMhlMqbA09oGF5tDZWVF6u9AJvQePc4XjffMxUvPmQn
+yGdexBSSCJBVNI1z2WYMMN1Cq3FztCYosROQewoQ8nx1BzYfpball6wgx4MMFc9c
+NN8/jYE+wEMqym/Ehswvk+FdGGikvcxbOfpA+tSni3pdt1l3SJur4HGyBB956tHN
+0yRSW0shL4QutNaHHU/+52yU/9ACUGu8Kh4hpaw+c7UvuhHFb4/3jusIEQDL4y0=
 -----END CERTIFICATE-----
 Certificate:
     Data:
@@ -240,64 +242,64 @@
             Public Key Algorithm: rsaEncryption
                 Public-Key: (2048 bit)
                 Modulus:
-                    00:cd:cf:d9:70:03:4f:4f:f1:9f:93:a1:2c:6e:cb:
-                    2f:20:d7:67:29:ce:99:02:4e:db:7d:6b:5e:6a:3a:
-                    a1:d2:7f:cd:f9:58:bd:34:fe:af:8d:8a:05:34:a2:
-                    67:16:ae:94:88:3b:77:3f:f2:a0:a5:46:2e:05:2e:
-                    b8:a7:2f:ff:e0:df:1d:b8:1e:31:6f:57:f9:aa:55:
-                    9c:83:aa:04:94:cd:e4:0f:99:f4:74:c1:38:8d:4c:
-                    90:67:ba:7e:92:42:59:ff:14:d6:4e:22:31:78:04:
-                    89:63:7d:84:fa:60:e7:d2:0d:61:0b:d8:a5:20:b3:
-                    8a:ce:f1:ef:b7:b0:b5:a6:81:d0:47:50:fb:5a:09:
-                    34:e1:a0:e3:6b:cf:e8:26:38:4d:cb:70:ae:4c:96:
-                    2c:9e:46:18:0c:e3:11:9f:8d:8a:65:c5:b1:03:5c:
-                    61:d9:35:a8:5d:29:08:7c:45:2e:38:13:dc:b0:72:
-                    a6:e6:29:04:85:6a:6d:fd:74:af:60:6c:24:51:e2:
-                    3a:58:38:c1:0f:b2:4e:ac:8e:63:81:36:01:9f:02:
-                    04:de:54:53:4c:fa:5f:67:44:db:f0:ed:ce:3f:f0:
-                    5b:e7:75:b3:72:d5:e8:76:9c:24:73:2b:0c:d9:7c:
-                    dd:85:a8:61:b9:42:d1:69:35:04:88:03:8a:c2:aa:
-                    10:cb
+                    00:b4:b2:8e:83:7f:3b:8b:0f:9f:71:37:18:78:d0:
+                    f5:bc:07:ac:d8:eb:bf:f6:7c:c0:65:dc:00:bf:83:
+                    f7:e4:5e:97:9f:db:24:e4:c1:f9:31:70:b2:51:44:
+                    2c:27:05:6a:1f:1e:35:9c:ea:c4:eb:f8:0a:c4:4b:
+                    14:30:89:e8:75:93:fb:96:32:bc:0e:64:ca:11:74:
+                    4a:ac:26:a0:9c:09:cd:6e:43:cf:6c:56:03:44:ab:
+                    53:81:66:8d:5a:ad:75:1b:31:23:9f:fd:5e:8c:10:
+                    cd:e9:e9:05:80:41:5e:b8:f1:96:3d:5b:17:b2:e1:
+                    a8:47:44:eb:82:30:5e:7a:fe:8f:11:bb:b8:31:8e:
+                    98:4c:a9:f3:2c:91:59:78:f4:63:1c:47:ad:6a:96:
+                    5e:87:39:f3:17:9b:d6:9c:e9:e1:3c:0e:ef:8a:d8:
+                    7e:c3:2d:33:d9:eb:26:29:1d:8a:66:ef:b9:8d:c3:
+                    b1:51:3a:75:56:1b:b8:a9:08:e7:10:db:37:70:c4:
+                    6c:32:c0:e1:2b:f4:84:12:a5:cf:49:83:e1:5a:40:
+                    ab:db:f9:23:c5:7d:c0:03:ac:0e:3e:be:7c:42:92:
+                    fb:b7:71:91:37:04:92:4e:d5:92:31:cf:1b:cd:e4:
+                    27:e5:85:98:ac:20:95:5d:6d:4e:90:fa:c7:6c:2b:
+                    fd:41
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Basic Constraints: critical
                 CA:TRUE
             X509v3 Subject Key Identifier: 
-                FA:45:82:63:D1:67:F2:93:F4:6A:6B:44:44:74:1A:D2:B0:CD:12:F6
+                69:E7:FF:33:A6:6B:A0:AD:5A:F1:D3:15:4F:9E:F7:C5:16:2E:C4:B6
             X509v3 Key Usage: critical
                 Certificate Sign, CRL Sign
     Signature Algorithm: sha256WithRSAEncryption
-         ac:1c:7c:de:1a:4a:31:54:77:c5:94:7d:6a:0b:9d:c2:c9:d4:
-         3b:2d:71:e4:99:df:ca:02:5c:a0:1c:1c:22:7d:f2:a5:0e:97:
-         7c:91:20:12:c5:b7:f5:56:15:8c:1b:44:b2:32:94:8b:e5:b1:
-         c0:0b:f6:c0:b8:b4:cf:b9:27:d8:49:52:fc:81:9f:48:2a:08:
-         b8:94:a1:3f:78:fe:20:66:f5:ed:3f:61:f6:f7:23:5c:4c:36:
-         49:48:10:07:de:40:62:eb:3b:bb:6b:4b:8e:e4:a7:b3:75:33:
-         2f:4d:11:58:76:1e:1c:d9:b9:dc:1c:33:da:82:2b:5f:fc:51:
-         f1:26:35:7d:5e:eb:67:ba:da:2c:f2:d7:6e:88:b6:a1:34:ed:
-         07:d2:a5:e4:ac:d6:9b:7c:6c:6e:77:aa:11:4e:d0:60:fa:86:
-         94:a0:74:00:60:8b:1c:0b:3e:5d:05:c9:b9:8c:b4:6f:a5:e7:
-         82:c0:6a:ef:60:73:de:1f:74:20:aa:67:c7:d9:c2:81:c7:4c:
-         d7:c9:57:e4:7d:db:80:bd:7d:4f:39:a4:77:d3:2e:65:79:87:
-         ae:05:f7:9c:28:ed:e8:4e:f6:ac:38:3f:8f:36:bb:ae:5e:42:
-         71:d5:a9:5b:a7:df:42:9f:6b:e0:ec:3e:3b:6e:36:11:9b:34:
-         a8:66:ff:d5
+         55:ec:3a:cd:87:dc:96:54:23:68:65:f7:a6:91:3c:37:f0:44:
+         94:2e:2f:3a:af:2c:0d:f4:09:f6:52:69:4f:ad:ac:83:6c:76:
+         76:72:2b:c0:48:ea:c9:76:c0:f5:7a:1e:73:ba:3c:f3:41:93:
+         b4:4b:a5:6a:a3:87:f5:c7:6f:e9:55:ce:e0:8b:8c:83:e6:f0:
+         e0:1c:e8:6a:8f:3b:67:b6:cd:35:6d:0b:1c:16:bf:38:fd:9d:
+         d8:95:a9:3c:b9:4c:05:19:71:f4:a0:2c:1f:83:18:5a:f3:5a:
+         ea:80:49:70:cc:49:84:63:7c:a9:4d:cb:1f:df:96:f2:c4:2c:
+         2c:e8:b0:75:69:8c:a9:71:7e:27:6a:fe:22:c6:77:e0:77:f4:
+         98:05:29:45:18:75:a3:f0:43:40:b2:8d:52:cb:2e:46:fb:37:
+         bb:c6:68:20:c2:2e:01:82:51:f0:00:3a:89:40:9b:ab:9c:c3:
+         5c:f2:a3:3b:f7:00:98:4d:bd:a7:74:37:f6:74:c7:6e:42:4b:
+         aa:8c:cc:c7:85:b2:4b:78:cb:8c:03:7c:e5:85:75:32:a9:89:
+         49:da:ed:3d:9e:5b:a2:c9:b2:2a:08:06:6d:cf:df:83:d4:a9:
+         3d:e9:44:de:70:9c:43:e3:35:24:dd:85:ed:7c:37:4e:02:44:
+         d2:5d:7a:ad
 -----BEGIN CERTIFICATE-----
 MIIDADCCAeigAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwITEfMB0GA1UEAwwWRCBS
 b290IENBIC0gTXVsdGktcm9vdDAeFw0xNjAxMDIwMDAwMDBaFw0yNjAxMDIwMDAw
 MDBaMCExHzAdBgNVBAMMFkQgUm9vdCBDQSAtIE11bHRpLXJvb3QwggEiMA0GCSqG
-SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDNz9lwA09P8Z+ToSxuyy8g12cpzpkCTtt9
-a15qOqHSf835WL00/q+NigU0omcWrpSIO3c/8qClRi4FLrinL//g3x24HjFvV/mq
-VZyDqgSUzeQPmfR0wTiNTJBnun6SQln/FNZOIjF4BIljfYT6YOfSDWEL2KUgs4rO
-8e+3sLWmgdBHUPtaCTThoONrz+gmOE3LcK5MliyeRhgM4xGfjYplxbEDXGHZNahd
-KQh8RS44E9ywcqbmKQSFam39dK9gbCRR4jpYOMEPsk6sjmOBNgGfAgTeVFNM+l9n
-RNvw7c4/8FvndbNy1eh2nCRzKwzZfN2FqGG5QtFpNQSIA4rCqhDLAgMBAAGjQjBA
-MA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFPpFgmPRZ/KT9GprRER0GtKwzRL2
-MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEArBx83hpKMVR3xZR9
-agudwsnUOy1x5JnfygJcoBwcIn3ypQ6XfJEgEsW39VYVjBtEsjKUi+WxwAv2wLi0
-z7kn2ElS/IGfSCoIuJShP3j+IGb17T9h9vcjXEw2SUgQB95AYus7u2tLjuSns3Uz
-L00RWHYeHNm53Bwz2oIrX/xR8SY1fV7rZ7raLPLXboi2oTTtB9Kl5KzWm3xsbneq
-EU7QYPqGlKB0AGCLHAs+XQXJuYy0b6XngsBq72Bz3h90IKpnx9nCgcdM18lX5H3b
-gL19Tzmkd9MuZXmHrgX3nCjt6E72rDg/jza7rl5CcdWpW6ffQp9r4Ow+O242EZs0
-qGb/1Q==
+SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC0so6DfzuLD59xNxh40PW8B6zY67/2fMBl
+3AC/g/fkXpef2yTkwfkxcLJRRCwnBWofHjWc6sTr+ArESxQwieh1k/uWMrwOZMoR
+dEqsJqCcCc1uQ89sVgNEq1OBZo1arXUbMSOf/V6MEM3p6QWAQV648ZY9Wxey4ahH
+ROuCMF56/o8Ru7gxjphMqfMskVl49GMcR61qll6HOfMXm9ac6eE8Du+K2H7DLTPZ
+6yYpHYpm77mNw7FROnVWG7ipCOcQ2zdwxGwywOEr9IQSpc9Jg+FaQKvb+SPFfcAD
+rA4+vnxCkvu3cZE3BJJO1ZIxzxvN5CflhZisIJVdbU6Q+sdsK/1BAgMBAAGjQjBA
+MA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFGnn/zOma6CtWvHTFU+e98UWLsS2
+MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAVew6zYfcllQjaGX3
+ppE8N/BElC4vOq8sDfQJ9lJpT62sg2x2dnIrwEjqyXbA9Xoec7o880GTtEulaqOH
+9cdv6VXO4IuMg+bw4Bzoao87Z7bNNW0LHBa/OP2d2JWpPLlMBRlx9KAsH4MYWvNa
+6oBJcMxJhGN8qU3LH9+W8sQsLOiwdWmMqXF+J2r+IsZ34Hf0mAUpRRh1o/BDQLKN
+UssuRvs3u8ZoIMIuAYJR8AA6iUCbq5zDXPKjO/cAmE29p3Q39nTHbkJLqozMx4Wy
+S3jLjAN85YV1MqmJSdrtPZ5bosmyKggGbc/fg9SpPelE3nCcQ+M1JN2F7Xw3TgJE
+0l16rQ==
 -----END CERTIFICATE-----
diff --git a/net/data/ssl/certificates/multi-root-chain2.pem b/net/data/ssl/certificates/multi-root-chain2.pem
index e7b91143..ea5a7f0 100644
--- a/net/data/ssl/certificates/multi-root-chain2.pem
+++ b/net/data/ssl/certificates/multi-root-chain2.pem
@@ -5,78 +5,80 @@
     Signature Algorithm: sha256WithRSAEncryption
         Issuer: CN=B CA - Multi-root
         Validity
-            Not Before: Mar 11 01:37:16 2016 GMT
-            Not After : Mar  9 01:37:16 2026 GMT
+            Not Before: Feb 28 23:46:47 2017 GMT
+            Not After : Feb 26 23:46:47 2027 GMT
         Subject: C=US, ST=California, L=Mountain View, O=Test CA, CN=127.0.0.1
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
                 Public-Key: (2048 bit)
                 Modulus:
-                    00:c8:27:1c:19:81:c0:a7:30:93:03:1c:f8:21:b8:
-                    2f:8a:22:b4:89:0f:da:b1:40:95:df:dc:46:53:fc:
-                    6f:36:26:66:5a:53:6d:45:78:c2:39:16:9a:3f:82:
-                    8b:ba:c5:b0:78:a8:18:bc:d5:a7:92:a5:e6:ac:e2:
-                    0c:81:d0:94:e5:0c:ec:5e:03:0c:17:c5:35:2a:7b:
-                    ab:86:eb:bf:e8:62:0a:8f:b0:25:b2:70:f5:11:8c:
-                    16:4f:c1:76:44:e5:75:e8:93:4f:e9:e7:c4:e4:42:
-                    0a:08:be:73:2c:cb:8f:73:6a:40:77:eb:33:60:ac:
-                    be:c5:27:fd:b1:4f:88:4b:15:af:98:fd:32:53:ae:
-                    b0:2a:0c:b2:f5:05:f3:3a:06:0d:6e:5c:fe:83:fc:
-                    e3:60:ae:99:8e:a1:21:c2:72:02:e6:f4:49:57:e6:
-                    91:31:2e:be:92:a1:ad:f8:71:31:64:74:10:33:d0:
-                    a7:0c:ed:18:c7:b2:50:71:fc:b9:b6:ae:95:a0:8d:
-                    ac:1f:3c:d5:79:a7:a9:88:50:b6:02:cd:68:60:24:
-                    45:9b:b6:e9:82:08:d9:9c:d4:7e:29:7d:2b:d9:ae:
-                    57:7f:62:6a:56:96:8b:4a:33:9e:5f:93:82:b0:d1:
-                    05:03:26:cd:15:f4:87:7f:6a:9a:df:e9:01:b5:d4:
-                    c9:11
+                    00:a4:18:86:3f:09:63:9c:d4:c0:06:45:a5:91:7f:
+                    e7:a7:b8:3d:c7:ff:0d:e8:39:f5:43:27:a7:44:2a:
+                    3b:53:03:e3:cd:13:23:46:5f:e0:27:f0:a3:7a:25:
+                    82:b0:52:bb:03:4f:99:e3:2c:1b:6f:54:05:0f:7f:
+                    4f:74:f9:ad:b2:88:85:43:63:06:ac:91:f1:19:b7:
+                    da:7a:42:68:6a:68:a5:e0:02:44:23:eb:d1:05:0d:
+                    3d:58:31:ee:ba:20:9e:16:11:f5:ae:b5:c3:21:cc:
+                    84:e7:1a:d2:c2:8c:7e:44:93:36:bd:6c:0c:07:35:
+                    f2:4e:57:3f:b3:cf:21:5a:ff:16:02:e9:61:f4:cc:
+                    4a:5a:24:da:55:fc:c6:da:44:d6:b7:2a:4e:31:bf:
+                    a0:80:24:55:ed:5c:bc:6b:84:12:a4:03:cc:b2:c2:
+                    db:ef:1e:08:bd:a3:bf:ef:fc:3d:53:38:b9:00:8a:
+                    d6:40:1a:cc:f2:6a:ab:e7:4b:67:1c:ae:ff:6d:43:
+                    12:08:c6:97:4b:73:df:85:cf:2a:a5:6e:ce:22:02:
+                    cb:63:6c:3f:00:aa:3b:b0:87:9b:d5:13:09:32:4c:
+                    bd:71:79:ff:04:b1:9a:8d:2d:a0:0a:65:d5:1e:53:
+                    c4:eb:0e:14:c0:b9:f3:8f:6f:64:b4:1d:11:a7:40:
+                    e7:61
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Basic Constraints: critical
                 CA:FALSE
             X509v3 Subject Key Identifier: 
-                FB:91:A9:5F:BC:27:81:98:55:30:BF:57:32:4D:B9:DA:56:DD:52:2C
+                28:6F:58:36:8F:1B:C5:99:18:5B:DC:A5:86:AF:89:F2:B4:3E:AF:51
             X509v3 Authority Key Identifier: 
-                keyid:90:CB:53:EE:36:0A:5A:B0:93:38:C9:11:B7:AC:FD:27:71:99:DC:81
+                keyid:D0:8D:1F:B2:BC:29:96:73:EF:0C:7A:C2:A4:06:96:CF:D5:8C:31:DB
 
             X509v3 Extended Key Usage: 
                 TLS Web Server Authentication, TLS Web Client Authentication
+            X509v3 Subject Alternative Name: 
+                IP Address:127.0.0.1
     Signature Algorithm: sha256WithRSAEncryption
-         b9:31:7a:95:b2:ba:3a:b4:f1:16:76:df:eb:d5:b9:af:67:b1:
-         9d:8a:27:04:9b:61:6f:42:3f:c2:b3:cd:65:c4:86:cb:90:fb:
-         9d:3a:ed:fc:b8:74:da:d7:6a:6c:2f:17:68:d1:73:58:f1:a2:
-         bb:8f:d6:b0:a8:7f:b6:a8:b0:74:d1:ea:c4:62:ed:bc:1e:ef:
-         02:6b:d5:e8:2d:15:78:16:1e:90:fa:f4:29:5a:a8:43:ad:d2:
-         58:40:b4:1c:60:4e:cd:bc:6f:1a:39:e4:46:b2:58:93:96:5a:
-         a8:a4:c4:31:73:ed:89:c4:81:27:e1:4c:66:20:7c:27:c4:f9:
-         61:ff:d1:d5:a5:02:93:4c:06:fa:15:33:7a:1f:5f:eb:29:b2:
-         b5:6a:cd:7e:d6:d7:b7:51:a7:01:2f:22:9f:9e:7e:81:98:c4:
-         72:11:36:2c:e7:c6:d0:f0:7d:98:36:ea:b7:a0:aa:13:8f:6e:
-         ae:41:59:9b:e6:c9:bc:9c:e8:93:f5:0c:4e:ca:b4:dd:e3:01:
-         fe:23:6e:fb:fa:b3:61:66:58:f5:fc:07:16:1d:a9:52:ec:a0:
-         29:61:a4:39:ed:41:50:a3:a2:33:72:0e:3c:03:e1:0a:1a:1a:
-         cf:22:73:09:d7:ea:e8:15:fc:73:3c:d4:4e:34:6c:b4:18:94:
-         c4:d3:6e:12
+         07:8f:f9:c6:33:3c:bc:74:20:21:92:46:7a:c5:df:76:18:47:
+         63:0c:5e:e8:f3:97:ec:37:83:0b:4d:a4:1c:6b:0b:a2:28:db:
+         5c:17:d9:91:77:00:4a:db:46:f9:68:ec:2a:f8:b5:82:0c:00:
+         d1:88:0c:7c:b4:2d:e9:48:f5:a2:9d:a9:d5:bb:db:9d:56:96:
+         c5:6c:46:da:23:a3:66:80:a5:9b:93:d0:df:9c:00:75:ac:48:
+         ea:48:b4:22:ee:ff:db:eb:bb:8f:f0:de:16:a1:99:98:85:4c:
+         b3:66:dd:22:96:96:97:48:ae:8a:2d:e9:a5:1c:5c:d9:dd:31:
+         3f:58:7c:bb:2b:db:86:6a:53:e5:af:6d:85:3a:ca:92:5d:56:
+         e2:02:90:d7:eb:98:0f:d8:ba:2a:d1:26:bb:82:5b:80:d5:2d:
+         52:d7:40:4d:0d:0d:1e:fe:c2:89:be:e2:80:4d:cd:91:dc:f3:
+         fa:19:25:3e:ba:a8:cf:48:d3:b6:35:a5:96:6e:a5:12:d1:65:
+         65:a9:92:6b:d0:fc:05:25:7c:fb:76:48:38:15:7e:4f:95:03:
+         b0:c3:55:89:bc:59:be:de:3c:fb:4b:5a:f1:3b:00:c1:03:59:
+         6c:b3:8b:21:7e:84:75:30:19:8c:19:f6:99:40:ec:87:43:3b:
+         89:d0:f5:6d
 -----BEGIN CERTIFICATE-----
-MIIDZzCCAk+gAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwHDEaMBgGA1UEAwwRQiBD
-QSAtIE11bHRpLXJvb3QwHhcNMTYwMzExMDEzNzE2WhcNMjYwMzA5MDEzNzE2WjBg
+MIIDeTCCAmGgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwHDEaMBgGA1UEAwwRQiBD
+QSAtIE11bHRpLXJvb3QwHhcNMTcwMjI4MjM0NjQ3WhcNMjcwMjI2MjM0NjQ3WjBg
 MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91
 bnRhaW4gVmlldzEQMA4GA1UECgwHVGVzdCBDQTESMBAGA1UEAwwJMTI3LjAuMC4x
-MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyCccGYHApzCTAxz4Ibgv
-iiK0iQ/asUCV39xGU/xvNiZmWlNtRXjCORaaP4KLusWweKgYvNWnkqXmrOIMgdCU
-5QzsXgMMF8U1Knurhuu/6GIKj7AlsnD1EYwWT8F2ROV16JNP6efE5EIKCL5zLMuP
-c2pAd+szYKy+xSf9sU+ISxWvmP0yU66wKgyy9QXzOgYNblz+g/zjYK6ZjqEhwnIC
-5vRJV+aRMS6+kqGt+HExZHQQM9CnDO0Yx7JQcfy5tq6VoI2sHzzVeaepiFC2As1o
-YCRFm7bpggjZnNR+KX0r2a5Xf2JqVpaLSjOeX5OCsNEFAybNFfSHf2qa3+kBtdTJ
-EQIDAQABo28wbTAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBT7kalfvCeBmFUwv1cy
-TbnaVt1SLDAfBgNVHSMEGDAWgBSQy1PuNgpasJM4yRG3rP0ncZncgTAdBgNVHSUE
-FjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBALkxepWy
-ujq08RZ23+vVua9nsZ2KJwSbYW9CP8KzzWXEhsuQ+5067fy4dNrXamwvF2jRc1jx
-oruP1rCof7aosHTR6sRi7bwe7wJr1egtFXgWHpD69ClaqEOt0lhAtBxgTs28bxo5
-5EayWJOWWqikxDFz7YnEgSfhTGYgfCfE+WH/0dWlApNMBvoVM3ofX+spsrVqzX7W
-17dRpwEvIp+efoGYxHIRNiznxtDwfZg26regqhOPbq5BWZvmybyc6JP1DE7KtN3j
-Af4jbvv6s2FmWPX8BxYdqVLsoClhpDntQVCjojNyDjwD4QoaGs8icwnX6ugV/HM8
-1E40bLQYlMTTbhI=
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApBiGPwljnNTABkWlkX/n
+p7g9x/8N6Dn1QyenRCo7UwPjzRMjRl/gJ/CjeiWCsFK7A0+Z4ywbb1QFD39PdPmt
+soiFQ2MGrJHxGbfaekJoamil4AJEI+vRBQ09WDHuuiCeFhH1rrXDIcyE5xrSwox+
+RJM2vWwMBzXyTlc/s88hWv8WAulh9MxKWiTaVfzG2kTWtypOMb+ggCRV7Vy8a4QS
+pAPMssLb7x4IvaO/7/w9Uzi5AIrWQBrM8mqr50tnHK7/bUMSCMaXS3Pfhc8qpW7O
+IgLLY2w/AKo7sIeb1RMJMky9cXn/BLGajS2gCmXVHlPE6w4UwLnzj29ktB0Rp0Dn
+YQIDAQABo4GAMH4wDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUKG9YNo8bxZkYW9yl
+hq+J8rQ+r1EwHwYDVR0jBBgwFoAU0I0fsrwplnPvDHrCpAaWz9WMMdswHQYDVR0l
+BBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA8GA1UdEQQIMAaHBH8AAAEwDQYJKoZI
+hvcNAQELBQADggEBAAeP+cYzPLx0ICGSRnrF33YYR2MMXujzl+w3gwtNpBxrC6Io
+21wX2ZF3AErbRvlo7Cr4tYIMANGIDHy0LelI9aKdqdW7251WlsVsRtojo2aApZuT
+0N+cAHWsSOpItCLu/9vru4/w3hahmZiFTLNm3SKWlpdIroot6aUcXNndMT9YfLsr
+24ZqU+WvbYU6ypJdVuICkNfrmA/YuirRJruCW4DVLVLXQE0NDR7+wom+4oBNzZHc
+8/oZJT66qM9I07Y1pZZupRLRZWWpkmvQ/AUlfPt2SDgVfk+VA7DDVYm8Wb7ePPtL
+WvE7AMEDWWyziyF+hHUwGYwZ9plA7IdDO4nQ9W0=
 -----END CERTIFICATE-----
 Certificate:
     Data:
@@ -92,65 +94,65 @@
             Public Key Algorithm: rsaEncryption
                 Public-Key: (2048 bit)
                 Modulus:
-                    00:ca:e9:f3:21:f4:a0:e7:ba:82:8c:7f:b3:98:44:
-                    20:4a:9a:8b:f9:e5:0c:99:c4:22:72:f7:57:7c:1e:
-                    cc:56:4c:c3:f5:fd:1e:90:a5:1c:bf:2c:c4:c4:29:
-                    29:38:cc:26:9e:1a:1d:e3:e4:db:97:58:35:14:e8:
-                    e2:db:37:05:1c:32:f7:bb:19:22:c2:37:3f:01:76:
-                    8c:17:23:ca:fc:10:69:b4:d1:74:27:b6:10:7e:b7:
-                    c1:07:a2:a1:af:18:4d:5c:2e:13:72:a9:fb:64:b1:
-                    e7:9f:49:41:3c:dc:b8:5f:94:e6:68:05:a5:1f:c8:
-                    56:84:e2:e5:6a:84:71:9c:b8:ac:3e:ec:8e:0c:d2:
-                    f2:5f:11:fd:f4:7f:40:a7:3b:08:01:bb:fd:6f:d0:
-                    a9:16:1d:14:a1:28:20:30:98:ba:1e:22:4e:5b:09:
-                    b9:c1:df:17:60:1b:80:43:97:49:69:cd:6a:4e:58:
-                    08:9c:dc:29:57:3f:1b:bf:d8:5f:32:94:ae:97:b2:
-                    d4:8d:50:1a:d1:8b:03:84:00:fd:87:d9:2e:ed:91:
-                    3d:3f:b7:89:54:46:0a:cd:db:10:62:80:47:60:21:
-                    b3:1d:0e:bc:41:4d:86:d4:9d:52:1b:53:82:1a:9f:
-                    46:91:98:1e:ed:9f:da:69:16:64:24:1c:de:f8:b3:
-                    34:69
+                    00:ca:6c:54:ab:3c:54:33:6c:d7:04:c4:4b:c4:39:
+                    32:db:7a:49:e4:e1:e7:60:c7:35:33:08:59:ba:62:
+                    bf:49:d6:05:1f:07:b8:b6:bd:38:2f:6b:a7:e5:8d:
+                    de:79:27:d8:36:58:92:69:cc:db:8e:6a:89:b4:79:
+                    ab:cf:98:53:08:12:17:9e:51:15:bc:e7:8f:e5:93:
+                    d9:1a:2e:68:a9:93:3c:d3:7a:75:a4:5c:c2:fc:16:
+                    9b:ba:df:49:5d:73:65:ec:b0:cc:1e:ba:cc:98:39:
+                    d1:4e:b2:d6:5f:e8:7f:24:1a:fa:56:b0:0d:33:46:
+                    22:56:4f:5c:f3:16:ad:55:8a:62:3c:bc:50:c2:3a:
+                    58:3e:70:4d:5a:df:99:ec:c7:a6:2c:8f:2a:a5:2e:
+                    11:b8:58:c5:d5:e8:43:2f:40:a5:20:80:32:2a:76:
+                    5e:06:07:48:6d:44:60:ba:21:72:61:e2:1a:ec:64:
+                    5d:72:72:f1:21:9d:04:2f:61:35:0b:2f:f0:c0:fe:
+                    52:b8:c4:41:9c:b6:13:58:21:81:e3:28:27:4d:6c:
+                    24:a3:20:fb:0f:9c:d4:4f:34:3a:d0:d1:08:84:c4:
+                    40:71:44:4f:e8:be:c5:1f:5d:1c:34:64:0b:6c:1c:
+                    24:fa:a9:83:49:c6:f5:4d:7f:63:c0:1a:a9:77:8a:
+                    c0:43
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Basic Constraints: critical
                 CA:TRUE
             X509v3 Subject Key Identifier: 
-                90:CB:53:EE:36:0A:5A:B0:93:38:C9:11:B7:AC:FD:27:71:99:DC:81
+                D0:8D:1F:B2:BC:29:96:73:EF:0C:7A:C2:A4:06:96:CF:D5:8C:31:DB
             X509v3 Key Usage: critical
                 Certificate Sign, CRL Sign
     Signature Algorithm: sha256WithRSAEncryption
-         97:cd:ae:5a:26:f4:25:f6:c0:8b:08:d8:df:82:35:d8:76:f3:
-         5d:cc:99:bd:ac:70:c9:41:e0:24:c8:fd:e6:4e:41:2c:d4:69:
-         8d:08:25:fd:f3:32:3a:58:0b:d3:58:9c:81:51:bf:97:a4:bc:
-         00:18:1c:4f:1c:54:04:63:e3:72:87:f4:dc:9e:7b:dc:da:5d:
-         e1:ef:59:6b:f0:1f:3d:0c:11:55:1e:9a:1a:d8:8d:bc:7b:18:
-         b7:4f:92:1c:68:73:82:ec:f3:69:48:0a:86:40:4a:a5:6f:ae:
-         8f:10:2e:12:0b:e8:7e:b9:bc:d7:26:f0:cf:f4:0f:5b:77:f2:
-         ff:77:28:b4:5f:5e:ef:65:08:21:b8:f9:1e:56:b9:69:3b:c4:
-         7f:01:88:c9:7c:ca:d0:e2:df:e5:5e:8d:e9:2e:7d:4a:78:04:
-         8b:c1:dc:d4:58:ac:90:fc:5c:8e:48:2b:60:99:63:37:3f:e5:
-         61:da:8f:58:9f:4d:0a:ee:6c:8d:bc:1f:7e:c4:be:0f:32:4b:
-         11:7a:28:bf:dd:d0:a0:40:42:a8:43:4d:0b:2f:01:0e:73:de:
-         1b:a6:df:49:57:58:89:57:c0:23:76:83:f0:9a:0e:83:d9:9b:
-         cb:eb:ac:3f:89:d1:e8:3c:3e:f1:d5:80:0c:38:18:02:5c:5f:
-         e5:68:5e:cf
+         1e:16:7c:d7:d1:ee:63:a9:a2:b1:87:2c:8b:1e:d3:cf:51:14:
+         ed:12:0b:ec:67:2b:7f:3b:0e:8e:3c:50:bb:d1:dc:3b:40:1a:
+         ec:44:30:c4:f6:65:c2:c3:5d:d8:cb:c2:6c:13:2e:5a:2d:76:
+         c6:6b:5d:65:a5:7e:c2:bf:cb:fc:b1:50:b0:43:47:fc:a3:7b:
+         07:d1:77:50:4f:d2:53:98:8f:a2:00:97:13:d9:b7:83:2e:d9:
+         c4:2a:e6:b1:fc:2d:6c:ce:d1:61:73:aa:40:e0:ce:87:74:43:
+         a2:f7:b5:d9:5f:46:79:97:28:c4:de:15:60:3b:3e:3f:3d:1d:
+         14:f4:87:ef:b9:08:09:2a:fb:d0:d5:1b:4f:77:f9:0d:c9:4b:
+         23:32:1c:06:04:a6:83:aa:00:9c:70:c2:2b:01:42:1e:f6:d6:
+         d3:5c:f9:a8:b7:84:9e:44:12:9a:9f:a8:2a:89:56:69:a6:2f:
+         e9:ee:67:e9:7e:32:b5:ef:6b:4e:f0:12:23:fa:85:3e:03:59:
+         94:db:88:99:04:55:c4:d1:df:df:c6:e2:fd:61:c5:f6:af:dc:
+         4c:e4:52:8f:f2:c8:07:39:dd:99:33:49:85:1e:df:e1:1f:08:
+         6b:e0:d2:1b:93:db:32:05:4b:39:ee:b3:f1:b6:af:18:07:a7:
+         24:9c:1e:75
 -----BEGIN CERTIFICATE-----
 MIIC9jCCAd6gAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwHDEaMBgGA1UEAwwRQyBD
 QSAtIE11bHRpLXJvb3QwHhcNMTYwMTA0MDAwMDAwWhcNMjYwMTAyMDAwMDAwWjAc
 MRowGAYDVQQDDBFCIENBIC0gTXVsdGktcm9vdDCCASIwDQYJKoZIhvcNAQEBBQAD
-ggEPADCCAQoCggEBAMrp8yH0oOe6gox/s5hEIEqai/nlDJnEInL3V3wezFZMw/X9
-HpClHL8sxMQpKTjMJp4aHePk25dYNRTo4ts3BRwy97sZIsI3PwF2jBcjyvwQabTR
-dCe2EH63wQeioa8YTVwuE3Kp+2Sx559JQTzcuF+U5mgFpR/IVoTi5WqEcZy4rD7s
-jgzS8l8R/fR/QKc7CAG7/W/QqRYdFKEoIDCYuh4iTlsJucHfF2AbgEOXSWnNak5Y
-CJzcKVc/G7/YXzKUrpey1I1QGtGLA4QA/YfZLu2RPT+3iVRGCs3bEGKAR2Ahsx0O
-vEFNhtSdUhtTghqfRpGYHu2f2mkWZCQc3vizNGkCAwEAAaNCMEAwDwYDVR0TAQH/
-BAUwAwEB/zAdBgNVHQ4EFgQUkMtT7jYKWrCTOMkRt6z9J3GZ3IEwDgYDVR0PAQH/
-BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IBAQCXza5aJvQl9sCLCNjfgjXYdvNdzJm9
-rHDJQeAkyP3mTkEs1GmNCCX98zI6WAvTWJyBUb+XpLwAGBxPHFQEY+Nyh/Tcnnvc
-2l3h71lr8B89DBFVHpoa2I28exi3T5IcaHOC7PNpSAqGQEqlb66PEC4SC+h+ubzX
-JvDP9A9bd/L/dyi0X17vZQghuPkeVrlpO8R/AYjJfMrQ4t/lXo3pLn1KeASLwdzU
-WKyQ/FyOSCtgmWM3P+Vh2o9Yn00K7myNvB9+xL4PMksReii/3dCgQEKoQ00LLwEO
-c94bpt9JV1iJV8AjdoPwmg6D2ZvL66w/idHoPD7x1YAMOBgCXF/laF7P
+ggEPADCCAQoCggEBAMpsVKs8VDNs1wTES8Q5Mtt6SeTh52DHNTMIWbpiv0nWBR8H
+uLa9OC9rp+WN3nkn2DZYkmnM245qibR5q8+YUwgSF55RFbznj+WT2RouaKmTPNN6
+daRcwvwWm7rfSV1zZeywzB66zJg50U6y1l/ofyQa+lawDTNGIlZPXPMWrVWKYjy8
+UMI6WD5wTVrfmezHpiyPKqUuEbhYxdXoQy9ApSCAMip2XgYHSG1EYLohcmHiGuxk
+XXJy8SGdBC9hNQsv8MD+UrjEQZy2E1ghgeMoJ01sJKMg+w+c1E80OtDRCITEQHFE
+T+i+xR9dHDRkC2wcJPqpg0nG9U1/Y8AaqXeKwEMCAwEAAaNCMEAwDwYDVR0TAQH/
+BAUwAwEB/zAdBgNVHQ4EFgQU0I0fsrwplnPvDHrCpAaWz9WMMdswDgYDVR0PAQH/
+BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IBAQAeFnzX0e5jqaKxhyyLHtPPURTtEgvs
+Zyt/Ow6OPFC70dw7QBrsRDDE9mXCw13Yy8JsEy5aLXbGa11lpX7Cv8v8sVCwQ0f8
+o3sH0XdQT9JTmI+iAJcT2beDLtnEKuax/C1sztFhc6pA4M6HdEOi97XZX0Z5lyjE
+3hVgOz4/PR0U9IfvuQgJKvvQ1RtPd/kNyUsjMhwGBKaDqgCccMIrAUIe9tbTXPmo
+t4SeRBKan6gqiVZppi/p7mfpfjK172tO8BIj+oU+A1mU24iZBFXE0d/fxuL9YcX2
+r9xM5FKP8sgHOd2ZM0mFHt/hHwhr4NIbk9syBUs57rPxtq8YB6cknB51
 -----END CERTIFICATE-----
 Certificate:
     Data:
@@ -166,65 +168,65 @@
             Public Key Algorithm: rsaEncryption
                 Public-Key: (2048 bit)
                 Modulus:
-                    00:b6:1f:67:e4:9e:db:e0:ff:eb:29:75:ee:68:a2:
-                    4e:95:6e:d2:f6:9d:c9:b6:dc:08:18:70:b5:76:bf:
-                    b7:14:8b:cb:46:c6:6a:2c:fa:43:f9:54:93:fa:bd:
-                    aa:f0:ee:a3:20:5b:2a:cd:08:f7:be:95:36:e4:88:
-                    f8:fd:43:7d:b8:f9:38:b4:d2:4e:22:0b:8b:85:de:
-                    6a:fe:6f:da:3b:4b:0f:26:c1:f8:31:22:36:19:96:
-                    0c:ef:85:7c:72:67:ac:4c:5c:f9:23:a4:29:d8:a5:
-                    1c:b6:ec:95:eb:d3:c2:8d:cb:ae:9a:d7:08:c8:b7:
-                    f7:a0:c6:28:44:5f:24:97:bd:ca:d9:6d:99:9b:17:
-                    47:1f:38:b3:e3:67:6a:b4:75:d6:92:cd:67:62:20:
-                    58:f0:a7:46:85:94:72:76:98:c5:ec:4c:75:1b:a1:
-                    76:67:4b:1f:c8:23:6c:2a:78:66:c2:a7:6b:af:ef:
-                    97:30:34:60:0a:db:98:94:3b:9f:95:3c:34:b6:35:
-                    40:12:fa:1d:bf:66:f4:7b:fd:66:1a:2a:49:8c:24:
-                    60:91:08:f9:61:39:f9:3b:29:98:64:7b:35:04:a9:
-                    f5:af:8d:0f:1e:e7:28:b6:30:32:b4:5f:d4:29:16:
-                    7a:70:8d:db:b9:ba:bf:eb:22:98:5d:94:c8:47:e3:
-                    4b:11
+                    00:b2:c4:16:dc:07:88:ec:7e:a6:b3:25:c8:7b:9c:
+                    e0:07:1e:40:a9:40:c0:4d:c8:73:27:ea:88:d8:58:
+                    1a:1a:12:e3:9a:62:41:4c:a1:e9:b1:ce:c6:b2:f6:
+                    3a:f6:89:3f:40:e6:0f:fb:15:4b:cb:d2:8d:8e:b6:
+                    44:aa:63:fa:3b:c5:cc:af:86:05:70:aa:ec:f4:b3:
+                    79:04:e6:3e:25:ec:ec:29:d6:c9:8b:7b:13:05:a7:
+                    ff:51:5b:ab:4c:bc:d0:e4:bd:61:1a:d2:27:f1:2e:
+                    5f:f4:51:81:c4:23:ba:20:c3:14:08:b4:be:78:49:
+                    b5:13:1f:69:fd:f6:a7:59:91:84:a9:99:10:c8:9c:
+                    63:9e:99:c2:f2:3d:61:9d:6a:6e:d4:26:9b:88:aa:
+                    da:66:b3:0d:c6:99:03:16:13:3a:a4:9a:ff:08:3e:
+                    59:df:a7:44:b7:17:99:3f:63:7f:3a:05:7e:ce:64:
+                    78:34:e6:00:77:69:e6:03:24:a7:12:f3:e8:a8:50:
+                    2b:55:16:fa:6e:65:c6:28:58:82:a4:20:7e:68:22:
+                    e9:81:9e:a2:e8:0f:d6:87:c2:73:dd:c2:0c:cc:a3:
+                    47:54:11:f5:3d:dc:51:52:57:b2:ce:77:8b:7a:ac:
+                    a7:f0:2a:26:36:e6:26:b9:6a:83:da:b2:6f:c0:f6:
+                    1e:f3
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Basic Constraints: critical
                 CA:TRUE
             X509v3 Subject Key Identifier: 
-                90:53:F5:80:11:F6:3F:1B:A8:9D:8D:75:0D:56:3B:F2:2B:C5:9C:44
+                E3:D1:05:98:4C:68:53:C2:DC:00:EE:AC:E5:A8:B8:FC:B9:72:D9:67
             X509v3 Key Usage: critical
                 Certificate Sign, CRL Sign
     Signature Algorithm: sha256WithRSAEncryption
-         43:35:08:cc:aa:f8:10:9f:9e:fa:ab:24:dc:c6:e6:9a:23:52:
-         c9:4c:81:33:ba:64:b2:86:a8:29:f4:1f:5a:fa:5a:c4:91:56:
-         16:d1:f9:84:96:89:8c:ac:1f:b6:ea:2f:cb:12:f4:92:ed:3b:
-         85:09:eb:f3:7a:2e:09:39:ec:ee:09:4b:fa:86:3e:62:40:0e:
-         57:72:07:de:fa:53:45:ac:40:1c:0d:0b:4a:67:9a:f7:39:ce:
-         33:5e:d0:17:0b:8a:83:ae:33:6f:96:c0:f0:7a:ac:07:36:c5:
-         86:a9:db:93:aa:2e:fa:71:d1:1a:dd:82:2a:f8:1c:30:2a:b9:
-         7d:29:fa:75:62:76:7c:15:15:75:af:78:6c:7c:53:ae:2e:80:
-         14:0d:0b:eb:0f:b1:6d:fa:df:72:0b:6f:f0:90:96:18:71:df:
-         76:1d:8c:f1:d5:c0:4f:ab:38:1a:eb:e6:a1:dd:1d:dc:60:d4:
-         da:7f:40:db:17:fc:4a:56:65:3a:86:60:83:87:b3:f6:3b:a8:
-         85:ac:2b:14:c2:26:77:8f:ee:a4:6f:11:f2:27:08:3f:bf:86:
-         4a:e3:bd:ef:6b:51:ec:72:a7:51:08:47:16:f8:d3:d7:b1:8d:
-         a1:b1:ca:d3:cd:fd:56:0a:2c:2f:62:27:8c:e1:ff:88:83:ff:
-         83:ab:87:70
+         0d:37:a8:9e:12:c9:fb:45:a2:b9:82:07:4a:2a:34:d2:3b:1d:
+         84:70:b1:4a:85:37:7e:64:31:45:c3:02:9d:32:4e:92:a4:97:
+         72:ed:1d:f2:c3:26:c8:3f:90:e4:24:f4:6e:4b:33:71:98:bc:
+         68:25:26:cc:de:c1:46:a6:a8:83:60:fc:6e:c0:72:98:8f:ce:
+         38:6e:69:9d:ab:d1:5a:f0:a6:c8:07:a1:09:b3:8c:03:09:7b:
+         44:62:73:15:85:71:5f:2c:0a:33:78:f2:a3:10:85:1e:6b:46:
+         d1:a5:f1:9c:13:ba:f7:95:41:a0:fb:de:c9:09:e1:72:a4:92:
+         ff:33:e4:81:25:10:af:90:17:79:df:54:ea:b9:87:0e:f8:6d:
+         09:55:10:46:4c:87:36:37:2f:c0:86:03:ee:7a:b4:d3:27:22:
+         22:d5:9c:2e:e6:38:f0:f4:84:5c:ca:b7:9b:4d:6a:1c:57:7e:
+         24:07:35:13:a0:f9:d6:a3:aa:29:cb:e0:8a:b0:86:1c:41:24:
+         b1:ed:04:30:71:2b:99:d7:0a:a4:51:53:b1:76:2e:be:63:5b:
+         7c:8e:d5:8f:fa:f3:99:58:7d:ce:30:07:5d:1e:ed:e6:bc:0a:
+         d1:a7:cc:17:94:e7:d1:67:07:7c:37:6d:3f:c2:8b:04:9e:77:
+         fb:5b:9c:2d
 -----BEGIN CERTIFICATE-----
 MIIC+zCCAeOgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwITEfMB0GA1UEAwwWRSBS
 b290IENBIC0gTXVsdGktcm9vdDAeFw0xNjAxMDUwMDAwMDBaFw0yNjAxMDIwMDAw
 MDBaMBwxGjAYBgNVBAMMEUMgQ0EgLSBNdWx0aS1yb290MIIBIjANBgkqhkiG9w0B
-AQEFAAOCAQ8AMIIBCgKCAQEAth9n5J7b4P/rKXXuaKJOlW7S9p3JttwIGHC1dr+3
-FIvLRsZqLPpD+VST+r2q8O6jIFsqzQj3vpU25Ij4/UN9uPk4tNJOIguLhd5q/m/a
-O0sPJsH4MSI2GZYM74V8cmesTFz5I6Qp2KUctuyV69PCjcuumtcIyLf3oMYoRF8k
-l73K2W2ZmxdHHziz42dqtHXWks1nYiBY8KdGhZRydpjF7Ex1G6F2Z0sfyCNsKnhm
-wqdrr++XMDRgCtuYlDuflTw0tjVAEvodv2b0e/1mGipJjCRgkQj5YTn5OymYZHs1
-BKn1r40PHucotjAytF/UKRZ6cI3bubq/6yKYXZTIR+NLEQIDAQABo0IwQDAPBgNV
-HRMBAf8EBTADAQH/MB0GA1UdDgQWBBSQU/WAEfY/G6idjXUNVjvyK8WcRDAOBgNV
-HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAEM1CMyq+BCfnvqrJNzG5poj
-UslMgTO6ZLKGqCn0H1r6WsSRVhbR+YSWiYysH7bqL8sS9JLtO4UJ6/N6Lgk57O4J
-S/qGPmJADldyB976U0WsQBwNC0pnmvc5zjNe0BcLioOuM2+WwPB6rAc2xYap25Oq
-Lvpx0Rrdgir4HDAquX0p+nVidnwVFXWveGx8U64ugBQNC+sPsW3633ILb/CQlhhx
-33YdjPHVwE+rOBrr5qHdHdxg1Np/QNsX/EpWZTqGYIOHs/Y7qIWsKxTCJneP7qRv
-EfInCD+/hkrjve9rUexyp1EIRxb409exjaGxytPN/VYKLC9iJ4zh/4iD/4Orh3A=
+AQEFAAOCAQ8AMIIBCgKCAQEAssQW3AeI7H6msyXIe5zgBx5AqUDATchzJ+qI2Fga
+GhLjmmJBTKHpsc7GsvY69ok/QOYP+xVLy9KNjrZEqmP6O8XMr4YFcKrs9LN5BOY+
+JezsKdbJi3sTBaf/UVurTLzQ5L1hGtIn8S5f9FGBxCO6IMMUCLS+eEm1Ex9p/fan
+WZGEqZkQyJxjnpnC8j1hnWpu1CabiKraZrMNxpkDFhM6pJr/CD5Z36dEtxeZP2N/
+OgV+zmR4NOYAd2nmAySnEvPoqFArVRb6bmXGKFiCpCB+aCLpgZ6i6A/Wh8Jz3cIM
+zKNHVBH1PdxRUleyzneLeqyn8ComNuYmuWqD2rJvwPYe8wIDAQABo0IwQDAPBgNV
+HRMBAf8EBTADAQH/MB0GA1UdDgQWBBTj0QWYTGhTwtwA7qzlqLj8uXLZZzAOBgNV
+HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAA03qJ4SyftFormCB0oqNNI7
+HYRwsUqFN35kMUXDAp0yTpKkl3LtHfLDJsg/kOQk9G5LM3GYvGglJszewUamqINg
+/G7AcpiPzjhuaZ2r0VrwpsgHoQmzjAMJe0RicxWFcV8sCjN48qMQhR5rRtGl8ZwT
+uveVQaD73skJ4XKkkv8z5IElEK+QF3nfVOq5hw74bQlVEEZMhzY3L8CGA+56tNMn
+IiLVnC7mOPD0hFzKt5tNahxXfiQHNROg+dajqinL4IqwhhxBJLHtBDBxK5nXCqRR
+U7F2Lr5jW3yO1Y/685lYfc4wB10e7ea8CtGnzBeU59FnB3w3bT/CiwSed/tbnC0=
 -----END CERTIFICATE-----
 Certificate:
     Data:
@@ -240,64 +242,64 @@
             Public Key Algorithm: rsaEncryption
                 Public-Key: (2048 bit)
                 Modulus:
-                    00:b5:60:cb:b4:84:ab:6c:ba:59:52:a9:4c:6a:85:
-                    41:f2:41:17:49:40:3f:3e:e8:70:5c:05:df:dd:64:
-                    9e:fc:be:fb:38:ef:5d:67:ab:0e:de:9c:ea:ad:91:
-                    e1:f4:db:8b:f4:c0:e6:d0:ad:e2:83:15:01:aa:49:
-                    42:97:ae:72:7b:78:e3:20:4e:7e:29:ee:b5:35:6b:
-                    c4:af:d4:54:b0:86:2f:a9:09:a7:3b:8c:05:9e:fd:
-                    b4:b8:1f:3a:aa:d5:b5:d2:91:0f:50:e9:d2:1e:62:
-                    1c:c1:30:07:41:aa:bd:c2:11:3f:cc:c8:0f:a9:7e:
-                    81:69:52:96:86:2a:07:63:7b:f0:23:9e:db:27:88:
-                    8c:dc:aa:8c:66:dd:35:3a:08:60:37:36:41:34:f5:
-                    48:69:23:1a:5b:18:a7:ec:df:68:0a:3c:19:fb:92:
-                    b7:fa:53:9b:f3:70:b6:0d:4c:cb:2f:b7:0e:7e:5f:
-                    94:8c:a3:71:66:09:be:0d:af:db:52:f6:82:3f:88:
-                    64:72:cc:19:79:f4:7b:4d:6e:50:dc:93:88:d5:29:
-                    8a:e1:c8:1f:32:71:9f:d9:0e:14:31:f8:94:11:23:
-                    b1:bf:64:eb:27:3a:64:fb:77:ee:40:8c:a7:03:ed:
-                    1d:ec:8f:ee:25:58:f0:26:91:3c:f8:28:a1:7a:45:
-                    9f:13
+                    00:c0:14:71:12:fe:4f:36:78:5f:3a:b4:1e:d5:bb:
+                    22:92:3e:57:bf:4d:e0:cf:1e:a1:fb:19:6d:88:3a:
+                    59:93:79:57:42:bc:ab:7c:a0:0d:73:35:db:db:ba:
+                    80:ef:a9:80:5b:b0:90:f5:2f:ea:17:7d:2b:92:a4:
+                    5e:88:0a:16:f3:dc:f5:25:3d:7a:8d:8e:9b:e9:22:
+                    74:dc:49:6e:87:ff:67:ae:3a:b8:09:63:63:e7:c2:
+                    bd:77:d7:1b:cb:93:c6:4a:1d:7b:51:25:05:31:cb:
+                    32:66:43:ea:2d:54:59:59:cd:de:d2:84:6f:d8:5a:
+                    c1:5b:6c:2d:67:d5:57:23:25:a0:04:dc:45:64:02:
+                    f0:de:1a:4a:62:c9:76:b5:f6:36:46:74:af:1f:18:
+                    6c:f7:38:cf:34:e3:e1:3f:ad:51:41:cf:92:ed:d5:
+                    27:f7:4a:e3:3c:d5:42:26:51:e3:b2:69:20:b1:1f:
+                    0a:f6:fd:19:3c:8e:98:94:64:eb:fe:e6:67:a0:12:
+                    f6:78:98:0f:44:b8:24:60:7c:de:e2:67:b9:0d:6e:
+                    8c:06:80:43:8e:41:76:1d:09:40:0e:3b:e7:8d:0a:
+                    d9:66:d7:34:6c:ce:7e:f9:25:6a:15:cf:9a:3e:ec:
+                    30:e0:a3:b1:d2:a3:b1:31:f1:62:50:5c:b4:fe:dd:
+                    54:61
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Basic Constraints: critical
                 CA:TRUE
             X509v3 Subject Key Identifier: 
-                51:68:BC:D9:1B:1D:7F:8E:0D:4A:33:39:2D:A4:1F:14:29:92:70:8E
+                15:FA:C3:A2:2A:E0:2C:25:C5:BE:D7:BE:91:51:DD:45:F0:F1:5D:64
             X509v3 Key Usage: critical
                 Certificate Sign, CRL Sign
     Signature Algorithm: sha256WithRSAEncryption
-         2d:d4:56:d9:90:bb:62:64:66:78:6d:cd:73:26:cc:42:ce:37:
-         f4:bf:e8:8f:e7:1e:00:cb:c2:bd:54:33:0b:a8:e2:04:e1:5f:
-         59:2a:1a:41:70:0f:d6:32:5f:d0:14:86:fa:e2:a7:19:29:49:
-         77:56:b9:d7:e6:eb:39:61:e4:25:67:22:eb:f8:46:86:b7:6b:
-         7d:44:01:0b:18:cb:ba:e5:af:76:ab:c6:fe:43:6c:d8:f6:33:
-         f7:86:0b:22:da:27:78:91:07:55:3f:b2:c5:1e:10:88:09:b3:
-         cf:22:c6:7e:8f:c6:d0:c5:ec:67:90:72:8b:2b:c4:46:81:2c:
-         82:d1:5c:57:4e:d5:af:c4:d2:d8:b2:a7:91:1a:42:b3:57:bc:
-         4e:81:5e:cf:91:af:da:f1:53:29:de:31:6b:d3:69:a4:4d:a9:
-         14:15:96:51:7d:0d:bd:28:11:03:71:d2:85:11:92:1d:96:1a:
-         12:33:0c:4b:cf:c4:40:19:fb:eb:6a:fe:9b:e7:2d:cd:f7:75:
-         a3:66:4e:a6:7d:8e:8c:2e:5d:b8:2c:a8:5e:d7:42:1b:97:00:
-         ba:12:41:8c:9b:f1:ed:91:49:63:5a:11:0d:e4:7d:f0:dc:36:
-         23:0b:1b:e8:5f:be:1f:6d:a7:aa:bb:30:76:e2:36:b2:5a:68:
-         80:f5:75:7e
+         bb:14:68:d2:09:0e:65:58:4d:d7:35:a0:a3:9b:e6:b4:2a:b4:
+         80:32:3e:61:6d:87:19:a6:a8:d2:01:78:cd:07:0b:09:a9:de:
+         5f:aa:86:43:dd:6f:d6:e0:3b:ab:60:71:d2:f0:aa:8f:14:93:
+         42:37:12:55:02:e1:a7:ed:8e:db:c0:83:10:19:f0:f5:1e:35:
+         77:84:9a:c1:79:9c:60:39:6f:50:00:66:73:6e:f0:b8:f7:75:
+         67:3e:fa:3e:0c:d0:d6:54:4a:ae:da:38:06:92:57:39:cc:d9:
+         b1:fa:60:5e:99:07:e6:97:3b:69:4d:e3:02:50:8d:60:76:8e:
+         7e:e3:60:d4:65:41:9b:6c:b8:cc:b2:c4:7a:61:32:cb:67:49:
+         b4:76:25:0c:7e:20:85:24:74:0a:90:0a:ce:73:f9:8e:ba:ce:
+         de:6e:0a:cf:6d:1c:50:67:fa:a2:4e:32:d0:ad:91:35:5e:aa:
+         b3:75:7e:23:14:29:a8:66:2a:82:ed:6c:ed:a9:9d:f6:77:20:
+         3a:e1:0b:ab:1e:ee:1d:8a:20:ff:7f:4f:36:5a:0a:30:5a:c6:
+         9c:aa:53:eb:3f:04:28:8a:6d:70:97:2a:99:d6:0c:db:a5:22:
+         0b:e5:6b:24:cf:6e:2a:c7:4a:6b:cd:82:8e:13:84:18:b6:47:
+         1b:9d:8b:83
 -----BEGIN CERTIFICATE-----
 MIIDADCCAeigAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwITEfMB0GA1UEAwwWRSBS
 b290IENBIC0gTXVsdGktcm9vdDAeFw0xNjAxMDIwMDAwMDBaFw0yNjAxMDIwMDAw
 MDBaMCExHzAdBgNVBAMMFkUgUm9vdCBDQSAtIE11bHRpLXJvb3QwggEiMA0GCSqG
-SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC1YMu0hKtsullSqUxqhUHyQRdJQD8+6HBc
-Bd/dZJ78vvs4711nqw7enOqtkeH024v0wObQreKDFQGqSUKXrnJ7eOMgTn4p7rU1
-a8Sv1FSwhi+pCac7jAWe/bS4Hzqq1bXSkQ9Q6dIeYhzBMAdBqr3CET/MyA+pfoFp
-UpaGKgdje/AjntsniIzcqoxm3TU6CGA3NkE09UhpIxpbGKfs32gKPBn7krf6U5vz
-cLYNTMsvtw5+X5SMo3FmCb4Nr9tS9oI/iGRyzBl59HtNblDck4jVKYrhyB8ycZ/Z
-DhQx+JQRI7G/ZOsnOmT7d+5AjKcD7R3sj+4lWPAmkTz4KKF6RZ8TAgMBAAGjQjBA
-MA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFFovNkbHX+ODUozOS2kHxQpknCO
-MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEALdRW2ZC7YmRmeG3N
-cybMQs439L/oj+ceAMvCvVQzC6jiBOFfWSoaQXAP1jJf0BSG+uKnGSlJd1a51+br
-OWHkJWci6/hGhrdrfUQBCxjLuuWvdqvG/kNs2PYz94YLItoneJEHVT+yxR4QiAmz
-zyLGfo/G0MXsZ5ByiyvERoEsgtFcV07Vr8TS2LKnkRpCs1e8ToFez5Gv2vFTKd4x
-a9NppE2pFBWWUX0NvSgRA3HShRGSHZYaEjMMS8/EQBn762r+m+ctzfd1o2ZOpn2O
-jC5duCyoXtdCG5cAuhJBjJvx7ZFJY1oRDeR98Nw2Iwsb6F++H22nqrswduI2slpo
-gPV1fg==
+SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDAFHES/k82eF86tB7VuyKSPle/TeDPHqH7
+GW2IOlmTeVdCvKt8oA1zNdvbuoDvqYBbsJD1L+oXfSuSpF6IChbz3PUlPXqNjpvp
+InTcSW6H/2euOrgJY2Pnwr131xvLk8ZKHXtRJQUxyzJmQ+otVFlZzd7ShG/YWsFb
+bC1n1VcjJaAE3EVkAvDeGkpiyXa19jZGdK8fGGz3OM804+E/rVFBz5Lt1Sf3SuM8
+1UImUeOyaSCxHwr2/Rk8jpiUZOv+5megEvZ4mA9EuCRgfN7iZ7kNbowGgEOOQXYd
+CUAOO+eNCtlm1zRszn75JWoVz5o+7DDgo7HSo7Ex8WJQXLT+3VRhAgMBAAGjQjBA
+MA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFBX6w6Iq4Cwlxb7XvpFR3UXw8V1k
+MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAuxRo0gkOZVhN1zWg
+o5vmtCq0gDI+YW2HGaao0gF4zQcLCaneX6qGQ91v1uA7q2Bx0vCqjxSTQjcSVQLh
+p+2O28CDEBnw9R41d4SawXmcYDlvUABmc27wuPd1Zz76PgzQ1lRKrto4BpJXOczZ
+sfpgXpkH5pc7aU3jAlCNYHaOfuNg1GVBm2y4zLLEemEyy2dJtHYlDH4ghSR0CpAK
+znP5jrrO3m4Kz20cUGf6ok4y0K2RNV6qs3V+IxQpqGYqgu1s7amd9ncgOuELqx7u
+HYog/39PNloKMFrGnKpT6z8EKIptcJcqmdYM26UiC+VrJM9uKsdKa82CjhOEGLZH
+G52Lgw==
 -----END CERTIFICATE-----
diff --git a/net/data/ssl/certificates/multi-root-crlset-C.raw b/net/data/ssl/certificates/multi-root-crlset-C.raw
index 5beec4c..c8ff83b 100644
--- a/net/data/ssl/certificates/multi-root-crlset-C.raw
+++ b/net/data/ssl/certificates/multi-root-crlset-C.raw
Binary files differ
diff --git a/net/data/ssl/certificates/multi-root-crlset-CD-and-FE.raw b/net/data/ssl/certificates/multi-root-crlset-CD-and-FE.raw
index 178cf4dd..4b04356 100644
--- a/net/data/ssl/certificates/multi-root-crlset-CD-and-FE.raw
+++ b/net/data/ssl/certificates/multi-root-crlset-CD-and-FE.raw
Binary files differ
diff --git a/net/data/ssl/certificates/multi-root-crlset-D-and-E.raw b/net/data/ssl/certificates/multi-root-crlset-D-and-E.raw
index 89e7e20f..eacdb4aaf 100644
--- a/net/data/ssl/certificates/multi-root-crlset-D-and-E.raw
+++ b/net/data/ssl/certificates/multi-root-crlset-D-and-E.raw
Binary files differ
diff --git a/net/data/ssl/certificates/multi-root-crlset-E.raw b/net/data/ssl/certificates/multi-root-crlset-E.raw
index 46e4c36..02051b8f 100644
--- a/net/data/ssl/certificates/multi-root-crlset-E.raw
+++ b/net/data/ssl/certificates/multi-root-crlset-E.raw
Binary files differ
diff --git a/net/data/ssl/certificates/multi-root-crlset-unrelated.raw b/net/data/ssl/certificates/multi-root-crlset-unrelated.raw
index 98680b6..83fd62c 100644
--- a/net/data/ssl/certificates/multi-root-crlset-unrelated.raw
+++ b/net/data/ssl/certificates/multi-root-crlset-unrelated.raw
Binary files differ
diff --git a/net/data/ssl/certificates/multi-root.keychain b/net/data/ssl/certificates/multi-root.keychain
index b3aa2bb..40cbb7c5 100644
--- a/net/data/ssl/certificates/multi-root.keychain
+++ b/net/data/ssl/certificates/multi-root.keychain
Binary files differ
diff --git a/net/data/ssl/certificates/reject_intranet_hosts.pem b/net/data/ssl/certificates/reject_intranet_hosts.pem
index 82c767c..e2d43b7 100644
--- a/net/data/ssl/certificates/reject_intranet_hosts.pem
+++ b/net/data/ssl/certificates/reject_intranet_hosts.pem
@@ -1,66 +1,69 @@
 Certificate:
     Data:
-        Version: 1 (0x0)
-        Serial Number: 15826771597900763765 (0xdba3fcea1a1dd275)
+        Version: 3 (0x2)
+        Serial Number: 11446371030079207460 (0x9ed9adce6f317824)
     Signature Algorithm: sha256WithRSAEncryption
         Issuer: CN=webmail
         Validity
-            Not Before: Feb 28 19:43:04 2017 GMT
-            Not After : Feb 28 19:43:04 2020 GMT
+            Not Before: Mar  1 03:41:00 2017 GMT
+            Not After : Feb 29 03:41:00 2020 GMT
         Subject: CN=webmail
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
                 Public-Key: (2048 bit)
                 Modulus:
-                    00:c0:ee:1b:56:47:23:82:d2:15:ca:ca:64:05:e3:
-                    ed:ab:0e:d5:b9:0c:ab:53:14:6b:8d:d4:d3:a9:79:
-                    64:b5:f2:16:34:a1:93:48:e0:a5:e7:ac:a9:80:b8:
-                    dc:f2:c1:25:b4:1b:7a:02:01:0d:58:a1:c7:5b:6a:
-                    e5:2a:92:b0:94:c0:62:53:15:fe:6b:f6:7f:73:c8:
-                    b0:2c:66:c2:69:3f:77:02:e6:6e:40:0b:2c:a1:bf:
-                    43:8c:65:cf:c5:8a:b8:38:e1:9b:f2:d4:3b:b2:58:
-                    ca:a2:a5:0d:e9:fe:02:06:13:a9:7a:4d:88:37:fb:
-                    d7:31:50:08:05:03:30:d7:eb:f8:18:50:e9:9a:d6:
-                    6d:97:6d:91:a0:16:51:86:ac:46:63:53:75:21:c3:
-                    64:b5:27:43:14:57:17:10:e1:69:92:9f:ec:83:d2:
-                    67:78:fb:1c:b4:41:34:5d:32:b6:43:f6:9c:40:8e:
-                    a5:00:e2:cc:9b:13:a8:76:30:73:59:18:ff:08:40:
-                    03:24:59:d2:1c:a8:e8:57:a6:63:cc:e1:9a:e5:22:
-                    36:b5:ff:30:a2:b9:b1:93:65:c4:13:f9:ee:98:1e:
-                    8a:3c:91:d6:6b:62:98:16:73:b5:63:8f:f4:ac:f5:
-                    b9:e0:4f:5a:c7:f3:68:2b:04:67:b2:2e:ad:40:6b:
-                    a5:c9
+                    00:be:3d:d3:32:19:9f:d4:0f:b8:fa:83:0d:4d:77:
+                    6a:00:b6:cc:16:45:70:45:a1:1b:29:2c:6b:43:82:
+                    29:9c:f9:9c:b5:37:e5:a8:3b:f8:b9:fa:96:df:7b:
+                    a9:a0:fc:a4:cf:19:49:e7:c3:2b:94:a0:02:d8:5c:
+                    17:f3:84:ec:8b:0c:1b:d6:cd:30:36:d1:41:35:46:
+                    c7:a9:62:73:2a:84:de:cf:59:51:8e:92:38:4a:af:
+                    f6:e0:7e:db:9e:19:7a:d0:8c:79:c8:4d:53:8c:6d:
+                    41:4c:04:b9:08:84:c8:81:eb:6b:65:ac:65:8d:d1:
+                    26:a9:31:3a:61:34:2e:70:91:da:c7:98:ff:73:de:
+                    95:7a:bf:90:6f:a5:94:d7:6f:e0:10:4b:79:ee:44:
+                    4b:a3:46:d1:9b:7d:14:77:7f:9d:74:6f:6c:a4:a7:
+                    8f:53:be:1f:fd:28:e8:c1:a7:03:11:57:fc:cb:08:
+                    d0:96:cd:41:66:cb:4f:e2:9e:22:d3:96:4b:97:f8:
+                    a9:a2:34:58:f3:95:50:59:fd:7f:c9:11:d4:1c:f1:
+                    af:b8:fd:35:55:86:5e:13:bf:e7:60:8f:90:76:50:
+                    c5:ef:06:95:88:b7:99:2e:1d:07:8f:4b:57:9f:5f:
+                    8d:f3:10:76:75:f0:72:0d:9e:48:0b:4e:d9:34:d0:
+                    49:05
                 Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Subject Alternative Name: 
+                DNS:webmail
     Signature Algorithm: sha256WithRSAEncryption
-         3d:88:8e:44:4c:08:ed:d6:78:bd:2e:2a:d2:1e:40:31:12:0c:
-         ab:c4:7d:e8:d6:4d:a4:85:04:26:3c:af:a8:00:b1:ff:d0:89:
-         e8:85:21:c8:7a:5b:5e:ee:b4:0b:30:b9:7f:5c:bf:9a:91:0e:
-         1a:3b:5f:8d:93:86:d4:c2:d4:95:aa:c8:3f:b3:9f:4a:e9:87:
-         3d:17:0f:a8:a2:31:3a:b6:55:b5:ce:24:52:34:71:11:c8:0e:
-         50:b1:50:2e:9f:f8:63:ed:d8:a9:3b:00:15:fc:8a:57:ee:9f:
-         2a:ef:5b:4a:4c:e2:55:38:4b:2a:d3:b0:c5:08:85:96:c2:e0:
-         39:d8:04:17:35:b6:a9:56:55:a4:26:26:82:49:43:9b:8a:dd:
-         0f:c2:c0:8b:cb:4c:91:d9:85:5e:8b:88:95:d8:25:b6:9c:2b:
-         9d:1b:37:4c:59:c5:65:52:60:c4:5f:af:61:0b:1b:b9:14:22:
-         eb:a9:4d:cf:07:3c:89:ae:74:6d:95:e7:eb:02:65:f9:f3:ee:
-         ba:2d:10:6e:7d:22:f6:8a:1d:ce:fc:e3:7a:75:49:ea:37:d1:
-         ce:30:a3:4f:9b:17:9e:71:e4:e0:2e:32:18:0e:76:29:33:31:
-         a0:22:c1:ed:0b:c4:0d:b6:66:37:48:98:98:ca:85:17:24:3c:
-         db:fb:ef:0f
+         10:c1:6c:f1:d6:5c:a7:94:c6:dd:9d:e4:2c:9b:1a:1a:59:84:
+         35:32:b3:7f:57:d6:4c:01:fa:ed:78:44:ec:2c:cf:2c:72:31:
+         a8:95:c9:50:0d:a5:fe:4c:68:ce:21:b5:bc:4c:a0:b2:84:39:
+         33:24:f8:92:05:9f:ea:c4:0e:31:22:85:27:e4:2a:8a:66:b3:
+         05:96:60:97:0c:2c:86:69:76:ef:ac:15:4f:36:ac:5a:bd:11:
+         69:30:c3:a8:7e:f4:23:ca:7e:3d:83:0f:8b:35:bd:56:d0:5f:
+         fc:fa:98:9e:45:54:04:d3:0a:43:3d:b7:01:ca:0b:4b:5c:61:
+         34:fe:af:f1:8b:c0:bc:0a:b5:dd:52:e6:c2:81:53:c9:ce:fc:
+         39:f4:1a:45:a6:f6:9a:06:eb:57:d9:bb:5e:94:43:98:7f:96:
+         33:1d:5f:9b:c5:73:68:86:96:8f:65:8f:be:b7:f2:c5:8f:f0:
+         0e:7f:63:67:9d:58:1d:d9:cb:fc:78:a0:74:e7:06:94:12:80:
+         03:ab:0a:32:8c:1e:5e:ba:28:a7:eb:ed:3b:55:80:54:38:5b:
+         85:d8:e8:dd:de:51:11:42:7a:20:ef:b7:9f:25:d3:5a:4b:e2:
+         e3:84:36:94:e3:69:aa:c7:bf:22:14:0e:da:a8:da:13:89:c3:
+         6e:7e:8c:32
 -----BEGIN CERTIFICATE-----
-MIICoDCCAYgCCQDbo/zqGh3SdTANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAd3
-ZWJtYWlsMB4XDTE3MDIyODE5NDMwNFoXDTIwMDIyODE5NDMwNFowEjEQMA4GA1UE
-AwwHd2VibWFpbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMDuG1ZH
-I4LSFcrKZAXj7asO1bkMq1MUa43U06l5ZLXyFjShk0jgpeesqYC43PLBJbQbegIB
-DVihx1tq5SqSsJTAYlMV/mv2f3PIsCxmwmk/dwLmbkALLKG/Q4xlz8WKuDjhm/LU
-O7JYyqKlDen+AgYTqXpNiDf71zFQCAUDMNfr+BhQ6ZrWbZdtkaAWUYasRmNTdSHD
-ZLUnQxRXFxDhaZKf7IPSZ3j7HLRBNF0ytkP2nECOpQDizJsTqHYwc1kY/whAAyRZ
-0hyo6FemY8zhmuUiNrX/MKK5sZNlxBP57pgeijyR1mtimBZztWOP9Kz1ueBPWsfz
-aCsEZ7IurUBrpckCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAPYiOREwI7dZ4vS4q
-0h5AMRIMq8R96NZNpIUEJjyvqACx/9CJ6IUhyHpbXu60CzC5f1y/mpEOGjtfjZOG
-1MLUlarIP7OfSumHPRcPqKIxOrZVtc4kUjRxEcgOULFQLp/4Y+3YqTsAFfyKV+6f
-Ku9bSkziVThLKtOwxQiFlsLgOdgEFzW2qVZVpCYmgklDm4rdD8LAi8tMkdmFXouI
-ldgltpwrnRs3TFnFZVJgxF+vYQsbuRQi66lNzwc8ia50bZXn6wJl+fPuui0Qbn0i
-9oodzvzjenVJ6jfRzjCjT5sXnnHk4C4yGA52KTMxoCLB7QvEDbZmN0iYmMqFFyQ8
-2/vvDw==
+MIICvTCCAaWgAwIBAgIJAJ7Zrc5vMXgkMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNV
+BAMMB3dlYm1haWwwHhcNMTcwMzAxMDM0MTAwWhcNMjAwMjI5MDM0MTAwWjASMRAw
+DgYDVQQDDAd3ZWJtYWlsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
+vj3TMhmf1A+4+oMNTXdqALbMFkVwRaEbKSxrQ4IpnPmctTflqDv4ufqW33upoPyk
+zxlJ58MrlKAC2FwX84Tsiwwb1s0wNtFBNUbHqWJzKoTez1lRjpI4Sq/24H7bnhl6
+0Ix5yE1TjG1BTAS5CITIgetrZaxljdEmqTE6YTQucJHax5j/c96Ver+Qb6WU12/g
+EEt57kRLo0bRm30Ud3+ddG9spKePU74f/SjowacDEVf8ywjQls1BZstP4p4i05ZL
+l/ipojRY85VQWf1/yRHUHPGvuP01VYZeE7/nYI+QdlDF7waViLeZLh0Hj0tXn1+N
+8xB2dfByDZ5IC07ZNNBJBQIDAQABoxYwFDASBgNVHREECzAJggd3ZWJtYWlsMA0G
+CSqGSIb3DQEBCwUAA4IBAQAQwWzx1lynlMbdneQsmxoaWYQ1MrN/V9ZMAfrteETs
+LM8scjGolclQDaX+TGjOIbW8TKCyhDkzJPiSBZ/qxA4xIoUn5CqKZrMFlmCXDCyG
+aXbvrBVPNqxavRFpMMOofvQjyn49gw+LNb1W0F/8+pieRVQE0wpDPbcBygtLXGE0
+/q/xi8C8CrXdUubCgVPJzvw59BpFpvaaButX2btelEOYf5YzHV+bxXNohpaPZY++
+t/LFj/AOf2NnnVgd2cv8eKB05waUEoADqwoyjB5euiin6+07VYBUOFuF2Ojd3lER
+Qnog77efJdNaS+LjhDaU42mqx78iFA7aqNoTicNufowy
 -----END CERTIFICATE-----
diff --git a/net/data/ssl/scripts/aia-test.cnf b/net/data/ssl/scripts/aia-test.cnf
index 635b033..ea2b6629 100644
--- a/net/data/ssl/scripts/aia-test.cnf
+++ b/net/data/ssl/scripts/aia-test.cnf
@@ -1,6 +1,7 @@
 CA_DIR=out
 CA_NAME=aia-test-root
 AIA_URL=http://aia-test.invalid
+HOST_NAME=aia-host.invalid
 
 [ca]
 default_ca = CA_root
@@ -27,6 +28,7 @@
 basicConstraints       = critical, CA:false
 extendedKeyUsage       = serverAuth, clientAuth
 authorityInfoAccess    = caIssuers;URI:${ENV::AIA_URL}
+subjectAltName         = DNS:${ENV::HOST_NAME}
 
 [ca_cert]
 basicConstraints       = critical, CA:true
diff --git a/net/data/ssl/scripts/ee.cnf b/net/data/ssl/scripts/ee.cnf
index 87e4855..7d91d75c 100644
--- a/net/data/ssl/scripts/ee.cnf
+++ b/net/data/ssl/scripts/ee.cnf
@@ -55,6 +55,9 @@
 [req_extensions]
 subjectAltName = IP:127.0.0.1
 
+[req_intranet_san]
+subjectAltName = DNS:webmail
+
 [req_extensions_with_tls_feature]
 subjectAltName = IP:127.0.0.1
 1.3.6.1.5.5.7.1.24=DER:30:03:02:01:05
diff --git a/net/data/ssl/scripts/generate-aia-certs.sh b/net/data/ssl/scripts/generate-aia-certs.sh
index 706d386ee..5d5672b6 100755
--- a/net/data/ssl/scripts/generate-aia-certs.sh
+++ b/net/data/ssl/scripts/generate-aia-certs.sh
@@ -80,6 +80,7 @@
   -config aia-test.cnf
 
 CA_COMMON_NAME="AIA Test Intermediate CA" \
+  HOST_NAME="aia-host.invalid" \
   CA_DIR=out \
   CA_NAME=aia-test-intermediate \
   AIA_URL=http://aia-test.invalid \
diff --git a/net/data/ssl/scripts/generate-policy-certs.sh b/net/data/ssl/scripts/generate-policy-certs.sh
index bef21f4..cebef5e 100755
--- a/net/data/ssl/scripts/generate-policy-certs.sh
+++ b/net/data/ssl/scripts/generate-policy-certs.sh
@@ -82,6 +82,7 @@
   -config policy.cnf
 
 COMMON_NAME="Policy Test Intermediate CA" \
+  SAN="policy_test.example" \
   CA_DIR=out \
   CA_NAME=policy-intermediate \
   try openssl ca \
diff --git a/net/data/ssl/scripts/generate-test-certs.sh b/net/data/ssl/scripts/generate-test-certs.sh
index 9a1a912..f5395e4 100755
--- a/net/data/ssl/scripts/generate-test-certs.sh
+++ b/net/data/ssl/scripts/generate-test-certs.sh
@@ -210,7 +210,7 @@
 ## Reject intranet hostnames in "publicly" trusted certs
 # 365 * 3 = 1095
 SUBJECT_NAME="req_intranet_dn" \
-  try openssl req -x509 -days 1095 \
+  try openssl req -x509 -days 1095 -extensions req_intranet_san \
     -config ../scripts/ee.cnf -newkey rsa:2048 -text \
     -out ../certificates/reject_intranet_hosts.pem
 
diff --git a/net/data/ssl/scripts/policy.cnf b/net/data/ssl/scripts/policy.cnf
index 12af828..dbb2efa 100644
--- a/net/data/ssl/scripts/policy.cnf
+++ b/net/data/ssl/scripts/policy.cnf
@@ -1,5 +1,6 @@
 CA_DIR=out
 CA_NAME=policy-root
+SAN=policy_test.example
 
 [ca]
 default_ca = CA_root
@@ -26,6 +27,7 @@
 basicConstraints       = critical, CA:false
 extendedKeyUsage       = serverAuth, clientAuth
 certificatePolicies    = 1.2.3.4
+subjectAltName         = DNS:${ENV::SAN}
 
 [ca_cert]
 basicConstraints       = critical, CA:true
diff --git a/net/data/ssl/scripts/redundant-ca.cnf b/net/data/ssl/scripts/redundant-ca.cnf
index 46e395f..4ae60ad 100644
--- a/net/data/ssl/scripts/redundant-ca.cnf
+++ b/net/data/ssl/scripts/redundant-ca.cnf
@@ -25,6 +25,7 @@
 subjectKeyIdentifier   = hash
 authorityKeyIdentifier = keyid:always
 extendedKeyUsage       = serverAuth,clientAuth
+subjectAltName         = IP:127.0.0.1
 
 [ca_cert]
 # Extensions to add when signing a request for an intermediate/CA cert
diff --git a/net/dns/dns_protocol.h b/net/dns/dns_protocol.h
index 416738a2..2c4478c4 100644
--- a/net/dns/dns_protocol.h
+++ b/net/dns/dns_protocol.h
@@ -135,12 +135,12 @@
 static const uint8_t kRcodeNOTIMP = 4;
 static const uint8_t kRcodeREFUSED = 5;
 
-// DNS flags.
+// DNS header flags.
+//
+// https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-12
 static const uint16_t kFlagResponse = 0x8000;
-static const uint16_t kFlagRA = 0x80;
-static const uint16_t kFlagRD = 0x100;
-static const uint16_t kFlagTC = 0x200;
-static const uint16_t kFlagAA = 0x400;
+static const uint16_t kFlagRD = 0x100;  // Recursion Desired - query flag.
+static const uint16_t kFlagTC = 0x200;  // Truncated - server flag.
 
 }  // namespace dns_protocol
 
diff --git a/net/http/transport_security_state.cc b/net/http/transport_security_state.cc
index 5f82c28..fa4f7876 100644
--- a/net/http/transport_security_state.cc
+++ b/net/http/transport_security_state.cc
@@ -91,7 +91,7 @@
   std::vector<std::string> pem_encoded_chain;
   cert_chain->GetPEMEncodedChain(&pem_encoded_chain);
   for (const std::string& cert : pem_encoded_chain)
-    result->Append(base::MakeUnique<base::StringValue>(cert));
+    result->Append(base::MakeUnique<base::Value>(cert));
 
   return result;
 }
@@ -157,7 +157,7 @@
     known_pin += "\"" + base64_value + "\"";
 
     known_pin_list->Append(
-        std::unique_ptr<base::Value>(new base::StringValue(known_pin)));
+        std::unique_ptr<base::Value>(new base::Value(known_pin)));
   }
 
   report.Set("known-pins", std::move(known_pin_list));
diff --git a/net/log/file_net_log_observer_unittest.cc b/net/log/file_net_log_observer_unittest.cc
index 66c61c1..84dcc98 100644
--- a/net/log/file_net_log_observer_unittest.cc
+++ b/net/log/file_net_log_observer_unittest.cc
@@ -334,8 +334,7 @@
   TestClosure closure;
 
   const char kConstantString[] = "awesome constant";
-  std::unique_ptr<base::Value> constants(
-      new base::StringValue(kConstantString));
+  std::unique_ptr<base::Value> constants(new base::Value(kConstantString));
 
   CreateAndStartObserving(std::move(constants));
 
diff --git a/net/log/net_log_with_source.cc b/net/log/net_log_with_source.cc
index 8a03c8c..fc954ba 100644
--- a/net/log/net_log_with_source.cc
+++ b/net/log/net_log_with_source.cc
@@ -23,7 +23,7 @@
 // Returns parameters for logging data transferred events. At a minimum includes
 // the number of bytes transferred. If the capture mode allows logging byte
 // contents and |byte_count| > 0, then will include the actual bytes. The
-// bytes are hex-encoded, since base::StringValue only supports UTF-8.
+// bytes are hex-encoded, since base::Value only supports UTF-8.
 std::unique_ptr<base::Value> BytesTransferredCallback(
     int byte_count,
     const char* bytes,
diff --git a/net/log/write_to_file_net_log_observer_unittest.cc b/net/log/write_to_file_net_log_observer_unittest.cc
index 06c2065..1f07c0ee 100644
--- a/net/log/write_to_file_net_log_observer_unittest.cc
+++ b/net/log/write_to_file_net_log_observer_unittest.cc
@@ -152,8 +152,7 @@
 
 TEST_F(WriteToFileNetLogObserverTest, CustomConstants) {
   const char kConstantString[] = "awesome constant";
-  std::unique_ptr<base::Value> constants(
-      new base::StringValue(kConstantString));
+  std::unique_ptr<base::Value> constants(new base::Value(kConstantString));
   base::ScopedFILE file(base::OpenFile(log_path_, "w"));
   ASSERT_TRUE(file);
   std::unique_ptr<WriteToFileNetLogObserver> logger(
diff --git a/net/nqe/event_creator.cc b/net/nqe/event_creator.cc
index 930e372..ab5000e3 100644
--- a/net/nqe/event_creator.cc
+++ b/net/nqe/event_creator.cc
@@ -4,6 +4,7 @@
 
 #include "net/nqe/event_creator.h"
 
+#include <stdlib.h>
 #include <memory>
 #include <utility>
 
@@ -21,7 +22,7 @@
 
 namespace {
 
-std::unique_ptr<base::Value> EffectiveConnectionTypeChangedNetLogCallback(
+std::unique_ptr<base::Value> NetworkQualityChangedNetLogCallback(
     base::TimeDelta http_rtt,
     base::TimeDelta transport_rtt,
     int32_t downstream_throughput_kbps,
@@ -36,6 +37,37 @@
   return std::move(dict);
 }
 
+bool MetricChangedMeaningfully(int32_t past_value, int32_t current_value) {
+  if ((past_value == INVALID_RTT_THROUGHPUT) !=
+      (current_value == INVALID_RTT_THROUGHPUT)) {
+    return true;
+  }
+
+  if (past_value == INVALID_RTT_THROUGHPUT &&
+      current_value == INVALID_RTT_THROUGHPUT) {
+    return false;
+  }
+
+  // Create a new entry only if (i) the difference between the two values exceed
+  // the threshold; and, (ii) the ratio of the values also exceeds the
+  // threshold.
+  static const int kMinDifferenceInMetrics = 100;
+  static const float kMinRatio = 1.2f;
+
+  if (std::abs(past_value - current_value) < kMinDifferenceInMetrics) {
+    // The absolute change in the value is not sufficient enough.
+    return false;
+  }
+
+  if (past_value < (kMinRatio * current_value) &&
+      current_value < (kMinRatio * past_value)) {
+    // The relative change in the value is not sufficient enough.
+    return false;
+  }
+
+  return true;
+}
+
 }  // namespace
 
 EventCreator::EventCreator(NetLogWithSource net_log)
@@ -46,7 +78,7 @@
   DCHECK(thread_checker_.CalledOnValidThread());
 }
 
-void EventCreator::MaybeAddEffectiveConnectionTypeChangedEventToNetLog(
+void EventCreator::MaybeAddNetworkQualityChangedEventToNetLog(
     EffectiveConnectionType effective_connection_type,
     const NetworkQuality& network_quality) {
   DCHECK(thread_checker_.CalledOnValidThread());
@@ -54,15 +86,16 @@
   // Check if any of the network quality metrics changed meaningfully.
   bool effective_connection_type_changed =
       past_effective_connection_type_ != effective_connection_type;
-  bool http_rtt_changed = (past_network_quality_.http_rtt() == InvalidRTT()) !=
-                          (network_quality.http_rtt() == InvalidRTT());
-  bool transport_rtt_changed =
-      (past_network_quality_.transport_rtt() == InvalidRTT()) !=
-      (network_quality.transport_rtt() == InvalidRTT());
-  bool kbps_changed =
-      (past_network_quality_.downstream_throughput_kbps() ==
-       INVALID_RTT_THROUGHPUT) !=
-      (network_quality.downstream_throughput_kbps() == INVALID_RTT_THROUGHPUT);
+  bool http_rtt_changed = MetricChangedMeaningfully(
+      past_network_quality_.http_rtt().InMilliseconds(),
+      network_quality.http_rtt().InMilliseconds());
+
+  bool transport_rtt_changed = MetricChangedMeaningfully(
+      past_network_quality_.transport_rtt().InMilliseconds(),
+      network_quality.transport_rtt().InMilliseconds());
+  bool kbps_changed = MetricChangedMeaningfully(
+      past_network_quality_.downstream_throughput_kbps(),
+      network_quality.downstream_throughput_kbps());
 
   if (!effective_connection_type_changed && !http_rtt_changed &&
       !transport_rtt_changed && !kbps_changed) {
@@ -75,7 +108,7 @@
 
   net_log_.AddEvent(
       NetLogEventType::NETWORK_QUALITY_CHANGED,
-      base::Bind(&EffectiveConnectionTypeChangedNetLogCallback,
+      base::Bind(&NetworkQualityChangedNetLogCallback,
                  network_quality.http_rtt(), network_quality.transport_rtt(),
                  network_quality.downstream_throughput_kbps(),
                  effective_connection_type));
diff --git a/net/nqe/event_creator.h b/net/nqe/event_creator.h
index 5000195..4cd87e6 100644
--- a/net/nqe/event_creator.h
+++ b/net/nqe/event_creator.h
@@ -30,11 +30,11 @@
   ~EventCreator();
 
   // May add network quality changed event to the net-internals log if there
-  // is a change in the effective connection type, or if there is a change in
-  // the availability of HTTP RTT, transport RTT or bandwidth.
+  // is a change in the effective connection type, or if there is a meaningful
+  // change in the values of HTTP RTT, transport RTT or bandwidth.
   // |effective_connection_type| is the current effective connection type.
   // |network_quality| is the current network quality.
-  void MaybeAddEffectiveConnectionTypeChangedEventToNetLog(
+  void MaybeAddNetworkQualityChangedEventToNetLog(
       EffectiveConnectionType effective_connection_type,
       const NetworkQuality& network_quality);
 
diff --git a/net/nqe/event_creator_unittest.cc b/net/nqe/event_creator_unittest.cc
new file mode 100644
index 0000000..bc9acfb0
--- /dev/null
+++ b/net/nqe/event_creator_unittest.cc
@@ -0,0 +1,127 @@
+// Copyright 2017 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 "net/nqe/event_creator.h"
+
+#include "base/memory/ptr_util.h"
+#include "base/time/time.h"
+#include "net/log/net_log_with_source.h"
+#include "net/log/test_net_log.h"
+#include "net/log/test_net_log_entry.h"
+#include "net/nqe/effective_connection_type.h"
+#include "net/nqe/network_quality.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+
+namespace nqe {
+
+namespace internal {
+
+namespace {
+
+// Returns the number of entries in |net_log| that have type set to
+// |NetLogEventType::NETWORK_QUALITY_CHANGED|.
+int GetNetworkQualityChangedEntriesCount(BoundTestNetLog* net_log) {
+  TestNetLogEntry::List entries;
+  net_log->GetEntries(&entries);
+
+  int count = 0;
+  for (const auto& entry : entries) {
+    if (entry.type == NetLogEventType::NETWORK_QUALITY_CHANGED)
+      ++count;
+  }
+  return count;
+}
+
+// Verify that the net log events are recorded correctly.
+TEST(NetworkQualityEstimatorEventCreatorTest, Notified) {
+  // std::unique_ptr<BoundTestNetLog>
+  // net_log(base::MakeUnique<BoundTestNetLog>());
+  BoundTestNetLog net_log;
+
+  EventCreator event_creator(net_log.bound());
+
+  NetworkQuality network_quality_100(base::TimeDelta::FromMilliseconds(100),
+                                     base::TimeDelta::FromMilliseconds(100),
+                                     100);
+
+  event_creator.MaybeAddNetworkQualityChangedEventToNetLog(
+      EFFECTIVE_CONNECTION_TYPE_2G, network_quality_100);
+  EXPECT_EQ(1, GetNetworkQualityChangedEntriesCount(&net_log));
+
+  // No new entry should be created since the network quality has not changed.
+  event_creator.MaybeAddNetworkQualityChangedEventToNetLog(
+      EFFECTIVE_CONNECTION_TYPE_2G, network_quality_100);
+  EXPECT_EQ(1, GetNetworkQualityChangedEntriesCount(&net_log));
+
+  // A new entry should be created since effective connection type has changed.
+  event_creator.MaybeAddNetworkQualityChangedEventToNetLog(
+      EFFECTIVE_CONNECTION_TYPE_3G, network_quality_100);
+  EXPECT_EQ(2, GetNetworkQualityChangedEntriesCount(&net_log));
+
+  // A new entry should not be created since HTTP RTT has not changed
+  // meaningfully.
+  NetworkQuality network_quality_http_rtt_110(
+      base::TimeDelta::FromMilliseconds(110),
+      base::TimeDelta::FromMilliseconds(100), 100);
+  event_creator.MaybeAddNetworkQualityChangedEventToNetLog(
+      EFFECTIVE_CONNECTION_TYPE_3G, network_quality_http_rtt_110);
+  EXPECT_EQ(2, GetNetworkQualityChangedEntriesCount(&net_log));
+
+  // A new entry should be created since HTTP RTT has changed meaningfully.
+  NetworkQuality network_quality_http_rtt_300(
+      base::TimeDelta::FromMilliseconds(300),
+      base::TimeDelta::FromMilliseconds(100), 100);
+  event_creator.MaybeAddNetworkQualityChangedEventToNetLog(
+      EFFECTIVE_CONNECTION_TYPE_3G, network_quality_http_rtt_300);
+  EXPECT_EQ(3, GetNetworkQualityChangedEntriesCount(&net_log));
+
+  // A new entry should be created since transport RTT has changed meaningfully.
+  NetworkQuality network_quality_transport_rtt_300(
+      base::TimeDelta::FromMilliseconds(300),
+      base::TimeDelta::FromMilliseconds(300), 100);
+  event_creator.MaybeAddNetworkQualityChangedEventToNetLog(
+      EFFECTIVE_CONNECTION_TYPE_3G, network_quality_transport_rtt_300);
+  EXPECT_EQ(4, GetNetworkQualityChangedEntriesCount(&net_log));
+
+  // A new entry should be created since bandwidth has changed meaningfully.
+  NetworkQuality network_quality_kbps_300(
+      base::TimeDelta::FromMilliseconds(300),
+      base::TimeDelta::FromMilliseconds(300), 300);
+  event_creator.MaybeAddNetworkQualityChangedEventToNetLog(
+      EFFECTIVE_CONNECTION_TYPE_3G, network_quality_kbps_300);
+  EXPECT_EQ(5, GetNetworkQualityChangedEntriesCount(&net_log));
+
+  // A new entry should not be created since network quality has not changed
+  // meaningfully.
+  event_creator.MaybeAddNetworkQualityChangedEventToNetLog(
+      EFFECTIVE_CONNECTION_TYPE_3G, network_quality_kbps_300);
+  EXPECT_EQ(5, GetNetworkQualityChangedEntriesCount(&net_log));
+
+  // A new entry should be created since bandwidth has changed meaningfully.
+  NetworkQuality network_quality_kbps_2000(
+      base::TimeDelta::FromMilliseconds(300),
+      base::TimeDelta::FromMilliseconds(300), 2000);
+  event_creator.MaybeAddNetworkQualityChangedEventToNetLog(
+      EFFECTIVE_CONNECTION_TYPE_3G, network_quality_kbps_2000);
+  EXPECT_EQ(6, GetNetworkQualityChangedEntriesCount(&net_log));
+
+  // A new entry should not be created since bandwidth has not changed by more
+  // than 20%.
+  NetworkQuality network_quality_kbps_2200(
+      base::TimeDelta::FromMilliseconds(300),
+      base::TimeDelta::FromMilliseconds(300), 2200);
+  event_creator.MaybeAddNetworkQualityChangedEventToNetLog(
+      EFFECTIVE_CONNECTION_TYPE_3G, network_quality_kbps_2200);
+  EXPECT_EQ(6, GetNetworkQualityChangedEntriesCount(&net_log));
+}
+
+}  // namespace
+
+}  // namespace internal
+
+}  // namespace nqe
+
+}  // namespace net
diff --git a/net/nqe/network_quality_estimator.cc b/net/nqe/network_quality_estimator.cc
index 9ca1e18..0d5fbe3 100644
--- a/net/nqe/network_quality_estimator.cc
+++ b/net/nqe/network_quality_estimator.cc
@@ -795,7 +795,7 @@
     EffectiveConnectionType effective_connection_type) {
   DCHECK(thread_checker_.CalledOnValidThread());
 
-  event_creator_.MaybeAddEffectiveConnectionTypeChangedEventToNetLog(
+  event_creator_.MaybeAddNetworkQualityChangedEventToNetLog(
       effective_connection_type_,
       typical_network_quality_[effective_connection_type]);
 
@@ -1105,7 +1105,7 @@
   if (past_type != effective_connection_type_)
     NotifyObserversOfEffectiveConnectionTypeChanged();
 
-  event_creator_.MaybeAddEffectiveConnectionTypeChangedEventToNetLog(
+  event_creator_.MaybeAddNetworkQualityChangedEventToNetLog(
       effective_connection_type_, network_quality_);
 
   rtt_observations_size_at_last_ect_computation_ = rtt_observations_.Size();
diff --git a/net/nqe/network_quality_estimator_unittest.cc b/net/nqe/network_quality_estimator_unittest.cc
index 4c68ae0..d5cc4f6 100644
--- a/net/nqe/network_quality_estimator_unittest.cc
+++ b/net/nqe/network_quality_estimator_unittest.cc
@@ -226,7 +226,7 @@
       estimator.GetRecentTransportRTT(base::TimeTicks(), &transport_rtt));
 
   // Verify the contents of the net log.
-  EXPECT_EQ(
+  EXPECT_LE(
       2, estimator.GetEntriesCount(NetLogEventType::NETWORK_QUALITY_CHANGED));
   EXPECT_EQ(http_rtt.InMilliseconds(),
             estimator.GetNetLogLastIntegerValue(
@@ -411,8 +411,10 @@
   // |observer| should be notified as soon as it is added.
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(1U, observer.effective_connection_types().size());
-  EXPECT_EQ(
-      2, estimator.GetEntriesCount(NetLogEventType::NETWORK_QUALITY_CHANGED));
+
+  int num_net_log_entries =
+      estimator.GetEntriesCount(NetLogEventType::NETWORK_QUALITY_CHANGED);
+  EXPECT_LE(2, num_net_log_entries);
 
   estimator.SimulateNetworkChange(
       NetworkChangeNotifier::ConnectionType::CONNECTION_2G, "test");
@@ -425,7 +427,8 @@
 
   // Verify the contents of the net log.
   EXPECT_LE(
-      3, estimator.GetEntriesCount(NetLogEventType::NETWORK_QUALITY_CHANGED));
+      1, estimator.GetEntriesCount(NetLogEventType::NETWORK_QUALITY_CHANGED) -
+             num_net_log_entries);
   EXPECT_NE(-1, estimator.GetNetLogLastIntegerValue(
                     NetLogEventType::NETWORK_QUALITY_CHANGED, "http_rtt_ms"));
   EXPECT_EQ(-1,
@@ -1741,7 +1744,7 @@
   request->Start();
   base::RunLoop().Run();
   EXPECT_EQ(1U, observer.effective_connection_types().size());
-  EXPECT_EQ(
+  EXPECT_LE(
       1, estimator.GetEntriesCount(NetLogEventType::NETWORK_QUALITY_CHANGED));
 
   // Verify the contents of the net log.
diff --git a/net/quic/chromium/quic_network_transaction_unittest.cc b/net/quic/chromium/quic_network_transaction_unittest.cc
index 611247e..ee3bad8 100644
--- a/net/quic/chromium/quic_network_transaction_unittest.cc
+++ b/net/quic/chromium/quic_network_transaction_unittest.cc
@@ -991,9 +991,8 @@
       ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
   ASSERT_TRUE(cert.get());
   // This certificate is valid for the proxy, but not for the origin.
-  bool common_name_fallback_used;
-  EXPECT_TRUE(cert->VerifyNameMatch(proxy_host, &common_name_fallback_used));
-  EXPECT_FALSE(cert->VerifyNameMatch(origin_host, &common_name_fallback_used));
+  EXPECT_TRUE(cert->VerifyNameMatch(proxy_host, false));
+  EXPECT_FALSE(cert->VerifyNameMatch(origin_host, false));
   ProofVerifyDetailsChromium verify_details;
   verify_details.cert_verify_result.verified_cert = cert;
   crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
@@ -1018,10 +1017,9 @@
   ASSERT_TRUE(cert.get());
   // TODO(rch): the connection should be "to" the origin, so if the cert is
   // valid for the origin but not the alternative, that should work too.
-  bool common_name_fallback_used;
-  EXPECT_TRUE(cert->VerifyNameMatch(origin.host(), &common_name_fallback_used));
+  EXPECT_TRUE(cert->VerifyNameMatch(origin.host(), false));
   EXPECT_TRUE(
-      cert->VerifyNameMatch(alternative.host(), &common_name_fallback_used));
+      cert->VerifyNameMatch(alternative.host(), false));
   ProofVerifyDetailsChromium verify_details;
   verify_details.cert_verify_result.verified_cert = cert;
   crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
@@ -3326,9 +3324,8 @@
 
   scoped_refptr<X509Certificate> cert(
       ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
-  bool unused;
-  ASSERT_FALSE(cert->VerifyNameMatch(origin1_, &unused));
-  ASSERT_TRUE(cert->VerifyNameMatch(origin2_, &unused));
+  ASSERT_FALSE(cert->VerifyNameMatch(origin1_, false));
+  ASSERT_TRUE(cert->VerifyNameMatch(origin2_, false));
 
   ProofVerifyDetailsChromium verify_details;
   verify_details.cert_verify_result.verified_cert = cert;
@@ -3366,10 +3363,9 @@
 
   scoped_refptr<X509Certificate> cert(
       ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
-  bool unused;
-  ASSERT_TRUE(cert->VerifyNameMatch(origin1_, &unused));
-  ASSERT_TRUE(cert->VerifyNameMatch(origin2_, &unused));
-  ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname, &unused));
+  ASSERT_TRUE(cert->VerifyNameMatch(origin1_, false));
+  ASSERT_TRUE(cert->VerifyNameMatch(origin2_, false));
+  ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname, false));
 
   ProofVerifyDetailsChromium verify_details;
   verify_details.cert_verify_result.verified_cert = cert;
@@ -3436,15 +3432,14 @@
 
   scoped_refptr<X509Certificate> cert1(
       ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
-  bool unused;
-  ASSERT_TRUE(cert1->VerifyNameMatch(origin1_, &unused));
-  ASSERT_FALSE(cert1->VerifyNameMatch(origin2_, &unused));
-  ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname, &unused));
+  ASSERT_TRUE(cert1->VerifyNameMatch(origin1_, false));
+  ASSERT_FALSE(cert1->VerifyNameMatch(origin2_, false));
+  ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname, false));
 
   scoped_refptr<X509Certificate> cert2(
       ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
-  ASSERT_TRUE(cert2->VerifyNameMatch(origin2_, &unused));
-  ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname, &unused));
+  ASSERT_TRUE(cert2->VerifyNameMatch(origin2_, false));
+  ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname, false));
 
   ProofVerifyDetailsChromium verify_details1;
   verify_details1.cert_verify_result.verified_cert = cert1;
diff --git a/net/quic/chromium/quic_stream_factory_test.cc b/net/quic/chromium/quic_stream_factory_test.cc
index 19d40b5e..d6fd5ae 100644
--- a/net/quic/chromium/quic_stream_factory_test.cc
+++ b/net/quic/chromium/quic_stream_factory_test.cc
@@ -5391,9 +5391,8 @@
 
   scoped_refptr<X509Certificate> cert(
       ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
-  bool unused;
-  ASSERT_FALSE(cert->VerifyNameMatch(origin1_.host(), &unused));
-  ASSERT_TRUE(cert->VerifyNameMatch(origin2_.host(), &unused));
+  ASSERT_FALSE(cert->VerifyNameMatch(origin1_.host(), false));
+  ASSERT_TRUE(cert->VerifyNameMatch(origin2_.host(), false));
 
   ProofVerifyDetailsChromium verify_details;
   verify_details.cert_verify_result.verified_cert = cert;
@@ -5425,10 +5424,9 @@
 
   scoped_refptr<X509Certificate> cert(
       ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
-  bool unused;
-  ASSERT_TRUE(cert->VerifyNameMatch(origin1_.host(), &unused));
-  ASSERT_TRUE(cert->VerifyNameMatch(origin2_.host(), &unused));
-  ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname, &unused));
+  ASSERT_TRUE(cert->VerifyNameMatch(origin1_.host(), false));
+  ASSERT_TRUE(cert->VerifyNameMatch(origin2_.host(), false));
+  ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname, false));
 
   ProofVerifyDetailsChromium verify_details;
   verify_details.cert_verify_result.verified_cert = cert;
@@ -5491,10 +5489,9 @@
 
   scoped_refptr<X509Certificate> cert(
       ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
-  bool unused;
-  ASSERT_TRUE(cert->VerifyNameMatch(origin1_.host(), &unused));
-  ASSERT_TRUE(cert->VerifyNameMatch(origin2_.host(), &unused));
-  ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname, &unused));
+  ASSERT_TRUE(cert->VerifyNameMatch(origin1_.host(), false));
+  ASSERT_TRUE(cert->VerifyNameMatch(origin2_.host(), false));
+  ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname, false));
 
   ProofVerifyDetailsChromium verify_details1;
   verify_details1.cert_verify_result.verified_cert = cert;
@@ -5572,10 +5569,9 @@
 
   scoped_refptr<X509Certificate> cert1(
       ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
-  bool unused;
-  ASSERT_TRUE(cert1->VerifyNameMatch(origin1_.host(), &unused));
-  ASSERT_FALSE(cert1->VerifyNameMatch(origin2_.host(), &unused));
-  ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname, &unused));
+  ASSERT_TRUE(cert1->VerifyNameMatch(origin1_.host(), false));
+  ASSERT_FALSE(cert1->VerifyNameMatch(origin2_.host(), false));
+  ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname, false));
 
   ProofVerifyDetailsChromium verify_details1;
   verify_details1.cert_verify_result.verified_cert = cert1;
@@ -5584,8 +5580,8 @@
 
   scoped_refptr<X509Certificate> cert2(
       ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
-  ASSERT_TRUE(cert2->VerifyNameMatch(origin2_.host(), &unused));
-  ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname, &unused));
+  ASSERT_TRUE(cert2->VerifyNameMatch(origin2_.host(), false));
+  ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname, false));
 
   ProofVerifyDetailsChromium verify_details2;
   verify_details2.cert_verify_result.verified_cert = cert2;
diff --git a/net/quic/core/congestion_control/bbr_sender.cc b/net/quic/core/congestion_control/bbr_sender.cc
index 438a553a..b63b630 100644
--- a/net/quic/core/congestion_control/bbr_sender.cc
+++ b/net/quic/core/congestion_control/bbr_sender.cc
@@ -8,8 +8,10 @@
 #include <sstream>
 
 #include "net/quic/core/congestion_control/rtt_stats.h"
+#include "net/quic/core/crypto/crypto_protocol.h"
 #include "net/quic/core/quic_flags.h"
 #include "net/quic/platform/api/quic_bug_tracker.h"
+#include "net/quic/platform/api/quic_flag_utils.h"
 #include "net/quic/platform/api/quic_logging.h"
 
 namespace net {
@@ -90,6 +92,7 @@
           static_cast<float>(base::GetFlag(FLAGS_quic_bbr_cwnd_gain))),
       rtt_variance_weight_(static_cast<float>(
           base::GetFlag(FLAGS_quic_bbr_rtt_variation_weight))),
+      num_startup_rtts_(kRoundTripsWithoutGrowthBeforeExitingStartup),
       cycle_current_offset_(0),
       last_cycle_start_(QuicTime::Zero()),
       is_at_full_bandwidth_(false),
@@ -167,6 +170,19 @@
   return recovery_state_ != NOT_IN_RECOVERY;
 }
 
+void BbrSender::SetFromConfig(const QuicConfig& config,
+                              Perspective perspective) {
+  if (FLAGS_quic_reloadable_flag_quic_allow_2_rtt_bbr_startup) {
+    QUIC_FLAG_COUNT(gfe2_reloadable_flag_quic_allow_2_rtt_bbr_startup);
+    if (config.HasClientRequestedIndependentOption(k1RTT, perspective)) {
+      num_startup_rtts_ = 1;
+    }
+    if (config.HasClientRequestedIndependentOption(k2RTT, perspective)) {
+      num_startup_rtts_ = 2;
+    }
+  }
+}
+
 void BbrSender::OnCongestionEvent(bool /*rtt_updated*/,
                                   QuicByteCount prior_in_flight,
                                   QuicTime event_time,
@@ -358,8 +374,7 @@
   }
 
   rounds_without_bandwidth_gain_++;
-  if (rounds_without_bandwidth_gain_ >=
-      kRoundTripsWithoutGrowthBeforeExitingStartup) {
+  if (rounds_without_bandwidth_gain_ >= num_startup_rtts_) {
     is_at_full_bandwidth_ = true;
   }
 }
diff --git a/net/quic/core/congestion_control/bbr_sender.h b/net/quic/core/congestion_control/bbr_sender.h
index 21d7115..7a1089c 100644
--- a/net/quic/core/congestion_control/bbr_sender.h
+++ b/net/quic/core/congestion_control/bbr_sender.h
@@ -102,7 +102,8 @@
   bool InRecovery() const override;
 
   void SetFromConfig(const QuicConfig& config,
-                     Perspective perspective) override {}
+                     Perspective perspective) override;
+
   void ResumeConnectionState(
       const CachedNetworkParameters& cached_network_params,
       bool max_bandwidth_resumption) override {}
@@ -130,6 +131,9 @@
   void OnApplicationLimited(QuicByteCount bytes_in_flight) override;
   // End implementation of SendAlgorithmInterface.
 
+  // Gets the number of RTTs BBR remains in STARTUP phase.
+  QuicRoundTripCount num_startup_rtts() const { return num_startup_rtts_; }
+
   DebugState ExportDebugState() const;
 
  private:
@@ -242,6 +246,8 @@
   // The coefficient by which mean RTT variance is added to the congestion
   // window.  Latched from quic_bbr_rtt_variation_weight flag.
   const float rtt_variance_weight_;
+  // The number of RTTs to stay in STARTUP mode.  Defaults to 3.
+  QuicRoundTripCount num_startup_rtts_;
 
   // Number of round-trips in PROBE_BW mode, used for determining the current
   // pacing gain cycle.
diff --git a/net/quic/core/congestion_control/bbr_sender_test.cc b/net/quic/core/congestion_control/bbr_sender_test.cc
index 1497689b..d987655 100644
--- a/net/quic/core/congestion_control/bbr_sender_test.cc
+++ b/net/quic/core/congestion_control/bbr_sender_test.cc
@@ -461,5 +461,71 @@
   EXPECT_GE(sender_->PacingRate(0), initial_rate);
 }
 
+// Test exiting STARTUP earlier due to the 1RTT connection option.
+TEST_F(BbrSenderTest, SimpleTransfer1RTTStartup) {
+  FLAGS_quic_reloadable_flag_quic_allow_2_rtt_bbr_startup = true;
+  CreateDefaultSetup();
+
+  QuicConfig config;
+  QuicTagVector options;
+  options.push_back(k1RTT);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  sender_->SetFromConfig(config, Perspective::IS_SERVER);
+  EXPECT_EQ(1u, sender_->num_startup_rtts());
+
+  // Run until the full bandwidth is reached and check how many rounds it was.
+  bbr_sender_.AddBytesToTransfer(12 * 1024 * 1024);
+  QuicRoundTripCount max_bw_round = 0;
+  QuicBandwidth max_bw(QuicBandwidth::Zero());
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this, &max_bw, &max_bw_round]() {
+        if (max_bw < sender_->ExportDebugState().max_bandwidth) {
+          max_bw = sender_->ExportDebugState().max_bandwidth;
+          max_bw_round = sender_->ExportDebugState().round_trip_count;
+        }
+        return sender_->ExportDebugState().is_at_full_bandwidth;
+      },
+      QuicTime::Delta::FromSeconds(5));
+  ASSERT_TRUE(simulator_result);
+  EXPECT_EQ(BbrSender::DRAIN, sender_->ExportDebugState().mode);
+  EXPECT_EQ(1u, sender_->ExportDebugState().round_trip_count - max_bw_round);
+  EXPECT_EQ(1u, sender_->ExportDebugState().rounds_without_bandwidth_gain);
+  EXPECT_EQ(0u, bbr_sender_.connection()->GetStats().packets_lost);
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+}
+
+// Test exiting STARTUP earlier due to the 2RTT connection option.
+TEST_F(BbrSenderTest, SimpleTransfer2RTTStartup) {
+  FLAGS_quic_reloadable_flag_quic_allow_2_rtt_bbr_startup = true;
+  CreateDefaultSetup();
+
+  QuicConfig config;
+  QuicTagVector options;
+  options.push_back(k2RTT);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  sender_->SetFromConfig(config, Perspective::IS_SERVER);
+  EXPECT_EQ(2u, sender_->num_startup_rtts());
+
+  // Run until the full bandwidth is reached and check how many rounds it was.
+  bbr_sender_.AddBytesToTransfer(12 * 1024 * 1024);
+  QuicRoundTripCount max_bw_round = 0;
+  QuicBandwidth max_bw(QuicBandwidth::Zero());
+  bool simulator_result = simulator_.RunUntilOrTimeout(
+      [this, &max_bw, &max_bw_round]() {
+        if (max_bw < sender_->ExportDebugState().max_bandwidth) {
+          max_bw = sender_->ExportDebugState().max_bandwidth;
+          max_bw_round = sender_->ExportDebugState().round_trip_count;
+        }
+        return sender_->ExportDebugState().is_at_full_bandwidth;
+      },
+      QuicTime::Delta::FromSeconds(5));
+  ASSERT_TRUE(simulator_result);
+  EXPECT_EQ(BbrSender::DRAIN, sender_->ExportDebugState().mode);
+  EXPECT_EQ(2u, sender_->ExportDebugState().round_trip_count - max_bw_round);
+  EXPECT_EQ(2u, sender_->ExportDebugState().rounds_without_bandwidth_gain);
+  EXPECT_EQ(0u, bbr_sender_.connection()->GetStats().packets_lost);
+  EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
+}
+
 }  // namespace test
 }  // namespace net
diff --git a/net/quic/core/congestion_control/cubic.cc b/net/quic/core/congestion_control/cubic.cc
index d3e04aa..2b023df 100644
--- a/net/quic/core/congestion_control/cubic.cc
+++ b/net/quic/core/congestion_control/cubic.cc
@@ -124,22 +124,18 @@
     QuicTime event_time) {
   acked_packets_count_ += 1;  // Packets acked.
   epoch_packets_count_ += 1;
-  QuicTime current_time = FLAGS_quic_reloadable_flag_quic_use_event_time
-                              ? event_time
-                              : clock_->ApproximateNow();
-
   // Cubic is "independent" of RTT, the update is limited by the time elapsed.
   if (last_congestion_window_ == current_congestion_window &&
-      (current_time - last_update_time_ <= MaxCubicTimeInterval())) {
+      (event_time - last_update_time_ <= MaxCubicTimeInterval())) {
     return std::max(last_target_congestion_window_,
                     estimated_tcp_congestion_window_);
   }
   last_congestion_window_ = current_congestion_window;
-  last_update_time_ = current_time;
+  last_update_time_ = event_time;
 
   if (!epoch_.IsInitialized()) {
     // First ACK after a loss event.
-    epoch_ = current_time;     // Start of epoch.
+    epoch_ = event_time;       // Start of epoch.
     acked_packets_count_ = 1;  // Reset count.
     epoch_packets_count_ = 1;
     // Reset estimated_tcp_congestion_window_ to be in sync with cubic.
@@ -159,7 +155,7 @@
   // the round trip time in account. This is done to allow us to use shift as a
   // divide operator.
   const int64_t elapsed_time =
-      ((current_time + delay_min - epoch_).ToMicroseconds() << 10) /
+      ((event_time + delay_min - epoch_).ToMicroseconds() << 10) /
       kNumMicrosPerSecond;
   DCHECK_GE(elapsed_time, 0);
 
diff --git a/net/quic/core/congestion_control/cubic_bytes.cc b/net/quic/core/congestion_control/cubic_bytes.cc
index ea19622e..e18e056 100644
--- a/net/quic/core/congestion_control/cubic_bytes.cc
+++ b/net/quic/core/congestion_control/cubic_bytes.cc
@@ -141,23 +141,19 @@
     QuicTime::Delta delay_min,
     QuicTime event_time) {
   acked_bytes_count_ += acked_bytes;
-  QuicTime current_time = FLAGS_quic_reloadable_flag_quic_use_event_time
-                              ? event_time
-                              : clock_->ApproximateNow();
-
   // Cubic is "independent" of RTT, the update is limited by the time elapsed.
   if (last_congestion_window_ == current_congestion_window &&
-      (current_time - last_update_time_ <= MaxCubicTimeInterval())) {
+      (event_time - last_update_time_ <= MaxCubicTimeInterval())) {
     return std::max(last_target_congestion_window_,
                     estimated_tcp_congestion_window_);
   }
   last_congestion_window_ = current_congestion_window;
-  last_update_time_ = current_time;
+  last_update_time_ = event_time;
 
   if (!epoch_.IsInitialized()) {
     // First ACK after a loss event.
     QUIC_DVLOG(1) << "Start of epoch";
-    epoch_ = current_time;             // Start of epoch.
+    epoch_ = event_time;               // Start of epoch.
     acked_bytes_count_ = acked_bytes;  // Reset count.
     // Reset estimated_tcp_congestion_window_ to be in sync with cubic.
     estimated_tcp_congestion_window_ = current_congestion_window;
@@ -175,7 +171,7 @@
   // the round trip time in account. This is done to allow us to use shift as a
   // divide operator.
   int64_t elapsed_time =
-      ((current_time + delay_min - epoch_).ToMicroseconds() << 10) /
+      ((event_time + delay_min - epoch_).ToMicroseconds() << 10) /
       kNumMicrosPerSecond;
 
   int64_t offset = time_to_origin_point_ - elapsed_time;
diff --git a/net/quic/core/congestion_control/general_loss_algorithm_test.cc b/net/quic/core/congestion_control/general_loss_algorithm_test.cc
index da9d11c..6fa96d7 100644
--- a/net/quic/core/congestion_control/general_loss_algorithm_test.cc
+++ b/net/quic/core/congestion_control/general_loss_algorithm_test.cc
@@ -35,18 +35,16 @@
   void SendDataPacket(QuicPacketNumber packet_number) {
     QuicStreamFrame* frame = new QuicStreamFrame();
     frame->stream_id = kHeadersStreamId;
-    SerializedPacket packet(kDefaultPathId, packet_number,
-                            PACKET_1BYTE_PACKET_NUMBER, nullptr, kDefaultLength,
-                            false, false);
+    SerializedPacket packet(packet_number, PACKET_1BYTE_PACKET_NUMBER, nullptr,
+                            kDefaultLength, false, false);
     packet.retransmittable_frames.push_back(QuicFrame(frame));
     unacked_packets_.AddSentPacket(&packet, 0, NOT_RETRANSMISSION, clock_.Now(),
                                    true);
   }
 
   void SendAckPacket(QuicPacketNumber packet_number) {
-    SerializedPacket packet(kDefaultPathId, packet_number,
-                            PACKET_1BYTE_PACKET_NUMBER, nullptr, kDefaultLength,
-                            true, false);
+    SerializedPacket packet(packet_number, PACKET_1BYTE_PACKET_NUMBER, nullptr,
+                            kDefaultLength, true, false);
     unacked_packets_.AddSentPacket(&packet, 0, NOT_RETRANSMISSION, clock_.Now(),
                                    false);
   }
diff --git a/net/quic/core/crypto/crypto_protocol.h b/net/quic/core/crypto/crypto_protocol.h
index e426832..9a7876d 100644
--- a/net/quic/core/crypto/crypto_protocol.h
+++ b/net/quic/core/crypto/crypto_protocol.h
@@ -79,6 +79,8 @@
                                                  // receive window to
                                                  // 1MB. (2^0xa KB).
 const QuicTag kTBBR = TAG('T', 'B', 'B', 'R');   // Reduced Buffer Bloat TCP
+const QuicTag k1RTT = TAG('1', 'R', 'T', 'T');   // STARTUP in BBR for 1 RTT
+const QuicTag k2RTT = TAG('2', 'R', 'T', 'T');   // STARTUP in BBR for 2 RTTs
 const QuicTag kRENO = TAG('R', 'E', 'N', 'O');   // Reno Congestion Control
 const QuicTag kBYTE = TAG('B', 'Y', 'T', 'E');   // TCP cubic or reno in bytes
 const QuicTag kRATE = TAG('R', 'A', 'T', 'E');   // TCP cubic rate based sending
@@ -123,6 +125,7 @@
 const QuicTag kCCVX = TAG('C', 'C', 'V', 'X');   // Fix Cubic convex bug.
 const QuicTag kCBQT = TAG('C', 'B', 'Q', 'T');   // Fix CubicBytes quantization.
 const QuicTag kBLMX = TAG('B', 'L', 'M', 'X');   // Fix Cubic BetaLastMax bug.
+const QuicTag kNSTP = TAG('N', 'S', 'T', 'P');   // No stop waiting frames.
 
 // 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/core/frames/quic_ack_frame.cc b/net/quic/core/frames/quic_ack_frame.cc
index 0f7464a..8dcb1373 100644
--- a/net/quic/core/frames/quic_ack_frame.cc
+++ b/net/quic/core/frames/quic_ack_frame.cc
@@ -5,6 +5,7 @@
 #include "net/quic/core/frames/quic_ack_frame.h"
 
 #include "net/quic/core/quic_constants.h"
+#include "net/quic/platform/api/quic_bug_tracker.h"
 
 namespace net {
 
@@ -16,9 +17,7 @@
 }
 
 QuicAckFrame::QuicAckFrame()
-    : largest_observed(0),
-      ack_delay_time(QuicTime::Delta::Infinite()),
-      path_id(kDefaultPathId) {}
+    : largest_observed(0), ack_delay_time(QuicTime::Delta::Infinite()) {}
 
 QuicAckFrame::QuicAckFrame(const QuicAckFrame& other) = default;
 
@@ -73,6 +72,14 @@
   return Empty() || old_min != Min();
 }
 
+void PacketNumberQueue::RemoveSmallestInterval() {
+  QUIC_BUG_IF(packet_number_intervals_.Size() < 2)
+      << (Empty() ? "No intervals to remove."
+                  : "Can't remove the last interval.");
+
+  packet_number_intervals_.Difference(*packet_number_intervals_.begin());
+}
+
 void PacketNumberQueue::Complement() {
   if (Empty()) {
     return;
diff --git a/net/quic/core/frames/quic_ack_frame.h b/net/quic/core/frames/quic_ack_frame.h
index 816a4ac..bdfc4be 100644
--- a/net/quic/core/frames/quic_ack_frame.h
+++ b/net/quic/core/frames/quic_ack_frame.h
@@ -50,6 +50,9 @@
   // the queue. Returns true if packets were removed.
   bool RemoveUpTo(QuicPacketNumber higher);
 
+  // Removes the smallest interval in the queue.
+  void RemoveSmallestInterval();
+
   // Mutates packet number set so that it contains only those packet numbers
   // from minimum to maximum packet number not currently in the set. Do nothing
   // if packet number set is empty.
@@ -115,9 +118,6 @@
 
   // Set of packets.
   PacketNumberQueue packets;
-
-  // Path which this ack belongs to.
-  QuicPathId path_id;
 };
 
 // True if the packet number is greater than largest_observed or is listed
diff --git a/net/quic/core/frames/quic_frames_test.cc b/net/quic/core/frames/quic_frames_test.cc
index 11f083ec..82b9667 100644
--- a/net/quic/core/frames/quic_frames_test.cc
+++ b/net/quic/core/frames/quic_frames_test.cc
@@ -145,6 +145,23 @@
   EXPECT_TRUE(IsAwaitingPacket(ack_frame2, 50u, 20u));
 }
 
+TEST(QuicFramesTest, RemoveSmallestInterval) {
+  QuicAckFrame ack_frame1;
+  ack_frame1.largest_observed = 100u;
+  ack_frame1.packets.Add(51, 60);
+  ack_frame1.packets.Add(71, 80);
+  ack_frame1.packets.Add(91, 100);
+  ack_frame1.packets.RemoveSmallestInterval();
+  EXPECT_EQ(2u, ack_frame1.packets.NumIntervals());
+  EXPECT_EQ(71u, ack_frame1.packets.Min());
+  EXPECT_EQ(99u, ack_frame1.packets.Max());
+
+  ack_frame1.packets.RemoveSmallestInterval();
+  EXPECT_EQ(1u, ack_frame1.packets.NumIntervals());
+  EXPECT_EQ(91u, ack_frame1.packets.Min());
+  EXPECT_EQ(99u, ack_frame1.packets.Max());
+}
+
 // Tests that a queue contains the expected data after calls to Add().
 TEST(PacketNumberQueueTest, AddRange) {
   PacketNumberQueue queue;
diff --git a/net/quic/core/frames/quic_stop_waiting_frame.cc b/net/quic/core/frames/quic_stop_waiting_frame.cc
index b051beb..b61b32ac 100644
--- a/net/quic/core/frames/quic_stop_waiting_frame.cc
+++ b/net/quic/core/frames/quic_stop_waiting_frame.cc
@@ -8,8 +8,7 @@
 
 namespace net {
 
-QuicStopWaitingFrame::QuicStopWaitingFrame()
-    : path_id(kDefaultPathId), least_unacked(0) {}
+QuicStopWaitingFrame::QuicStopWaitingFrame() : least_unacked(0) {}
 
 QuicStopWaitingFrame::~QuicStopWaitingFrame() {}
 
diff --git a/net/quic/core/frames/quic_stop_waiting_frame.h b/net/quic/core/frames/quic_stop_waiting_frame.h
index 1c02a77..7632d08 100644
--- a/net/quic/core/frames/quic_stop_waiting_frame.h
+++ b/net/quic/core/frames/quic_stop_waiting_frame.h
@@ -20,8 +20,6 @@
       std::ostream& os,
       const QuicStopWaitingFrame& s);
 
-  // Path which this stop waiting frame belongs to.
-  QuicPathId path_id;
   // The lowest packet we've sent which is unacked, and we expect an ack for.
   QuicPacketNumber least_unacked;
 };
diff --git a/net/quic/core/quic_connection.cc b/net/quic/core/quic_connection.cc
index ae9e1cd..60e6d7e 100644
--- a/net/quic/core/quic_connection.cc
+++ b/net/quic/core/quic_connection.cc
@@ -29,6 +29,7 @@
 #include "net/quic/core/quic_pending_retransmission.h"
 #include "net/quic/core/quic_utils.h"
 #include "net/quic/platform/api/quic_bug_tracker.h"
+#include "net/quic/platform/api/quic_flag_utils.h"
 #include "net/quic/platform/api/quic_logging.h"
 #include "net/quic/platform/api/quic_map_util.h"
 #include "net/quic/platform/api/quic_str_cat.h"
@@ -260,7 +261,8 @@
       goaway_sent_(false),
       goaway_received_(false),
       multipath_enabled_(false),
-      write_error_occured_(false) {
+      write_error_occured_(false),
+      no_stop_waiting_frames_(false) {
   QUIC_DLOG(INFO) << ENDPOINT
                   << "Created connection with connection_id: " << connection_id;
   framer_.set_visitor(this);
@@ -273,6 +275,10 @@
   SetMaxPacketLength(perspective_ == Perspective::IS_SERVER
                          ? kDefaultServerMaxPacketSize
                          : kDefaultMaxPacketSize);
+  if (packet_generator_.latched_flag_no_stop_waiting_frames()) {
+    QUIC_FLAG_COUNT_N(gfe2_reloadable_flag_quic_no_stop_waiting_frame, 1, 2);
+    received_packet_manager_.set_max_ack_ranges(255);
+  }
 }
 
 QuicConnection::~QuicConnection() {
@@ -345,6 +351,11 @@
   if (config.HasClientSentConnectionOption(k5RTO, perspective_)) {
     close_connection_after_five_rtos_ = true;
   }
+  if (packet_generator_.latched_flag_no_stop_waiting_frames() &&
+      config.HasClientSentConnectionOption(kNSTP, perspective_)) {
+    QUIC_FLAG_COUNT_N(gfe2_reloadable_flag_quic_no_stop_waiting_frame, 2, 2);
+    no_stop_waiting_frames_ = true;
+  }
 }
 
 void QuicConnection::OnSendConnectionState(
@@ -694,6 +705,10 @@
   largest_seen_packet_with_ack_ = last_header_.packet_number;
   sent_packet_manager_.OnIncomingAck(incoming_ack,
                                      time_of_last_received_packet_);
+  if (no_stop_waiting_frames_) {
+    received_packet_manager_.DontWaitForPacketsBefore(
+        sent_packet_manager_.largest_packet_peer_knows_is_acked());
+  }
   // Always reset the retransmission alarm when an ack comes in, since we now
   // have a better estimate of the current rtt than when it was set.
   SetRetransmissionAlarm();
@@ -716,7 +731,9 @@
 
 bool QuicConnection::OnStopWaitingFrame(const QuicStopWaitingFrame& frame) {
   DCHECK(connected_);
-
+  if (no_stop_waiting_frames_) {
+    return true;
+  }
   if (last_header_.packet_number <= largest_seen_packet_with_stop_waiting_) {
     QUIC_DLOG(INFO) << ENDPOINT
                     << "Received an old stop waiting frame: ignoring";
@@ -1131,12 +1148,6 @@
   stats_.blocked_frames_sent++;
 }
 
-void QuicConnection::SendPathClose(QuicPathId path_id) {
-  // Opportunistically bundle an ack with this outgoing packet.
-  ScopedPacketBundler ack_bundler(this, SEND_ACK_IF_PENDING);
-  packet_generator_.AddControlFrame(QuicFrame(new QuicPathCloseFrame(path_id)));
-}
-
 const QuicConnectionStats& QuicConnection::GetStats() {
   const RttStats* rtt_stats = sent_packet_manager_.GetRttStats();
 
@@ -1186,9 +1197,8 @@
   ++stats_.packets_received;
 
   // Ensure the time coming from the packet reader is within a minute of now.
-  if (FLAGS_quic_reloadable_flag_quic_allow_large_send_deltas &&
-      std::abs((packet.receipt_time() - clock_->ApproximateNow()).ToSeconds()) >
-          60) {
+  if (std::abs((packet.receipt_time() - clock_->ApproximateNow()).ToSeconds()) >
+      60) {
     QUIC_BUG << "Packet receipt time:"
              << packet.receipt_time().ToDebuggingValue()
              << " too far from current time:"
@@ -1281,10 +1291,16 @@
     if (self_address_.port() != last_packet_destination_address_.port() ||
         self_address_.host().Normalized() !=
             last_packet_destination_address_.host().Normalized()) {
-      CloseConnection(QUIC_ERROR_MIGRATING_ADDRESS,
-                      "Self address migration is not supported at the server.",
-                      ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
-      return false;
+      if (FLAGS_quic_reloadable_flag_quic_allow_one_address_change &&
+          AllowSelfAddressChange()) {
+        OnSelfAddressChange();
+      } else {
+        CloseConnection(
+            QUIC_ERROR_MIGRATING_ADDRESS,
+            "Self address migration is not supported at the server.",
+            ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+        return false;
+      }
     }
     self_address_ = last_packet_destination_address_;
   }
@@ -1618,6 +1634,10 @@
   return false;
 }
 
+bool QuicConnection::AllowSelfAddressChange() const {
+  return false;
+}
+
 void QuicConnection::OnWriteError(int error_code) {
   if (write_error_occured_) {
     // A write error already occurred. The connection is being closed.
@@ -1642,7 +1662,6 @@
 }
 
 void QuicConnection::OnSerializedPacket(SerializedPacket* serialized_packet) {
-  DCHECK_NE(kInvalidPathId, serialized_packet->path_id);
   if (serialized_packet->encrypted_buffer == nullptr) {
     // We failed to serialize the packet, so close the connection.
     // TearDownLocalConnectionState does not send close packet, so no infinite
@@ -1743,7 +1762,7 @@
   last_ack_had_missing_packets_ = received_packet_manager_.HasMissingPackets();
   num_packets_received_since_last_ack_sent_ = 0;
 
-  packet_generator_.SetShouldSendAck(true);
+  packet_generator_.SetShouldSendAck(!no_stop_waiting_frames_);
 }
 
 void QuicConnection::OnRetransmissionTimeout() {
diff --git a/net/quic/core/quic_connection.h b/net/quic/core/quic_connection.h
index ba3faf2f..bdcc2fa3 100644
--- a/net/quic/core/quic_connection.h
+++ b/net/quic/core/quic_connection.h
@@ -362,9 +362,6 @@
   // Send a WINDOW_UPDATE frame to the peer.
   virtual void SendWindowUpdate(QuicStreamId id, QuicStreamOffset byte_offset);
 
-  // Send a PATH_CLOSE frame to the peer.
-  virtual void SendPathClose(QuicPathId path_id);
-
   // Closes the connection.
   // |connection_close_behavior| determines whether or not a connection close
   // packet is sent to the peer.
@@ -741,6 +738,12 @@
   // Returns true if the packet should be discarded and not sent.
   virtual bool ShouldDiscardPacket(const SerializedPacket& packet);
 
+  // Returns true if this connection allows self address change.
+  virtual bool AllowSelfAddressChange() const;
+
+  // Called when a self address change is observed.
+  virtual void OnSelfAddressChange() {}
+
  private:
   friend class test::QuicConnectionPeer;
   friend class test::PacketSavingConnection;
@@ -1083,6 +1086,9 @@
   // avoid infinite write errors.
   bool write_error_occured_;
 
+  // Indicates not to send or process stop waiting frames.
+  bool no_stop_waiting_frames_;
+
   DISALLOW_COPY_AND_ASSIGN(QuicConnection);
 };
 
diff --git a/net/quic/core/quic_connection_test.cc b/net/quic/core/quic_connection_test.cc
index c607cc26..b8d7384 100644
--- a/net/quic/core/quic_connection_test.cc
+++ b/net/quic/core/quic_connection_test.cc
@@ -488,7 +488,6 @@
   }
 
   void SendPacket(EncryptionLevel level,
-                  QuicPathId path_id,
                   QuicPacketNumber packet_number,
                   QuicPacket* packet,
                   HasRetransmittableData retransmittable,
@@ -500,8 +499,8 @@
             ENCRYPTION_NONE, packet_number, *packet, buffer, kMaxPacketSize);
     delete packet;
     SerializedPacket serialized_packet(
-        kDefaultPathId, packet_number, PACKET_6BYTE_PACKET_NUMBER, buffer,
-        encrypted_length, has_ack, has_pending_frames);
+        packet_number, PACKET_6BYTE_PACKET_NUMBER, buffer, encrypted_length,
+        has_ack, has_pending_frames);
     if (retransmittable == HAS_RETRANSMITTABLE_DATA) {
       serialized_packet.retransmittable_frames.push_back(
           QuicFrame(new QuicStreamFrame()));
@@ -642,19 +641,24 @@
 
 // Run tests with combinations of {QuicVersion, AckResponse}.
 struct TestParams {
-  TestParams(QuicVersion version, AckResponse ack_response)
-      : version(version), ack_response(ack_response) {}
+  TestParams(QuicVersion version,
+             AckResponse ack_response,
+             bool no_stop_waiting)
+      : version(version),
+        ack_response(ack_response),
+        no_stop_waiting(no_stop_waiting) {}
 
   friend std::ostream& operator<<(std::ostream& os, const TestParams& p) {
     os << "{ client_version: " << QuicVersionToString(p.version)
        << " ack_response: "
        << (p.ack_response == AckResponse::kDefer ? "defer" : "immediate")
-       << " }";
+       << " no_stop_waiting: " << p.no_stop_waiting << " }";
     return os;
   }
 
   QuicVersion version;
   AckResponse ack_response;
+  bool no_stop_waiting;
 };
 
 // Constructs various test permutations.
@@ -664,7 +668,10 @@
   for (size_t i = 0; i < all_supported_versions.size(); ++i) {
     for (AckResponse ack_response :
          {AckResponse::kDefer, AckResponse::kImmediate}) {
-      params.push_back(TestParams(all_supported_versions[i], ack_response));
+      for (bool stop_waiting : {true, false}) {
+        params.push_back(
+            TestParams(all_supported_versions[i], ack_response, stop_waiting));
+      }
     }
   }
   return params;
@@ -705,6 +712,8 @@
         connection_id_length_(PACKET_8BYTE_CONNECTION_ID) {
     connection_.set_defer_send_in_response_to_packets(GetParam().ack_response ==
                                                       AckResponse::kDefer);
+    QuicConnectionPeer::SetNoStopWaitingFrames(&connection_,
+                                               GetParam().no_stop_waiting);
     connection_.set_visitor(&visitor_);
     connection_.SetSendAlgorithm(send_algorithm_);
     connection_.SetLossAlgorithm(loss_algorithm_.get());
@@ -762,9 +771,9 @@
 
   void use_tagging_decrypter() { writer_->use_tagging_decrypter(); }
 
-  void ProcessPacket(QuicPathId path_id, QuicPacketNumber number) {
+  void ProcessPacket(QuicPacketNumber number) {
     EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-    ProcessDataPacket(path_id, number);
+    ProcessDataPacket(number);
     if (connection_.GetSendAlarm()->IsSet()) {
       connection_.GetSendAlarm()->Fire();
     }
@@ -810,7 +819,7 @@
     DCHECK_GT(length, 0u);
 
     const size_t encrypted_length = peer_framer_.EncryptInPlace(
-        ENCRYPTION_NONE, kDefaultPathId, header.packet_number,
+        ENCRYPTION_NONE, header.packet_number,
         GetStartOfEncryptedData(peer_framer_.version(), header), length,
         kMaxPacketSize, encrypted_buffer);
     DCHECK_GT(encrypted_length, 0u);
@@ -820,16 +829,14 @@
         QuicReceivedPacket(encrypted_buffer, encrypted_length, clock_.Now()));
   }
 
-  size_t ProcessFramePacketAtLevel(QuicPathId path_id,
-                                   QuicPacketNumber number,
+  size_t ProcessFramePacketAtLevel(QuicPacketNumber number,
                                    QuicFrame frame,
                                    EncryptionLevel level) {
     QuicPacketHeader header;
     header.public_header.connection_id = connection_id_;
     header.public_header.packet_number_length = packet_number_length_;
     header.public_header.connection_id_length = connection_id_length_;
-    header.public_header.multipath_flag = path_id != kDefaultPathId;
-    header.path_id = path_id;
+    header.public_header.multipath_flag = false;
     header.packet_number = number;
     QuicFrames frames;
     frames.push_back(frame);
@@ -844,16 +851,15 @@
     return encrypted_length;
   }
 
-  size_t ProcessDataPacket(QuicPathId path_id, QuicPacketNumber number) {
-    return ProcessDataPacketAtLevel(path_id, number, false, ENCRYPTION_NONE);
+  size_t ProcessDataPacket(QuicPacketNumber number) {
+    return ProcessDataPacketAtLevel(number, false, ENCRYPTION_NONE);
   }
 
-  size_t ProcessDataPacketAtLevel(QuicPathId path_id,
-                                  QuicPacketNumber number,
+  size_t ProcessDataPacketAtLevel(QuicPacketNumber number,
                                   bool has_stop_waiting,
                                   EncryptionLevel level) {
     std::unique_ptr<QuicPacket> packet(
-        ConstructDataPacket(path_id, number, has_stop_waiting));
+        ConstructDataPacket(number, has_stop_waiting));
     char buffer[kMaxPacketSize];
     size_t encrypted_length = peer_framer_.EncryptPayload(
         level, number, *packet, buffer, kMaxPacketSize);
@@ -866,7 +872,7 @@
     return encrypted_length;
   }
 
-  void ProcessClosePacket(QuicPathId path_id, QuicPacketNumber number) {
+  void ProcessClosePacket(QuicPacketNumber number) {
     std::unique_ptr<QuicPacket> packet(ConstructClosePacket(number));
     char buffer[kMaxPacketSize];
     size_t encrypted_length = peer_framer_.EncryptPayload(
@@ -913,11 +919,10 @@
     ProcessFramePacket(QuicFrame(frame));
   }
 
-  size_t ProcessStopWaitingPacketAtLevel(QuicPathId path_id,
-                                         QuicPacketNumber number,
+  size_t ProcessStopWaitingPacketAtLevel(QuicPacketNumber number,
                                          QuicStopWaitingFrame* frame,
                                          EncryptionLevel level) {
-    return ProcessFramePacketAtLevel(path_id, number, QuicFrame(frame),
+    return ProcessFramePacketAtLevel(number, QuicFrame(frame),
                                      ENCRYPTION_INITIAL);
   }
 
@@ -939,15 +944,13 @@
     return packet;
   }
 
-  QuicPacket* ConstructDataPacket(QuicPathId path_id,
-                                  QuicPacketNumber number,
+  QuicPacket* ConstructDataPacket(QuicPacketNumber number,
                                   bool has_stop_waiting) {
     QuicPacketHeader header;
     header.public_header.connection_id = connection_id_;
     header.public_header.packet_number_length = packet_number_length_;
     header.public_header.connection_id_length = connection_id_length_;
-    header.public_header.multipath_flag = path_id != kDefaultPathId;
-    header.path_id = path_id;
+    header.public_header.multipath_flag = false;
     header.packet_number = number;
 
     QuicFrames frames;
@@ -1012,7 +1015,7 @@
                                              ConnectionCloseSource::FROM_SELF));
     // Call ProcessDataPacket rather than ProcessPacket, as we should not get a
     // packet call to the visitor.
-    ProcessDataPacket(kDefaultPathId, 6000);
+    ProcessDataPacket(6000);
     EXPECT_FALSE(QuicConnectionPeer::GetConnectionClosePacket(&connection_) ==
                  nullptr);
   }
@@ -1203,7 +1206,6 @@
   QuicPacketHeader header;
   header.public_header.connection_id = connection_id_;
   header.public_header.version_flag = true;
-  header.path_id = kDefaultPathId;
   header.packet_number = 1;
 
   QuicFrames frames;
@@ -1237,7 +1239,6 @@
   QuicPacketHeader header;
   header.public_header.connection_id = connection_id_;
   header.public_header.version_flag = true;
-  header.path_id = kDefaultPathId;
   header.packet_number = 1;
 
   QuicFrames frames;
@@ -1286,15 +1287,15 @@
 TEST_P(QuicConnectionTest, PacketsInOrder) {
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
 
-  ProcessPacket(kDefaultPathId, 1);
+  ProcessPacket(1);
   EXPECT_EQ(1u, outgoing_ack()->largest_observed);
   EXPECT_EQ(1u, outgoing_ack()->packets.NumIntervals());
 
-  ProcessPacket(kDefaultPathId, 2);
+  ProcessPacket(2);
   EXPECT_EQ(2u, outgoing_ack()->largest_observed);
   EXPECT_EQ(1u, outgoing_ack()->packets.NumIntervals());
 
-  ProcessPacket(kDefaultPathId, 3);
+  ProcessPacket(3);
   EXPECT_EQ(3u, outgoing_ack()->largest_observed);
   EXPECT_EQ(1u, outgoing_ack()->packets.NumIntervals());
 }
@@ -1302,17 +1303,17 @@
 TEST_P(QuicConnectionTest, PacketsOutOfOrder) {
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
 
-  ProcessPacket(kDefaultPathId, 3);
+  ProcessPacket(3);
   EXPECT_EQ(3u, outgoing_ack()->largest_observed);
   EXPECT_TRUE(IsMissing(2));
   EXPECT_TRUE(IsMissing(1));
 
-  ProcessPacket(kDefaultPathId, 2);
+  ProcessPacket(2);
   EXPECT_EQ(3u, outgoing_ack()->largest_observed);
   EXPECT_FALSE(IsMissing(2));
   EXPECT_TRUE(IsMissing(1));
 
-  ProcessPacket(kDefaultPathId, 1);
+  ProcessPacket(1);
   EXPECT_EQ(3u, outgoing_ack()->largest_observed);
   EXPECT_FALSE(IsMissing(2));
   EXPECT_FALSE(IsMissing(1));
@@ -1321,14 +1322,14 @@
 TEST_P(QuicConnectionTest, DuplicatePacket) {
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
 
-  ProcessPacket(kDefaultPathId, 3);
+  ProcessPacket(3);
   EXPECT_EQ(3u, outgoing_ack()->largest_observed);
   EXPECT_TRUE(IsMissing(2));
   EXPECT_TRUE(IsMissing(1));
 
   // Send packet 3 again, but do not set the expectation that
   // the visitor OnStreamFrame() will be called.
-  ProcessDataPacket(kDefaultPathId, 3);
+  ProcessDataPacket(3);
   EXPECT_EQ(3u, outgoing_ack()->largest_observed);
   EXPECT_TRUE(IsMissing(2));
   EXPECT_TRUE(IsMissing(1));
@@ -1337,16 +1338,16 @@
 TEST_P(QuicConnectionTest, PacketsOutOfOrderWithAdditionsAndLeastAwaiting) {
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
 
-  ProcessPacket(kDefaultPathId, 3);
+  ProcessPacket(3);
   EXPECT_EQ(3u, outgoing_ack()->largest_observed);
   EXPECT_TRUE(IsMissing(2));
   EXPECT_TRUE(IsMissing(1));
 
-  ProcessPacket(kDefaultPathId, 2);
+  ProcessPacket(2);
   EXPECT_EQ(3u, outgoing_ack()->largest_observed);
   EXPECT_TRUE(IsMissing(1));
 
-  ProcessPacket(kDefaultPathId, 5);
+  ProcessPacket(5);
   EXPECT_EQ(5u, outgoing_ack()->largest_observed);
   EXPECT_TRUE(IsMissing(1));
   EXPECT_TRUE(IsMissing(4));
@@ -1369,7 +1370,7 @@
                                            ConnectionCloseSource::FROM_SELF));
   // Call ProcessDataPacket rather than ProcessPacket, as we should not get a
   // packet call to the visitor.
-  ProcessDataPacket(kDefaultPathId, 6000);
+  ProcessDataPacket(6000);
   EXPECT_FALSE(QuicConnectionPeer::GetConnectionClosePacket(&connection_) ==
                nullptr);
 }
@@ -1380,7 +1381,7 @@
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
   EXPECT_CALL(visitor_, OnConnectionClosed(QUIC_UNENCRYPTED_STREAM_DATA, _,
                                            ConnectionCloseSource::FROM_SELF));
-  EXPECT_QUIC_BUG(ProcessDataPacket(kDefaultPathId, 1), "");
+  EXPECT_QUIC_BUG(ProcessDataPacket(1), "");
   EXPECT_FALSE(QuicConnectionPeer::GetConnectionClosePacket(&connection_) ==
                nullptr);
   const std::vector<QuicConnectionCloseFrame>& connection_close_frames =
@@ -1393,19 +1394,19 @@
 TEST_P(QuicConnectionTest, OutOfOrderReceiptCausesAckSend) {
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
 
-  ProcessPacket(kDefaultPathId, 3);
+  ProcessPacket(3);
   // Should ack immediately since we have missing packets.
   EXPECT_EQ(1u, writer_->packets_write_attempts());
 
-  ProcessPacket(kDefaultPathId, 2);
+  ProcessPacket(2);
   // Should ack immediately since we have missing packets.
   EXPECT_EQ(2u, writer_->packets_write_attempts());
 
-  ProcessPacket(kDefaultPathId, 1);
+  ProcessPacket(1);
   // Should ack immediately, since this fills the last hole.
   EXPECT_EQ(3u, writer_->packets_write_attempts());
 
-  ProcessPacket(kDefaultPathId, 4);
+  ProcessPacket(4);
   // Should not cause an ack.
   EXPECT_EQ(3u, writer_->packets_write_attempts());
 }
@@ -1475,7 +1476,11 @@
               OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA));
   connection_.SendStreamDataWithString(3, "foo", 3, !kFin, nullptr);
   // Ack bundled.
-  EXPECT_EQ(3u, writer_->frame_count());
+  if (GetParam().no_stop_waiting) {
+    EXPECT_EQ(2u, writer_->frame_count());
+  } else {
+    EXPECT_EQ(3u, writer_->frame_count());
+  }
   EXPECT_EQ(1u, writer_->stream_frames().size());
   EXPECT_FALSE(writer_->ack_frames().empty());
 
@@ -1521,16 +1526,20 @@
   QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 1);
   // The scheduler will not process out of order acks, but all packet processing
   // causes the connection to try to write.
-  EXPECT_CALL(visitor_, OnCanWrite());
+  if (!GetParam().no_stop_waiting) {
+    EXPECT_CALL(visitor_, OnCanWrite());
+  }
   QuicStopWaitingFrame frame2 = InitStopWaitingFrame(1);
   ProcessStopWaitingPacket(&frame2);
 
   // Now claim it's one, but set the ordering so it was sent "after" the first
   // one.  This should cause a connection error.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
   QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 7);
-  EXPECT_CALL(visitor_, OnConnectionClosed(QUIC_INVALID_STOP_WAITING_DATA, _,
-                                           ConnectionCloseSource::FROM_SELF));
+  if (!GetParam().no_stop_waiting) {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
+    EXPECT_CALL(visitor_, OnConnectionClosed(QUIC_INVALID_STOP_WAITING_DATA, _,
+                                             ConnectionCloseSource::FROM_SELF));
+  }
   QuicStopWaitingFrame frame3 = InitStopWaitingFrame(1);
   ProcessStopWaitingPacket(&frame3);
 }
@@ -1556,7 +1565,7 @@
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
   // Miss 99 of every 100 packets for 5500 packets.
   for (QuicPacketNumber i = 1; i < kMaxTrackedPackets + 500; i += 100) {
-    ProcessPacket(kDefaultPathId, i);
+    ProcessPacket(i);
     if (!connection_.connected()) {
       break;
     }
@@ -1596,7 +1605,7 @@
 
 TEST_P(QuicConnectionTest, AckAll) {
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  ProcessPacket(kDefaultPathId, 1);
+  ProcessPacket(1);
 
   QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 1);
   QuicAckFrame frame1 = InitAckFrame(0);
@@ -1610,15 +1619,30 @@
   EXPECT_EQ(1u, last_packet);
   SendAckPacketToPeer();  // Packet 2
 
-  EXPECT_EQ(1u, least_unacked());
+  if (GetParam().no_stop_waiting) {
+    // Expect no stop waiting frame is sent.
+    EXPECT_EQ(0u, least_unacked());
+  } else {
+    EXPECT_EQ(1u, least_unacked());
+  }
 
   SendAckPacketToPeer();  // Packet 3
-  EXPECT_EQ(1u, least_unacked());
+  if (GetParam().no_stop_waiting) {
+    // Expect no stop waiting frame is sent.
+    EXPECT_EQ(0u, least_unacked());
+  } else {
+    EXPECT_EQ(1u, least_unacked());
+  }
 
   SendStreamDataToPeer(1, "bar", 3, !kFin, &last_packet);  // Packet 4
   EXPECT_EQ(4u, last_packet);
   SendAckPacketToPeer();  // Packet 5
-  EXPECT_EQ(1u, least_unacked());
+  if (GetParam().no_stop_waiting) {
+    // Expect no stop waiting frame is sent.
+    EXPECT_EQ(0u, least_unacked());
+  } else {
+    EXPECT_EQ(1u, least_unacked());
+  }
 
   EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
 
@@ -1629,7 +1653,12 @@
 
   // As soon as we've acked one, we skip ack packets 2 and 3 and note lack of
   // ack for 4.
-  EXPECT_EQ(4u, least_unacked());
+  if (GetParam().no_stop_waiting) {
+    // Expect no stop waiting frame is sent.
+    EXPECT_EQ(0u, least_unacked());
+  } else {
+    EXPECT_EQ(4u, least_unacked());
+  }
 
   EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
 
@@ -1641,17 +1670,32 @@
   EXPECT_EQ(6u, writer_->header().packet_number);
 
   // So the last ack has not changed.
-  EXPECT_EQ(4u, least_unacked());
+  if (GetParam().no_stop_waiting) {
+    // Expect no stop waiting frame is sent.
+    EXPECT_EQ(0u, least_unacked());
+  } else {
+    EXPECT_EQ(4u, least_unacked());
+  }
 
   // If we force an ack, we shouldn't change our retransmit state.
   SendAckPacketToPeer();  // Packet 7
-  EXPECT_EQ(7u, least_unacked());
+  if (GetParam().no_stop_waiting) {
+    // Expect no stop waiting frame is sent.
+    EXPECT_EQ(0u, least_unacked());
+  } else {
+    EXPECT_EQ(7u, least_unacked());
+  }
 
   // But if we send more data it should.
   SendStreamDataToPeer(1, "eep", 6, !kFin, &last_packet);  // Packet 8
   EXPECT_EQ(8u, last_packet);
   SendAckPacketToPeer();  // Packet 9
-  EXPECT_EQ(7u, least_unacked());
+  if (GetParam().no_stop_waiting) {
+    // Expect no stop waiting frame is sent.
+    EXPECT_EQ(0u, least_unacked());
+  } else {
+    EXPECT_EQ(7u, least_unacked());
+  }
 }
 
 // QuicConnection should record the the packet sent-time prior to sending the
@@ -1701,8 +1745,13 @@
 
   // Parse the last packet and ensure it's an ack and two stream frames from
   // two different streams.
-  EXPECT_EQ(4u, writer_->frame_count());
-  EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  if (GetParam().no_stop_waiting) {
+    EXPECT_EQ(3u, writer_->frame_count());
+    EXPECT_TRUE(writer_->stop_waiting_frames().empty());
+  } else {
+    EXPECT_EQ(4u, writer_->frame_count());
+    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  }
   EXPECT_FALSE(writer_->ack_frames().empty());
   ASSERT_EQ(2u, writer_->stream_frames().size());
   EXPECT_EQ(kClientDataStreamId1, writer_->stream_frames()[0]->stream_id);
@@ -1751,7 +1800,7 @@
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
   // Process a data packet to queue up a pending ack.
   EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-  ProcessDataPacket(kDefaultPathId, 1);
+  ProcessDataPacket(1);
 
   EXPECT_CALL(visitor_, OnCanWrite())
       .WillOnce(DoAll(IgnoreResult(InvokeWithoutArgs(
@@ -1770,8 +1819,13 @@
 
   // Parse the last packet and ensure it's an ack and two stream frames from
   // two different streams.
-  EXPECT_EQ(4u, writer_->frame_count());
-  EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  if (GetParam().no_stop_waiting) {
+    EXPECT_EQ(3u, writer_->frame_count());
+    EXPECT_TRUE(writer_->stop_waiting_frames().empty());
+  } else {
+    EXPECT_EQ(4u, writer_->frame_count());
+    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  }
   EXPECT_FALSE(writer_->ack_frames().empty());
   ASSERT_EQ(2u, writer_->stream_frames().size());
   EXPECT_EQ(kClientDataStreamId1, writer_->stream_frames()[0]->stream_id);
@@ -2180,8 +2234,7 @@
 
   EXPECT_EQ(0u, connection_.NumQueuedPackets());
   // We do not store retransmittable frames of this retransmission.
-  EXPECT_FALSE(QuicConnectionPeer::HasRetransmittableFrames(&connection_,
-                                                            kDefaultPathId, 4));
+  EXPECT_FALSE(QuicConnectionPeer::HasRetransmittableFrames(&connection_, 4));
 }
 
 TEST_P(QuicConnectionTest, RetransmitNackedLargestObserved) {
@@ -2284,8 +2337,7 @@
   connection_.OnCanWrite();
   // There is now a pending packet, but with no retransmittable frames.
   EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
-  EXPECT_FALSE(QuicConnectionPeer::HasRetransmittableFrames(&connection_,
-                                                            ack.path_id, 2));
+  EXPECT_FALSE(QuicConnectionPeer::HasRetransmittableFrames(&connection_, 2));
 }
 
 TEST_P(QuicConnectionTest, AlarmsWhenWriteBlocked) {
@@ -2389,8 +2441,13 @@
   SendAckPacketToPeer();  // Packet 3
   // Least_unacked remains at 3 until another ack is received.
   EXPECT_EQ(3u, stop_waiting()->least_unacked);
-  // Check that the outgoing ack had its packet number as least_unacked.
-  EXPECT_EQ(3u, least_unacked());
+  if (GetParam().no_stop_waiting) {
+    // Expect no stop waiting frame is sent.
+    EXPECT_EQ(0u, least_unacked());
+  } else {
+    // Check that the outgoing ack had its packet number as least_unacked.
+    EXPECT_EQ(3u, least_unacked());
+  }
 
   // Ack the ack, which updates the rtt and raises the least unacked.
   EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
@@ -2404,7 +2461,12 @@
   ON_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
       .WillByDefault(Return(false));
   SendAckPacketToPeer();  // Packet 5
-  EXPECT_EQ(4u, least_unacked());
+  if (GetParam().no_stop_waiting) {
+    // Expect no stop waiting frame is sent.
+    EXPECT_EQ(0u, least_unacked());
+  } else {
+    EXPECT_EQ(4u, least_unacked());
+  }
 
   // Send two data packets at the end, and ensure if the last one is acked,
   // the least unacked is raised above the ack packets.
@@ -2574,8 +2636,7 @@
 
   // Process an encrypted packet which can not yet be decrypted which should
   // result in the packet being buffered.
-  ProcessDataPacketAtLevel(kDefaultPathId, 1, !kHasStopWaiting,
-                           ENCRYPTION_INITIAL);
+  ProcessDataPacketAtLevel(1, !kHasStopWaiting, ENCRYPTION_INITIAL);
 
   // Transition to the new encryption state and process another encrypted packet
   // which should result in the original packet being processed.
@@ -2583,14 +2644,12 @@
   connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
   connection_.SetEncrypter(ENCRYPTION_INITIAL, new TaggingEncrypter(tag));
   EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(2);
-  ProcessDataPacketAtLevel(kDefaultPathId, 2, !kHasStopWaiting,
-                           ENCRYPTION_INITIAL);
+  ProcessDataPacketAtLevel(2, !kHasStopWaiting, ENCRYPTION_INITIAL);
 
   // Finally, process a third packet and note that we do not reprocess the
   // buffered packet.
   EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-  ProcessDataPacketAtLevel(kDefaultPathId, 3, !kHasStopWaiting,
-                           ENCRYPTION_INITIAL);
+  ProcessDataPacketAtLevel(3, !kHasStopWaiting, ENCRYPTION_INITIAL);
 }
 
 TEST_P(QuicConnectionTest, Buffer100NonDecryptablePackets) {
@@ -2608,8 +2667,7 @@
   // Process an encrypted packet which can not yet be decrypted which should
   // result in the packet being buffered.
   for (QuicPacketNumber i = 1; i <= 100; ++i) {
-    ProcessDataPacketAtLevel(kDefaultPathId, i, !kHasStopWaiting,
-                             ENCRYPTION_INITIAL);
+    ProcessDataPacketAtLevel(i, !kHasStopWaiting, ENCRYPTION_INITIAL);
   }
 
   // Transition to the new encryption state and process another encrypted packet
@@ -2618,14 +2676,12 @@
   connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
   connection_.SetEncrypter(ENCRYPTION_INITIAL, new TaggingEncrypter(tag));
   EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(101);
-  ProcessDataPacketAtLevel(kDefaultPathId, 101, !kHasStopWaiting,
-                           ENCRYPTION_INITIAL);
+  ProcessDataPacketAtLevel(101, !kHasStopWaiting, ENCRYPTION_INITIAL);
 
   // Finally, process a third packet and note that we do not reprocess the
   // buffered packet.
   EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-  ProcessDataPacketAtLevel(kDefaultPathId, 102, !kHasStopWaiting,
-                           ENCRYPTION_INITIAL);
+  ProcessDataPacketAtLevel(102, !kHasStopWaiting, ENCRYPTION_INITIAL);
 }
 
 TEST_P(QuicConnectionTest, TestRetransmitOrder) {
@@ -3252,7 +3308,7 @@
   const QuicTime receive_time = send_time + five_ms;
   clock_.AdvanceTime(receive_time - clock_.Now());
   ASSERT_EQ(receive_time, clock_.Now());
-  ProcessPacket(kDefaultPathId, 1);
+  ProcessPacket(1);
 
   // Now move forward to the retransmission time and retransmit the
   // packet, which should move the timeout forward again (but will not
@@ -3497,10 +3553,10 @@
 
 TEST_P(QuicConnectionTest, SendScheduler) {
   // Test that if we send a packet without delay, it is not queued.
-  QuicPacket* packet = ConstructDataPacket(kDefaultPathId, 1, !kHasStopWaiting);
+  QuicPacket* packet = ConstructDataPacket(1, !kHasStopWaiting);
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
-  connection_.SendPacket(ENCRYPTION_NONE, kDefaultPathId, 1, packet,
-                         HAS_RETRANSMITTABLE_DATA, false, false);
+  connection_.SendPacket(ENCRYPTION_NONE, 1, packet, HAS_RETRANSMITTABLE_DATA,
+                         false, false);
   EXPECT_EQ(0u, connection_.NumQueuedPackets());
 }
 
@@ -3508,18 +3564,18 @@
   // Test that the connection does not crash when it fails to send the first
   // packet at which point self_address_ might be uninitialized.
   EXPECT_CALL(visitor_, OnConnectionClosed(_, _, _)).Times(1);
-  QuicPacket* packet = ConstructDataPacket(kDefaultPathId, 1, !kHasStopWaiting);
+  QuicPacket* packet = ConstructDataPacket(1, !kHasStopWaiting);
   writer_->SetShouldWriteFail();
-  connection_.SendPacket(ENCRYPTION_NONE, kDefaultPathId, 1, packet,
-                         HAS_RETRANSMITTABLE_DATA, false, false);
+  connection_.SendPacket(ENCRYPTION_NONE, 1, packet, HAS_RETRANSMITTABLE_DATA,
+                         false, false);
 }
 
 TEST_P(QuicConnectionTest, SendSchedulerEAGAIN) {
-  QuicPacket* packet = ConstructDataPacket(kDefaultPathId, 1, !kHasStopWaiting);
+  QuicPacket* packet = ConstructDataPacket(1, !kHasStopWaiting);
   BlockOnNextWrite();
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 1, _, _)).Times(0);
-  connection_.SendPacket(ENCRYPTION_NONE, kDefaultPathId, 1, packet,
-                         HAS_RETRANSMITTABLE_DATA, false, false);
+  connection_.SendPacket(ENCRYPTION_NONE, 1, packet, HAS_RETRANSMITTABLE_DATA,
+                         false, false);
   EXPECT_EQ(1u, connection_.NumQueuedPackets());
 }
 
@@ -3604,8 +3660,7 @@
   // The same as ProcessPacket(1) except that ENCRYPTION_INITIAL is used
   // instead of ENCRYPTION_NONE.
   EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-  ProcessDataPacketAtLevel(kDefaultPathId, 1, !kHasStopWaiting,
-                           ENCRYPTION_INITIAL);
+  ProcessDataPacketAtLevel(1, !kHasStopWaiting, ENCRYPTION_INITIAL);
 
   // Check if delayed ack timer is running for the expected interval.
   EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
@@ -3613,8 +3668,13 @@
   // Simulate delayed ack alarm firing.
   connection_.GetAckAlarm()->Fire();
   // Check that ack is sent and that delayed ack alarm is reset.
-  EXPECT_EQ(2u, writer_->frame_count());
-  EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  if (GetParam().no_stop_waiting) {
+    EXPECT_EQ(1u, writer_->frame_count());
+    EXPECT_TRUE(writer_->stop_waiting_frames().empty());
+  } else {
+    EXPECT_EQ(2u, writer_->frame_count());
+    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  }
   EXPECT_FALSE(writer_->ack_frames().empty());
   EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
 }
@@ -3642,15 +3702,14 @@
   QuicPacketNumber kFirstDecimatedPacket = 101;
   for (unsigned int i = 0; i < kFirstDecimatedPacket - 1; ++i) {
     EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-    ProcessDataPacketAtLevel(kDefaultPathId, 1 + i, !kHasStopWaiting,
-                             ENCRYPTION_INITIAL);
+    ProcessDataPacketAtLevel(1 + i, !kHasStopWaiting, ENCRYPTION_INITIAL);
   }
   EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
   // The same as ProcessPacket(1) except that ENCRYPTION_INITIAL is used
   // instead of ENCRYPTION_NONE.
   EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-  ProcessDataPacketAtLevel(kDefaultPathId, kFirstDecimatedPacket,
-                           !kHasStopWaiting, ENCRYPTION_INITIAL);
+  ProcessDataPacketAtLevel(kFirstDecimatedPacket, !kHasStopWaiting,
+                           ENCRYPTION_INITIAL);
 
   // Check if delayed ack timer is running for the expected interval.
   EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
@@ -3660,12 +3719,17 @@
   for (int i = 0; i < 9; ++i) {
     EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
     EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-    ProcessDataPacketAtLevel(kDefaultPathId, kFirstDecimatedPacket + 1 + i,
-                             !kHasStopWaiting, ENCRYPTION_INITIAL);
+    ProcessDataPacketAtLevel(kFirstDecimatedPacket + 1 + i, !kHasStopWaiting,
+                             ENCRYPTION_INITIAL);
   }
   // Check that ack is sent and that delayed ack alarm is reset.
-  EXPECT_EQ(2u, writer_->frame_count());
-  EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  if (GetParam().no_stop_waiting) {
+    EXPECT_EQ(1u, writer_->frame_count());
+    EXPECT_TRUE(writer_->stop_waiting_frames().empty());
+  } else {
+    EXPECT_EQ(2u, writer_->frame_count());
+    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  }
   EXPECT_FALSE(writer_->ack_frames().empty());
   EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
 }
@@ -3694,15 +3758,14 @@
   QuicPacketNumber kFirstDecimatedPacket = 101;
   for (unsigned int i = 0; i < kFirstDecimatedPacket - 1; ++i) {
     EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-    ProcessDataPacketAtLevel(kDefaultPathId, 1 + i, !kHasStopWaiting,
-                             ENCRYPTION_INITIAL);
+    ProcessDataPacketAtLevel(1 + i, !kHasStopWaiting, ENCRYPTION_INITIAL);
   }
   EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
   // The same as ProcessPacket(1) except that ENCRYPTION_INITIAL is used
   // instead of ENCRYPTION_NONE.
   EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-  ProcessDataPacketAtLevel(kDefaultPathId, kFirstDecimatedPacket,
-                           !kHasStopWaiting, ENCRYPTION_INITIAL);
+  ProcessDataPacketAtLevel(kFirstDecimatedPacket, !kHasStopWaiting,
+                           ENCRYPTION_INITIAL);
 
   // Check if delayed ack timer is running for the expected interval.
   EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
@@ -3712,12 +3775,17 @@
   for (int i = 0; i < 9; ++i) {
     EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
     EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-    ProcessDataPacketAtLevel(kDefaultPathId, kFirstDecimatedPacket + 1 + i,
-                             !kHasStopWaiting, ENCRYPTION_INITIAL);
+    ProcessDataPacketAtLevel(kFirstDecimatedPacket + 1 + i, !kHasStopWaiting,
+                             ENCRYPTION_INITIAL);
   }
   // Check that ack is sent and that delayed ack alarm is reset.
-  EXPECT_EQ(2u, writer_->frame_count());
-  EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  if (GetParam().no_stop_waiting) {
+    EXPECT_EQ(1u, writer_->frame_count());
+    EXPECT_TRUE(writer_->stop_waiting_frames().empty());
+  } else {
+    EXPECT_EQ(2u, writer_->frame_count());
+    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  }
   EXPECT_FALSE(writer_->ack_frames().empty());
   EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
 }
@@ -3746,15 +3814,14 @@
   QuicPacketNumber kFirstDecimatedPacket = 101;
   for (unsigned int i = 0; i < kFirstDecimatedPacket - 1; ++i) {
     EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-    ProcessDataPacketAtLevel(kDefaultPathId, 1 + i, !kHasStopWaiting,
-                             ENCRYPTION_INITIAL);
+    ProcessDataPacketAtLevel(1 + i, !kHasStopWaiting, ENCRYPTION_INITIAL);
   }
   EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
   // The same as ProcessPacket(1) except that ENCRYPTION_INITIAL is used
   // instead of ENCRYPTION_NONE.
   EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-  ProcessDataPacketAtLevel(kDefaultPathId, kFirstDecimatedPacket,
-                           !kHasStopWaiting, ENCRYPTION_INITIAL);
+  ProcessDataPacketAtLevel(kFirstDecimatedPacket, !kHasStopWaiting,
+                           ENCRYPTION_INITIAL);
 
   // Check if delayed ack timer is running for the expected interval.
   EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
@@ -3762,8 +3829,8 @@
 
   // Process packet 10 first and ensure the alarm is one eighth min_rtt.
   EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-  ProcessDataPacketAtLevel(kDefaultPathId, kFirstDecimatedPacket + 9,
-                           !kHasStopWaiting, ENCRYPTION_INITIAL);
+  ProcessDataPacketAtLevel(kFirstDecimatedPacket + 9, !kHasStopWaiting,
+                           ENCRYPTION_INITIAL);
   ack_time = clock_.ApproximateNow() + QuicTime::Delta::FromMilliseconds(5);
   EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
   EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
@@ -3772,12 +3839,17 @@
   for (int i = 0; i < 8; ++i) {
     EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
     EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-    ProcessDataPacketAtLevel(kDefaultPathId, kFirstDecimatedPacket + 1 + i,
-                             !kHasStopWaiting, ENCRYPTION_INITIAL);
+    ProcessDataPacketAtLevel(kFirstDecimatedPacket + 1 + i, !kHasStopWaiting,
+                             ENCRYPTION_INITIAL);
   }
   // Check that ack is sent and that delayed ack alarm is reset.
-  EXPECT_EQ(2u, writer_->frame_count());
-  EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  if (GetParam().no_stop_waiting) {
+    EXPECT_EQ(1u, writer_->frame_count());
+    EXPECT_TRUE(writer_->stop_waiting_frames().empty());
+  } else {
+    EXPECT_EQ(2u, writer_->frame_count());
+    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  }
   EXPECT_FALSE(writer_->ack_frames().empty());
   EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
 }
@@ -3806,15 +3878,14 @@
   QuicPacketNumber kFirstDecimatedPacket = 101;
   for (unsigned int i = 0; i < kFirstDecimatedPacket - 1; ++i) {
     EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-    ProcessDataPacketAtLevel(kDefaultPathId, 1 + i, !kHasStopWaiting,
-                             ENCRYPTION_INITIAL);
+    ProcessDataPacketAtLevel(1 + i, !kHasStopWaiting, ENCRYPTION_INITIAL);
   }
   EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
   // The same as ProcessPacket(1) except that ENCRYPTION_INITIAL is used
   // instead of ENCRYPTION_NONE.
   EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-  ProcessDataPacketAtLevel(kDefaultPathId, kFirstDecimatedPacket,
-                           !kHasStopWaiting, ENCRYPTION_INITIAL);
+  ProcessDataPacketAtLevel(kFirstDecimatedPacket, !kHasStopWaiting,
+                           ENCRYPTION_INITIAL);
 
   // Check if delayed ack timer is running for the expected interval.
   EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
@@ -3822,8 +3893,8 @@
 
   // Process packet 10 first and ensure the alarm is one eighth min_rtt.
   EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-  ProcessDataPacketAtLevel(kDefaultPathId, kFirstDecimatedPacket + 19,
-                           !kHasStopWaiting, ENCRYPTION_INITIAL);
+  ProcessDataPacketAtLevel(kFirstDecimatedPacket + 19, !kHasStopWaiting,
+                           ENCRYPTION_INITIAL);
   ack_time = clock_.ApproximateNow() + QuicTime::Delta::FromMilliseconds(5);
   EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
   EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
@@ -3832,12 +3903,17 @@
   for (int i = 0; i < 8; ++i) {
     EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
     EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-    ProcessDataPacketAtLevel(kDefaultPathId, kFirstDecimatedPacket + 1 + i,
-                             !kHasStopWaiting, ENCRYPTION_INITIAL);
+    ProcessDataPacketAtLevel(kFirstDecimatedPacket + 1 + i, !kHasStopWaiting,
+                             ENCRYPTION_INITIAL);
   }
   // Check that ack is sent and that delayed ack alarm is reset.
-  EXPECT_EQ(2u, writer_->frame_count());
-  EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  if (GetParam().no_stop_waiting) {
+    EXPECT_EQ(1u, writer_->frame_count());
+    EXPECT_TRUE(writer_->stop_waiting_frames().empty());
+  } else {
+    EXPECT_EQ(2u, writer_->frame_count());
+    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  }
   EXPECT_FALSE(writer_->ack_frames().empty());
   EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
 
@@ -3845,11 +3921,16 @@
   // because it fills a hole.
   EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
   EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-  ProcessDataPacketAtLevel(kDefaultPathId, kFirstDecimatedPacket + 10,
-                           !kHasStopWaiting, ENCRYPTION_INITIAL);
+  ProcessDataPacketAtLevel(kFirstDecimatedPacket + 10, !kHasStopWaiting,
+                           ENCRYPTION_INITIAL);
   // Check that ack is sent and that delayed ack alarm is reset.
-  EXPECT_EQ(2u, writer_->frame_count());
-  EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  if (GetParam().no_stop_waiting) {
+    EXPECT_EQ(1u, writer_->frame_count());
+    EXPECT_TRUE(writer_->stop_waiting_frames().empty());
+  } else {
+    EXPECT_EQ(2u, writer_->frame_count());
+    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  }
   EXPECT_FALSE(writer_->ack_frames().empty());
   EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
 }
@@ -3879,15 +3960,14 @@
   QuicPacketNumber kFirstDecimatedPacket = 101;
   for (unsigned int i = 0; i < kFirstDecimatedPacket - 1; ++i) {
     EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-    ProcessDataPacketAtLevel(kDefaultPathId, 1 + i, !kHasStopWaiting,
-                             ENCRYPTION_INITIAL);
+    ProcessDataPacketAtLevel(1 + i, !kHasStopWaiting, ENCRYPTION_INITIAL);
   }
   EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
   // The same as ProcessPacket(1) except that ENCRYPTION_INITIAL is used
   // instead of ENCRYPTION_NONE.
   EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-  ProcessDataPacketAtLevel(kDefaultPathId, kFirstDecimatedPacket,
-                           !kHasStopWaiting, ENCRYPTION_INITIAL);
+  ProcessDataPacketAtLevel(kFirstDecimatedPacket, !kHasStopWaiting,
+                           ENCRYPTION_INITIAL);
 
   // Check if delayed ack timer is running for the expected interval.
   EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
@@ -3895,8 +3975,8 @@
 
   // Process packet 10 first and ensure the alarm is one eighth min_rtt.
   EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-  ProcessDataPacketAtLevel(kDefaultPathId, kFirstDecimatedPacket + 9,
-                           !kHasStopWaiting, ENCRYPTION_INITIAL);
+  ProcessDataPacketAtLevel(kFirstDecimatedPacket + 9, !kHasStopWaiting,
+                           ENCRYPTION_INITIAL);
   ack_time = clock_.ApproximateNow() + QuicTime::Delta::FromMilliseconds(5);
   EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
   EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
@@ -3905,12 +3985,17 @@
   for (int i = 0; i < 8; ++i) {
     EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
     EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-    ProcessDataPacketAtLevel(kDefaultPathId, kFirstDecimatedPacket + 1 + i,
-                             !kHasStopWaiting, ENCRYPTION_INITIAL);
+    ProcessDataPacketAtLevel(kFirstDecimatedPacket + 1 + i, !kHasStopWaiting,
+                             ENCRYPTION_INITIAL);
   }
   // Check that ack is sent and that delayed ack alarm is reset.
-  EXPECT_EQ(2u, writer_->frame_count());
-  EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  if (GetParam().no_stop_waiting) {
+    EXPECT_EQ(1u, writer_->frame_count());
+    EXPECT_TRUE(writer_->stop_waiting_frames().empty());
+  } else {
+    EXPECT_EQ(2u, writer_->frame_count());
+    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  }
   EXPECT_FALSE(writer_->ack_frames().empty());
   EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
 }
@@ -3941,15 +4026,14 @@
   QuicPacketNumber kFirstDecimatedPacket = 101;
   for (unsigned int i = 0; i < kFirstDecimatedPacket - 1; ++i) {
     EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-    ProcessDataPacketAtLevel(kDefaultPathId, 1 + i, !kHasStopWaiting,
-                             ENCRYPTION_INITIAL);
+    ProcessDataPacketAtLevel(1 + i, !kHasStopWaiting, ENCRYPTION_INITIAL);
   }
   EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
   // The same as ProcessPacket(1) except that ENCRYPTION_INITIAL is used
   // instead of ENCRYPTION_NONE.
   EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-  ProcessDataPacketAtLevel(kDefaultPathId, kFirstDecimatedPacket,
-                           !kHasStopWaiting, ENCRYPTION_INITIAL);
+  ProcessDataPacketAtLevel(kFirstDecimatedPacket, !kHasStopWaiting,
+                           ENCRYPTION_INITIAL);
 
   // Check if delayed ack timer is running for the expected interval.
   EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
@@ -3957,8 +4041,8 @@
 
   // Process packet 10 first and ensure the alarm is one eighth min_rtt.
   EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-  ProcessDataPacketAtLevel(kDefaultPathId, kFirstDecimatedPacket + 19,
-                           !kHasStopWaiting, ENCRYPTION_INITIAL);
+  ProcessDataPacketAtLevel(kFirstDecimatedPacket + 19, !kHasStopWaiting,
+                           ENCRYPTION_INITIAL);
   ack_time = clock_.ApproximateNow() + QuicTime::Delta::FromMilliseconds(5);
   EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
   EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
@@ -3967,12 +4051,17 @@
   for (int i = 0; i < 8; ++i) {
     EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
     EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-    ProcessDataPacketAtLevel(kDefaultPathId, kFirstDecimatedPacket + 1 + i,
-                             !kHasStopWaiting, ENCRYPTION_INITIAL);
+    ProcessDataPacketAtLevel(kFirstDecimatedPacket + 1 + i, !kHasStopWaiting,
+                             ENCRYPTION_INITIAL);
   }
   // Check that ack is sent and that delayed ack alarm is reset.
-  EXPECT_EQ(2u, writer_->frame_count());
-  EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  if (GetParam().no_stop_waiting) {
+    EXPECT_EQ(1u, writer_->frame_count());
+    EXPECT_TRUE(writer_->stop_waiting_frames().empty());
+  } else {
+    EXPECT_EQ(2u, writer_->frame_count());
+    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  }
   EXPECT_FALSE(writer_->ack_frames().empty());
   EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
 
@@ -3980,18 +4069,23 @@
   // because it fills a hole.
   EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
   EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-  ProcessDataPacketAtLevel(kDefaultPathId, kFirstDecimatedPacket + 10,
-                           !kHasStopWaiting, ENCRYPTION_INITIAL);
+  ProcessDataPacketAtLevel(kFirstDecimatedPacket + 10, !kHasStopWaiting,
+                           ENCRYPTION_INITIAL);
   // Check that ack is sent and that delayed ack alarm is reset.
-  EXPECT_EQ(2u, writer_->frame_count());
-  EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  if (GetParam().no_stop_waiting) {
+    EXPECT_EQ(1u, writer_->frame_count());
+    EXPECT_TRUE(writer_->stop_waiting_frames().empty());
+  } else {
+    EXPECT_EQ(2u, writer_->frame_count());
+    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  }
   EXPECT_FALSE(writer_->ack_frames().empty());
   EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
 }
 
 TEST_P(QuicConnectionTest, SendDelayedAckOnHandshakeConfirmed) {
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  ProcessPacket(kDefaultPathId, 1);
+  ProcessPacket(1);
   // Check that ack is sent and that delayed ack alarm is set.
   EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
   QuicTime ack_time = clock_.ApproximateNow() + DefaultDelayedAckTime();
@@ -4012,11 +4106,16 @@
 
 TEST_P(QuicConnectionTest, SendDelayedAckOnSecondPacket) {
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  ProcessPacket(kDefaultPathId, 1);
-  ProcessPacket(kDefaultPathId, 2);
+  ProcessPacket(1);
+  ProcessPacket(2);
   // Check that ack is sent and that delayed ack alarm is reset.
-  EXPECT_EQ(2u, writer_->frame_count());
-  EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  if (GetParam().no_stop_waiting) {
+    EXPECT_EQ(1u, writer_->frame_count());
+    EXPECT_TRUE(writer_->stop_waiting_frames().empty());
+  } else {
+    EXPECT_EQ(2u, writer_->frame_count());
+    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  }
   EXPECT_FALSE(writer_->ack_frames().empty());
   EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
 }
@@ -4024,56 +4123,66 @@
 TEST_P(QuicConnectionTest, NoAckOnOldNacks) {
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
   // Drop one packet, triggering a sequence of acks.
-  ProcessPacket(kDefaultPathId, 2);
-  size_t frames_per_ack = 2;
+  ProcessPacket(2);
+  size_t frames_per_ack = GetParam().no_stop_waiting ? 1 : 2;
   EXPECT_EQ(frames_per_ack, writer_->frame_count());
   EXPECT_FALSE(writer_->ack_frames().empty());
   writer_->Reset();
-  ProcessPacket(kDefaultPathId, 3);
+  ProcessPacket(3);
   EXPECT_EQ(frames_per_ack, writer_->frame_count());
   EXPECT_FALSE(writer_->ack_frames().empty());
   writer_->Reset();
-  ProcessPacket(kDefaultPathId, 4);
+  ProcessPacket(4);
   EXPECT_EQ(frames_per_ack, writer_->frame_count());
   EXPECT_FALSE(writer_->ack_frames().empty());
   writer_->Reset();
-  ProcessPacket(kDefaultPathId, 5);
+  ProcessPacket(5);
   EXPECT_EQ(frames_per_ack, writer_->frame_count());
   EXPECT_FALSE(writer_->ack_frames().empty());
   writer_->Reset();
   // Now only set the timer on the 6th packet, instead of sending another ack.
-  ProcessPacket(kDefaultPathId, 6);
+  ProcessPacket(6);
   EXPECT_EQ(0u, writer_->frame_count());
   EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
 }
 
 TEST_P(QuicConnectionTest, SendDelayedAckOnOutgoingPacket) {
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  ProcessPacket(kDefaultPathId, 1);
+  ProcessPacket(1);
   connection_.SendStreamDataWithString(kClientDataStreamId1, "foo", 0, !kFin,
                                        nullptr);
   // Check that ack is bundled with outgoing data and that delayed ack
   // alarm is reset.
-  EXPECT_EQ(3u, writer_->frame_count());
-  EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  if (GetParam().no_stop_waiting) {
+    EXPECT_EQ(2u, writer_->frame_count());
+    EXPECT_TRUE(writer_->stop_waiting_frames().empty());
+  } else {
+    EXPECT_EQ(3u, writer_->frame_count());
+    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  }
   EXPECT_FALSE(writer_->ack_frames().empty());
   EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
 }
 
 TEST_P(QuicConnectionTest, SendDelayedAckOnOutgoingCryptoPacket) {
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  ProcessPacket(kDefaultPathId, 1);
+  ProcessPacket(1);
   connection_.SendStreamDataWithString(kCryptoStreamId, "foo", 0, !kFin,
                                        nullptr);
   // Check that ack is bundled with outgoing crypto data.
-  EXPECT_EQ(3u, writer_->frame_count());
-  EXPECT_FALSE(writer_->ack_frames().empty());
+  if (GetParam().no_stop_waiting) {
+    EXPECT_EQ(2u, writer_->frame_count());
+    EXPECT_TRUE(writer_->stop_waiting_frames().empty());
+  } else {
+    EXPECT_EQ(3u, writer_->frame_count());
+    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  }
   EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
 }
 
 TEST_P(QuicConnectionTest, BlockAndBufferOnFirstCHLOPacketOfTwo) {
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  ProcessPacket(kDefaultPathId, 1);
+  ProcessPacket(1);
   BlockOnNextWrite();
   writer_->set_is_write_blocked_data_buffered(true);
   connection_.SendStreamDataWithString(kCryptoStreamId, "foo", 0, !kFin,
@@ -4095,10 +4204,15 @@
   // Process a packet from the crypto stream, which is frame1_'s default.
   // Receiving the CHLO as packet 2 first will cause the connection to
   // immediately send an ack, due to the packet gap.
-  ProcessPacket(kDefaultPathId, 2);
+  ProcessPacket(2);
   // Check that ack is sent and that delayed ack alarm is reset.
-  EXPECT_EQ(3u, writer_->frame_count());
-  EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  if (GetParam().no_stop_waiting) {
+    EXPECT_EQ(2u, writer_->frame_count());
+    EXPECT_TRUE(writer_->stop_waiting_frames().empty());
+  } else {
+    EXPECT_EQ(3u, writer_->frame_count());
+    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  }
   EXPECT_EQ(1u, writer_->stream_frames().size());
   EXPECT_FALSE(writer_->ack_frames().empty());
   EXPECT_EQ(2u, writer_->ack_frames().front().largest_observed);
@@ -4112,16 +4226,21 @@
   // Process two packets from the crypto stream, which is frame1_'s default,
   // simulating a 2 packet reject.
   {
-    ProcessPacket(kDefaultPathId, 1);
+    ProcessPacket(1);
     // Send the new CHLO when the REJ is processed.
     EXPECT_CALL(visitor_, OnStreamFrame(_))
         .WillOnce(IgnoreResult(InvokeWithoutArgs(
             &connection_, &TestConnection::SendCryptoStreamData)));
-    ProcessDataPacket(kDefaultPathId, 2);
+    ProcessDataPacket(2);
   }
   // Check that ack is sent and that delayed ack alarm is reset.
-  EXPECT_EQ(3u, writer_->frame_count());
-  EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  if (GetParam().no_stop_waiting) {
+    EXPECT_EQ(2u, writer_->frame_count());
+    EXPECT_TRUE(writer_->stop_waiting_frames().empty());
+  } else {
+    EXPECT_EQ(3u, writer_->frame_count());
+    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  }
   EXPECT_EQ(1u, writer_->stream_frames().size());
   EXPECT_FALSE(writer_->ack_frames().empty());
   EXPECT_EQ(2u, writer_->ack_frames().front().largest_observed);
@@ -4171,8 +4290,13 @@
 
   // Check that ack is bundled with outgoing data and the delayed ack
   // alarm is reset.
-  EXPECT_EQ(3u, writer_->frame_count());
-  EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  if (GetParam().no_stop_waiting) {
+    EXPECT_EQ(2u, writer_->frame_count());
+    EXPECT_TRUE(writer_->stop_waiting_frames().empty());
+  } else {
+    EXPECT_EQ(3u, writer_->frame_count());
+    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
+  }
   EXPECT_FALSE(writer_->ack_frames().empty());
   EXPECT_EQ(3u, writer_->ack_frames().front().largest_observed);
   EXPECT_EQ(1u, writer_->stream_frames().size());
@@ -4181,11 +4305,11 @@
 
 TEST_P(QuicConnectionTest, NoAckSentForClose) {
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  ProcessPacket(kDefaultPathId, 1);
+  ProcessPacket(1);
   EXPECT_CALL(visitor_, OnConnectionClosed(QUIC_PEER_GOING_AWAY, _,
                                            ConnectionCloseSource::FROM_PEER));
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
-  ProcessClosePacket(kDefaultPathId, 2);
+  ProcessClosePacket(2);
 }
 
 TEST_P(QuicConnectionTest, SendWhenDisconnected) {
@@ -4196,10 +4320,10 @@
                               ConnectionCloseBehavior::SILENT_CLOSE);
   EXPECT_FALSE(connection_.connected());
   EXPECT_FALSE(connection_.CanWriteStreamData());
-  QuicPacket* packet = ConstructDataPacket(kDefaultPathId, 1, !kHasStopWaiting);
+  QuicPacket* packet = ConstructDataPacket(1, !kHasStopWaiting);
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 1, _, _)).Times(0);
-  connection_.SendPacket(ENCRYPTION_NONE, kDefaultPathId, 1, packet,
-                         HAS_RETRANSMITTABLE_DATA, false, false);
+  connection_.SendPacket(ENCRYPTION_NONE, 1, packet, HAS_RETRANSMITTABLE_DATA,
+                         false, false);
 }
 
 TEST_P(QuicConnectionTest, PublicReset) {
@@ -4273,7 +4397,6 @@
   QuicPacketHeader header;
   header.public_header.connection_id = connection_id_;
   header.public_header.version_flag = true;
-  header.path_id = kDefaultPathId;
   header.packet_number = 12;
 
   QuicFrames frames;
@@ -4388,7 +4511,6 @@
   // NEGOTIATED_VERSION state and tell the packet creator to StopSendingVersion.
   QuicPacketHeader header;
   header.public_header.connection_id = connection_id_;
-  header.path_id = kDefaultPathId;
   header.packet_number = 12;
   header.public_header.version_flag = false;
   QuicFrames frames;
@@ -5020,7 +5142,7 @@
 TEST_P(QuicConnectionTest, DonotForceSendingAckOnPacketTooLarge) {
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
   // Send an ack by simulating delayed ack alarm firing.
-  ProcessPacket(kDefaultPathId, 1);
+  ProcessPacket(1);
   QuicAlarm* ack_alarm = QuicConnectionPeer::GetAckAlarm(&connection_);
   EXPECT_TRUE(ack_alarm->IsSet());
   connection_.GetAckAlarm()->Fire();
diff --git a/net/quic/core/quic_crypto_client_stream_test.cc b/net/quic/core/quic_crypto_client_stream_test.cc
index 571ca249..497e82a 100644
--- a/net/quic/core/quic_crypto_client_stream_test.cc
+++ b/net/quic/core/quic_crypto_client_stream_test.cc
@@ -230,10 +230,8 @@
       reinterpret_cast<char*>(scfg), arraysize(scfg));
 
   QuicStreamSequencer* sequencer = QuicStreamPeer::sequencer(stream());
-  EXPECT_NE(
-      FLAGS_quic_reloadable_flag_quic_release_crypto_stream_buffer &&
-          FLAGS_quic_reloadable_flag_quic_reduce_sequencer_buffer_memory_life_time,  // NOLINT
-      QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer));
+  EXPECT_NE(FLAGS_quic_reloadable_flag_quic_release_crypto_stream_buffer,
+            QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer));
 }
 
 TEST_F(QuicCryptoClientStreamTest, ServerConfigUpdateWithCert) {
diff --git a/net/quic/core/quic_flags_list.h b/net/quic/core/quic_flags_list.h
index 8d284003..4128de5 100644
--- a/net/quic/core/quic_flags_list.h
+++ b/net/quic/core/quic_flags_list.h
@@ -76,29 +76,15 @@
           FLAGS_quic_reloadable_flag_quic_enable_server_push_by_default,
           true)
 
-// Allow large send deltas to be used as RTT samples.
-QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_allow_large_send_deltas, true)
-
 // If true, release QuicCryptoStream\'s read buffer when stream are less
 // frequently used.
 QUIC_FLAG(bool,
           FLAGS_quic_reloadable_flag_quic_release_crypto_stream_buffer,
           true)
 
-// Use a more conservative backoff of 2x instead of 1.5x for handshake
-// retransmissions, as well as a larger minimum.
-QUIC_FLAG(bool,
-          FLAGS_quic_reloadable_flag_quic_conservative_handshake_retransmits,
-          false)
-
 // If true, buffer packets while parsing public headers instead of parsing down
 // if CHLO is already buffered.
-QUIC_FLAG(bool,
-          FLAGS_quic_reloadable_flag_quic_buffer_packets_after_chlo,
-          false)
-
-// If true, enable the Lazy FACK style loss detection in QUIC.
-QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_enable_lazy_fack, true)
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_buffer_packets_after_chlo, true)
 
 // If true, do not override a connection in global map if exists. Only create
 // QUIC session if it is successfully inserted to the global map. Toss the
@@ -122,13 +108,6 @@
           FLAGS_quic_reloadable_flag_quic_limit_uncompressed_headers,
           false)
 
-// If true, release headers stream\'s sequencer buffer when there is no active
-// stream.
-QUIC_FLAG(
-    bool,
-    FLAGS_quic_reloadable_flag_quic_headers_stream_release_sequencer_buffer,
-    true)
-
 // Enable QUIC force HOL blocking experiment.
 QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_enable_force_hol_blocking, true)
 
@@ -136,10 +115,6 @@
 // allow CHLO packets to be buffered until next iteration of the event loop.
 QUIC_FLAG(bool, FLAGS_quic_allow_chlo_buffering, true)
 
-// Add a new client connection options field to QuicOptions which is only used
-// to configure client side features, such as congestion control.
-QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_client_connection_options, true)
-
 // If true, fix some casts that were causing off-by-one errors in QUIC's cubic
 // "convex" increases.
 QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_fix_cubic_convex_mode, false)
@@ -153,17 +128,6 @@
           FLAGS_quic_reloadable_flag_quic_fix_cubic_bytes_quantization,
           false)
 
-// If true, QUIC cubic code will use the event time when adjusting CWND after an
-// ACK instead of the clock\'s current approximate time.
-QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_use_event_time, true)
-
-// If true, lazy allocate and early release memeory used in
-// QuicStreamSequencerBuffer to buffer incoming data.
-QUIC_FLAG(
-    bool,
-    FLAGS_quic_reloadable_flag_quic_reduce_sequencer_buffer_memory_life_time,
-    true)
-
 // If true, Makes GFE respect the connection options for initial flow control
 // window larger than 32 KB.
 QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_large_ifw_options, true)
@@ -177,9 +141,6 @@
 // If true, disables QUIC v34.
 QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_disable_version_34, true)
 
-// Allow quic to properly support proxying 100 Continue responses.
-QUIC_FLAG(bool, FLAGS_quic_restart_flag_quic_supports_100_continue, false)
-
 // If true, enable quic version 38
 QUIC_FLAG(bool, FLAGS_quic_enable_version_38, false)
 
@@ -198,3 +159,14 @@
 QUIC_FLAG(bool,
           FLAGS_quic_reloadable_flag_quic_always_enable_bidi_streaming,
           false)
+
+// If true, allows the 1RTT and 2RTT connection options to reduce the time
+// in BBR STARTUP to 1 or 2 RTTs with no bandwidth increase from 3.
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_allow_2_rtt_bbr_startup, false)
+
+// If true, do not send or process stop waiting frames in QUIC if the NSTP
+// connection option is provided.
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_no_stop_waiting_frames, false)
+
+// Allows one self address change.
+QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_allow_one_address_change, false)
diff --git a/net/quic/core/quic_framer.cc b/net/quic/core/quic_framer.cc
index e32db271..0084511 100644
--- a/net/quic/core/quic_framer.cc
+++ b/net/quic/core/quic_framer.cc
@@ -703,11 +703,6 @@
                   << QuicTagToString(tag) << "'";
   }
 
-  if (header.public_header.multipath_flag &&
-      !writer->WriteUInt8(header.path_id)) {
-    return false;
-  }
-
   if (header.public_header.nonce != nullptr &&
       !writer->WriteBytes(header.public_header.nonce,
                           kDiversificationNonceSize)) {
@@ -924,13 +919,6 @@
 
 bool QuicFramer::ProcessUnauthenticatedHeader(QuicDataReader* encrypted_reader,
                                               QuicPacketHeader* header) {
-  header->path_id = kDefaultPathId;
-  if (header->public_header.multipath_flag &&
-      !ProcessPathId(encrypted_reader, &header->path_id)) {
-    set_detailed_error("Unable to read path id.");
-    return RaiseError(QUIC_INVALID_PACKET_HEADER);
-  }
-
   QuicPacketNumber base_packet_number = largest_packet_number_;
 
   if (!ProcessPacketSequenceNumber(
@@ -953,14 +941,6 @@
   return true;
 }
 
-bool QuicFramer::ProcessPathId(QuicDataReader* reader, QuicPathId* path_id) {
-  if (!reader->ReadBytes(path_id, 1)) {
-    return false;
-  }
-
-  return true;
-}
-
 bool QuicFramer::ProcessPacketSequenceNumber(
     QuicDataReader* reader,
     QuicPacketNumberLength packet_number_length,
@@ -1525,7 +1505,6 @@
 }
 
 size_t QuicFramer::EncryptInPlace(EncryptionLevel level,
-                                  QuicPathId path_id,
                                   QuicPacketNumber packet_number,
                                   size_t ad_len,
                                   size_t total_len,
diff --git a/net/quic/core/quic_framer.h b/net/quic/core/quic_framer.h
index 23d3c3ce..004643f 100644
--- a/net/quic/core/quic_framer.h
+++ b/net/quic/core/quic_framer.h
@@ -296,7 +296,6 @@
   // data. |total_len| is the length of the associated data plus plaintext.
   // |buffer_len| is the full length of the allocated buffer.
   size_t EncryptInPlace(EncryptionLevel level,
-                        QuicPathId path_id,
                         QuicPacketNumber packet_number,
                         size_t ad_len,
                         size_t total_len,
@@ -370,7 +369,6 @@
   bool ProcessUnauthenticatedHeader(QuicDataReader* encrypted_reader,
                                     QuicPacketHeader* header);
 
-  bool ProcessPathId(QuicDataReader* reader, QuicPathId* path_id);
   bool ProcessPacketSequenceNumber(QuicDataReader* reader,
                                    QuicPacketNumberLength packet_number_length,
                                    QuicPacketNumber base_packet_number,
diff --git a/net/quic/core/quic_framer_test.cc b/net/quic/core/quic_framer_test.cc
index 01a201d..26ece5bf 100644
--- a/net/quic/core/quic_framer_test.cc
+++ b/net/quic/core/quic_framer_test.cc
@@ -67,37 +67,29 @@
 
 // Index into the packet number offset in the header.
 size_t GetPacketNumberOffset(QuicConnectionIdLength connection_id_length,
-                             bool include_version,
-                             bool include_path_id) {
+                             bool include_version) {
   return kConnectionIdOffset + connection_id_length +
-         (include_version ? kQuicVersionSize : 0) +
-         (include_path_id ? kQuicPathIdSize : 0);
+         (include_version ? kQuicVersionSize : 0);
 }
 
-size_t GetPacketNumberOffset(bool include_version, bool include_path_id) {
-  return GetPacketNumberOffset(PACKET_8BYTE_CONNECTION_ID, include_version,
-                               include_path_id);
+size_t GetPacketNumberOffset(bool include_version) {
+  return GetPacketNumberOffset(PACKET_8BYTE_CONNECTION_ID, include_version);
 }
 
 // Index into the private flags offset in the data packet header.
 size_t GetPrivateFlagsOffset(QuicConnectionIdLength connection_id_length,
-                             bool include_version,
-                             bool include_path_id) {
-  return GetPacketNumberOffset(connection_id_length, include_version,
-                               include_path_id) +
+                             bool include_version) {
+  return GetPacketNumberOffset(connection_id_length, include_version) +
          PACKET_6BYTE_PACKET_NUMBER;
 }
 
-size_t GetPrivateFlagsOffset(bool include_version, bool include_path_id) {
-  return GetPrivateFlagsOffset(PACKET_8BYTE_CONNECTION_ID, include_version,
-                               include_path_id);
+size_t GetPrivateFlagsOffset(bool include_version) {
+  return GetPrivateFlagsOffset(PACKET_8BYTE_CONNECTION_ID, include_version);
 }
 
 size_t GetPrivateFlagsOffset(bool include_version,
-                             bool include_path_id,
                              QuicPacketNumberLength packet_number_length) {
-  return GetPacketNumberOffset(PACKET_8BYTE_CONNECTION_ID, include_version,
-                               include_path_id) +
+  return GetPacketNumberOffset(PACKET_8BYTE_CONNECTION_ID, include_version) +
          packet_number_length;
 }
 
@@ -355,9 +347,7 @@
     return static_cast<unsigned char>('0' + (version_ / 10) % 10);
   }
 
-  bool CheckEncryption(QuicPathId path_id,
-                       QuicPacketNumber packet_number,
-                       QuicPacket* packet) {
+  bool CheckEncryption(QuicPacketNumber packet_number, QuicPacket* packet) {
     EXPECT_EQ(version_, encrypter_->version_);
     if (packet_number != encrypter_->packet_number_) {
       QUIC_LOG(ERROR) << "Encrypted incorrect packet number.  expected "
@@ -663,7 +653,7 @@
     string expected_error;
     if (i < kConnectionIdOffset) {
       expected_error = "Unable to read public flags.";
-    } else if (i < GetPacketNumberOffset(!kIncludeVersion, !kIncludePathId)) {
+    } else if (i < GetPacketNumberOffset(!kIncludeVersion)) {
       expected_error = "Unable to read ConnectionId.";
     } else {
       expected_error = "Unable to read packet number.";
@@ -706,7 +696,7 @@
     if (i < kConnectionIdOffset) {
       expected_error = "Unable to read public flags.";
     } else if (i < GetPacketNumberOffset(PACKET_0BYTE_CONNECTION_ID,
-                                         !kIncludeVersion, !kIncludePathId)) {
+                                         !kIncludeVersion)) {
       expected_error = "Unable to read ConnectionId.";
     } else {
       expected_error = "Unable to read packet number.";
@@ -751,7 +741,7 @@
       expected_error = "Unable to read public flags.";
     } else if (i < kVersionOffset) {
       expected_error = "Unable to read ConnectionId.";
-    } else if (i < GetPacketNumberOffset(kIncludeVersion, !kIncludePathId)) {
+    } else if (i < GetPacketNumberOffset(kIncludeVersion)) {
       expected_error = "Unable to read protocol version.";
     } else {
       expected_error = "Unable to read packet number.";
@@ -793,7 +783,7 @@
     string expected_error;
     if (i < kConnectionIdOffset) {
       expected_error = "Unable to read public flags.";
-    } else if (i < GetPacketNumberOffset(!kIncludeVersion, !kIncludePathId)) {
+    } else if (i < GetPacketNumberOffset(!kIncludeVersion)) {
       expected_error = "Unable to read ConnectionId.";
     } else {
       expected_error = "Unable to read packet number.";
@@ -837,7 +827,7 @@
     string expected_error;
     if (i < kConnectionIdOffset) {
       expected_error = "Unable to read public flags.";
-    } else if (i < GetPacketNumberOffset(!kIncludeVersion, !kIncludePathId)) {
+    } else if (i < GetPacketNumberOffset(!kIncludeVersion)) {
       expected_error = "Unable to read ConnectionId.";
     } else {
       expected_error = "Unable to read packet number.";
@@ -881,7 +871,7 @@
     string expected_error;
     if (i < kConnectionIdOffset) {
       expected_error = "Unable to read public flags.";
-    } else if (i < GetPacketNumberOffset(!kIncludeVersion, !kIncludePathId)) {
+    } else if (i < GetPacketNumberOffset(!kIncludeVersion)) {
       expected_error = "Unable to read ConnectionId.";
     } else {
       expected_error = "Unable to read packet number.";
@@ -3359,7 +3349,7 @@
       ENCRYPTION_NONE, packet_number, *raw, buffer, kMaxPacketSize);
 
   ASSERT_NE(0u, encrypted_length);
-  EXPECT_TRUE(CheckEncryption(kDefaultPathId, packet_number, raw.get()));
+  EXPECT_TRUE(CheckEncryption(packet_number, raw.get()));
 }
 
 TEST_P(QuicFramerTest, EncryptPacketWithVersionFlag) {
@@ -3394,7 +3384,7 @@
       ENCRYPTION_NONE, packet_number, *raw, buffer, kMaxPacketSize);
 
   ASSERT_NE(0u, encrypted_length);
-  EXPECT_TRUE(CheckEncryption(kDefaultPathId, packet_number, raw.get()));
+  EXPECT_TRUE(CheckEncryption(packet_number, raw.get()));
 }
 
 TEST_P(QuicFramerTest, AckTruncationLargePacket) {
@@ -3579,7 +3569,7 @@
   QuicVersionVector versions;
   versions.push_back(framer_.version());
   std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
-      42, false, false, false, kDefaultPathId, kTestQuicStreamId, kTestString,
+      42, false, false, false, kTestQuicStreamId, kTestString,
       PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, &versions));
 
   MockFramerVisitor visitor;
@@ -3615,7 +3605,7 @@
   QuicVersionVector versions;
   versions.push_back(framer_.version());
   std::unique_ptr<QuicEncryptedPacket> packet(ConstructMisFramedEncryptedPacket(
-      42, false, false, kDefaultPathId, kTestQuicStreamId, kTestString,
+      42, false, false, kTestQuicStreamId, kTestString,
       PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, &versions,
       Perspective::IS_CLIENT));
 
diff --git a/net/quic/core/quic_headers_stream.cc b/net/quic/core/quic_headers_stream.cc
index 9f03573..00c769c 100644
--- a/net/quic/core/quic_headers_stream.cc
+++ b/net/quic/core/quic_headers_stream.cc
@@ -38,8 +38,7 @@
 }
 
 void QuicHeadersStream::MaybeReleaseSequencerBuffer() {
-  if (FLAGS_quic_reloadable_flag_quic_headers_stream_release_sequencer_buffer &&
-      spdy_session_->ShouldReleaseHeadersStreamSequencerBuffer()) {
+  if (spdy_session_->ShouldReleaseHeadersStreamSequencerBuffer()) {
     sequencer()->ReleaseBufferIfEmpty();
   }
 }
diff --git a/net/quic/core/quic_multipath_received_packet_manager.cc b/net/quic/core/quic_multipath_received_packet_manager.cc
deleted file mode 100644
index c7931cf..0000000
--- a/net/quic/core/quic_multipath_received_packet_manager.cc
+++ /dev/null
@@ -1,117 +0,0 @@
-// Copyright (c) 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 "net/quic/core/quic_multipath_received_packet_manager.h"
-
-#include <cstdint>
-
-#include "net/quic/platform/api/quic_bug_tracker.h"
-#include "net/quic/platform/api/quic_ptr_util.h"
-
-namespace net {
-
-QuicMultipathReceivedPacketManager::QuicMultipathReceivedPacketManager(
-    QuicConnectionStats* stats) {
-  path_managers_[kDefaultPathId] =
-      QuicMakeUnique<QuicReceivedPacketManager>(stats);
-}
-
-QuicMultipathReceivedPacketManager::~QuicMultipathReceivedPacketManager() {}
-
-void QuicMultipathReceivedPacketManager::OnPathCreated(
-    QuicPathId path_id,
-    QuicConnectionStats* stats) {
-  if (path_managers_[path_id] != nullptr) {
-    QUIC_BUG << "Received packet manager of path already exists: "
-             << static_cast<uint32_t>(path_id);
-    return;
-  }
-
-  path_managers_[path_id] = QuicMakeUnique<QuicReceivedPacketManager>(stats);
-}
-
-void QuicMultipathReceivedPacketManager::OnPathClosed(QuicPathId path_id) {
-  QuicReceivedPacketManager* manager = path_managers_[path_id].get();
-  if (manager == nullptr) {
-    QUIC_BUG << "Received packet manager of path does not exist: "
-             << static_cast<uint32_t>(path_id);
-    return;
-  }
-
-  path_managers_.erase(path_id);
-}
-
-void QuicMultipathReceivedPacketManager::RecordPacketReceived(
-    QuicPathId path_id,
-    const QuicPacketHeader& header,
-    QuicTime receipt_time) {
-  QuicReceivedPacketManager* manager = path_managers_[path_id].get();
-  if (manager == nullptr) {
-    QUIC_BUG << "Received a packet on a non-existent path.";
-    return;
-  }
-
-  manager->RecordPacketReceived(header, receipt_time);
-}
-
-bool QuicMultipathReceivedPacketManager::IsMissing(
-    QuicPathId path_id,
-    QuicPacketNumber packet_number) {
-  QuicReceivedPacketManager* manager = path_managers_[path_id].get();
-  if (manager == nullptr) {
-    QUIC_BUG << "Check whether a packet is missing on a non-existent path.";
-    return true;
-  }
-
-  return manager->IsMissing(packet_number);
-}
-
-bool QuicMultipathReceivedPacketManager::IsAwaitingPacket(
-    QuicPathId path_id,
-    QuicPacketNumber packet_number) {
-  QuicReceivedPacketManager* manager = path_managers_[path_id].get();
-  if (manager == nullptr) {
-    QUIC_BUG << "Check whether a packet is awaited on a non-existent path.";
-    return false;
-  }
-
-  return manager->IsAwaitingPacket(packet_number);
-}
-
-void QuicMultipathReceivedPacketManager::UpdatePacketInformationSentByPeer(
-    const std::vector<QuicStopWaitingFrame>& stop_waitings) {
-  for (QuicStopWaitingFrame stop_waiting : stop_waitings) {
-    QuicReceivedPacketManager* manager =
-        path_managers_[stop_waiting.path_id].get();
-    if (manager != nullptr) {
-      manager->DontWaitForPacketsBefore(stop_waiting.least_unacked);
-    }
-  }
-}
-
-bool QuicMultipathReceivedPacketManager::HasNewMissingPackets(
-    QuicPathId path_id) const {
-  auto it = path_managers_.find(path_id);
-  if (it == path_managers_.end()) {
-    QUIC_BUG << "Check whether has new missing packets on a non-existent path.";
-    return false;
-  }
-
-  return it->second->HasNewMissingPackets();
-}
-
-QuicPacketNumber
-QuicMultipathReceivedPacketManager::GetPeerLeastPacketAwaitingAck(
-    QuicPathId path_id) {
-  QuicReceivedPacketManager* manager = path_managers_[path_id].get();
-  if (manager == nullptr) {
-    QUIC_BUG
-        << "Try to get peer_least_packet_awaiting_ack of a non-existent path.";
-    return false;
-  }
-
-  return manager->peer_least_packet_awaiting_ack();
-}
-
-}  // namespace net
diff --git a/net/quic/core/quic_multipath_received_packet_manager.h b/net/quic/core/quic_multipath_received_packet_manager.h
deleted file mode 100644
index 3f48aaa..0000000
--- a/net/quic/core/quic_multipath_received_packet_manager.h
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright (c) 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.
-
-// A connection level received packet manager which manages multiple per path
-// received packet managers.
-
-#ifndef NET_QUIC_CORE_QUIC_MULTIPATH_RECEIVED_PACKET_MANAGER_H_
-#define NET_QUIC_CORE_QUIC_MULTIPATH_RECEIVED_PACKET_MANAGER_H_
-
-#include <memory>
-#include <unordered_map>
-#include <vector>
-
-#include "net/quic/core/quic_packets.h"
-#include "net/quic/core/quic_received_packet_manager.h"
-#include "net/quic/platform/api/quic_export.h"
-
-namespace net {
-
-namespace test {
-class QuicMultipathReceivedPacketManagerPeer;
-}  // namespace test
-
-class QUIC_EXPORT_PRIVATE QuicMultipathReceivedPacketManager {
- public:
-  explicit QuicMultipathReceivedPacketManager(QuicConnectionStats* stats);
-  ~QuicMultipathReceivedPacketManager();
-  QuicMultipathReceivedPacketManager(
-      const QuicMultipathReceivedPacketManager&) = delete;
-  QuicMultipathReceivedPacketManager& operator=(
-      const QuicMultipathReceivedPacketManager&) = delete;
-
-  // Called when a new path with |path_id| is created.
-  void OnPathCreated(QuicPathId path_id, QuicConnectionStats* stats);
-
-  // Called when path with |path_id| is closed.
-  void OnPathClosed(QuicPathId path_id);
-
-  // Records packet receipt information on path with |path_id|.
-  void RecordPacketReceived(QuicPathId path_id,
-                            const QuicPacketHeader& header,
-                            QuicTime receipt_time);
-
-  // Checks whether |packet_number| is missing on path with |path_id|.
-  bool IsMissing(QuicPathId path_id, QuicPacketNumber packet_number);
-
-  // Checks if we're still waiting for the packet with |packet_number| on path
-  // with |path_id|.
-  bool IsAwaitingPacket(QuicPathId path_id, QuicPacketNumber packet_number);
-
-  // If |force_all_paths| is false, populates ack information for paths whose
-  // ack has been updated since UpdateReceivedPacketInfo was called last time.
-  // Otherwise, populates ack for all paths.
-  void UpdateReceivedPacketInfo(std::vector<QuicAckFrame>* ack_frames,
-                                QuicTime approximate_now,
-                                bool force_all_paths);
-
-  // Updates internal state based on stop_waiting frames for corresponding path.
-  void UpdatePacketInformationSentByPeer(
-      const std::vector<QuicStopWaitingFrame>& stop_waitings);
-
-  // Returns true when there are new missing packets to be reported within 3
-  // packets of the largest observed on path with |path_id|.
-  bool HasNewMissingPackets(QuicPathId path_id) const;
-
-  QuicPacketNumber GetPeerLeastPacketAwaitingAck(QuicPathId path_id);
-
- private:
-  friend class test::QuicMultipathReceivedPacketManagerPeer;
-
-  // Map mapping path id to path received packet manager.
-  std::unordered_map<QuicPathId, std::unique_ptr<QuicReceivedPacketManager>>
-      path_managers_;
-};
-
-}  // namespace net
-
-#endif  // NET_QUIC_CORE_QUIC_MULTIPATH_RECEIVED_PACKET_MANAGER_H_
diff --git a/net/quic/core/quic_multipath_received_packet_manager_test.cc b/net/quic/core/quic_multipath_received_packet_manager_test.cc
deleted file mode 100644
index afedaa3..0000000
--- a/net/quic/core/quic_multipath_received_packet_manager_test.cc
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright (c) 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 "net/quic/core/quic_multipath_received_packet_manager.h"
-
-#include "net/quic/core/quic_connection_stats.h"
-#include "net/quic/platform/api/quic_ptr_util.h"
-#include "net/quic/test_tools/quic_test_utils.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using testing::Return;
-using testing::_;
-
-namespace net {
-namespace test {
-
-class QuicMultipathReceivedPacketManagerPeer {
- public:
-  static bool PathReceivedPacketManagerExists(
-      QuicMultipathReceivedPacketManager* multipath_manager,
-      QuicPathId path_id) {
-    return multipath_manager->path_managers_.count(path_id);
-  }
-
-  static void SetPathReceivedPacketManager(
-      QuicMultipathReceivedPacketManager* multipath_manager,
-      QuicPathId path_id,
-      std::unique_ptr<QuicReceivedPacketManager> manager) {
-    multipath_manager->path_managers_[path_id] = std::move(manager);
-  }
-};
-
-namespace {
-
-const QuicPathId kPathId1 = 1;
-const QuicPathId kPathId2 = 2;
-const QuicPathId kPathId3 = 3;
-
-class QuicMultipathReceivedPacketManagerTest : public testing::Test {
- public:
-  QuicMultipathReceivedPacketManagerTest()
-      : multipath_manager_(&stats_),
-        manager_0_(new MockReceivedPacketManager(&stats_)),
-        manager_1_(new MockReceivedPacketManager(&stats_)) {
-    QuicMultipathReceivedPacketManagerPeer::SetPathReceivedPacketManager(
-        &multipath_manager_, kDefaultPathId, QuicWrapUnique(manager_0_));
-    QuicMultipathReceivedPacketManagerPeer::SetPathReceivedPacketManager(
-        &multipath_manager_, kPathId1, QuicWrapUnique(manager_1_));
-  }
-
-  QuicConnectionStats stats_;
-  QuicMultipathReceivedPacketManager multipath_manager_;
-  MockReceivedPacketManager* manager_0_;
-  MockReceivedPacketManager* manager_1_;
-  QuicPacketHeader header_;
-};
-
-TEST_F(QuicMultipathReceivedPacketManagerTest, OnPathCreatedAndClosed) {
-  EXPECT_TRUE(
-      QuicMultipathReceivedPacketManagerPeer::PathReceivedPacketManagerExists(
-          &multipath_manager_, kDefaultPathId));
-  EXPECT_TRUE(
-      QuicMultipathReceivedPacketManagerPeer::PathReceivedPacketManagerExists(
-          &multipath_manager_, kPathId1));
-  EXPECT_QUIC_BUG(multipath_manager_.OnPathCreated(kDefaultPathId, &stats_),
-                  "Received packet manager of path already exists");
-  // Path 2 created.
-  multipath_manager_.OnPathCreated(kPathId2, &stats_);
-  EXPECT_TRUE(
-      QuicMultipathReceivedPacketManagerPeer::PathReceivedPacketManagerExists(
-          &multipath_manager_, kPathId2));
-  EXPECT_FALSE(
-      QuicMultipathReceivedPacketManagerPeer::PathReceivedPacketManagerExists(
-          &multipath_manager_, kPathId3));
-  // Path 3 created.
-  multipath_manager_.OnPathCreated(kPathId3, &stats_);
-  EXPECT_TRUE(
-      QuicMultipathReceivedPacketManagerPeer::PathReceivedPacketManagerExists(
-          &multipath_manager_, kPathId3));
-
-  // Path 0 closed.
-  multipath_manager_.OnPathClosed(kDefaultPathId);
-  EXPECT_FALSE(
-      QuicMultipathReceivedPacketManagerPeer::PathReceivedPacketManagerExists(
-          &multipath_manager_, kDefaultPathId));
-  EXPECT_QUIC_BUG(multipath_manager_.OnPathClosed(kDefaultPathId),
-                  "Received packet manager of path does not exist");
-}
-
-TEST_F(QuicMultipathReceivedPacketManagerTest, RecordPacketReceived) {
-  EXPECT_CALL(*manager_0_, RecordPacketReceived(_, _)).Times(1);
-  multipath_manager_.RecordPacketReceived(kDefaultPathId, header_,
-                                          QuicTime::Zero());
-  EXPECT_QUIC_BUG(multipath_manager_.RecordPacketReceived(kPathId2, header_,
-                                                          QuicTime::Zero()),
-                  "Received a packet on a non-existent path");
-}
-
-TEST_F(QuicMultipathReceivedPacketManagerTest, IsMissing) {
-  EXPECT_CALL(*manager_0_, IsMissing(header_.packet_number))
-      .WillOnce(Return(true));
-  EXPECT_CALL(*manager_1_, IsMissing(header_.packet_number))
-      .WillOnce(Return(false));
-  EXPECT_TRUE(
-      multipath_manager_.IsMissing(kDefaultPathId, header_.packet_number));
-  EXPECT_FALSE(multipath_manager_.IsMissing(kPathId1, header_.packet_number));
-  EXPECT_QUIC_BUG(multipath_manager_.IsMissing(kPathId2, header_.packet_number),
-                  "Check whether a packet is missing on a non-existent path");
-}
-
-TEST_F(QuicMultipathReceivedPacketManagerTest, IsAwaitingPacket) {
-  EXPECT_CALL(*manager_0_, IsAwaitingPacket(header_.packet_number))
-      .WillOnce(Return(true));
-  EXPECT_CALL(*manager_1_, IsAwaitingPacket(header_.packet_number))
-      .WillOnce(Return(false));
-  EXPECT_TRUE(multipath_manager_.IsAwaitingPacket(kDefaultPathId,
-                                                  header_.packet_number));
-  EXPECT_FALSE(
-      multipath_manager_.IsAwaitingPacket(kPathId1, header_.packet_number));
-  EXPECT_QUIC_BUG(
-      multipath_manager_.IsAwaitingPacket(kPathId2, header_.packet_number),
-      "Check whether a packet is awaited on a non-existent path");
-}
-
-TEST_F(QuicMultipathReceivedPacketManagerTest, HasNewMissingPackets) {
-  EXPECT_CALL(*manager_0_, HasNewMissingPackets()).WillOnce(Return(true));
-  EXPECT_CALL(*manager_1_, HasNewMissingPackets()).WillOnce(Return(false));
-  EXPECT_TRUE(multipath_manager_.HasNewMissingPackets(kDefaultPathId));
-  EXPECT_FALSE(multipath_manager_.HasNewMissingPackets(kPathId1));
-  EXPECT_QUIC_BUG(
-      multipath_manager_.HasNewMissingPackets(kPathId2),
-      "Check whether has new missing packets on a non-existent path");
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace net
diff --git a/net/quic/core/quic_multipath_transmissions_map.cc b/net/quic/core/quic_multipath_transmissions_map.cc
deleted file mode 100644
index 100bf08..0000000
--- a/net/quic/core/quic_multipath_transmissions_map.cc
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright (c) 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 "net/quic/core/quic_multipath_transmissions_map.h"
-
-namespace net {
-
-QuicMultipathTransmissionsMap::QuicMultipathTransmissionsMap() {}
-
-QuicMultipathTransmissionsMap::~QuicMultipathTransmissionsMap() {
-  for (std::pair<QuicPathIdPacketNumber, MultipathTransmissionsList*>
-           packet_transmissions : transmission_map_) {
-    packet_transmissions.second->pop_front();
-    if (packet_transmissions.second->empty()) {
-      delete packet_transmissions.second;
-    }
-  }
-}
-
-void QuicMultipathTransmissionsMap::OnPacketRetransmittedOnDifferentPath(
-    QuicPathIdPacketNumber original_path_id_packet_number,
-    QuicPathIdPacketNumber path_id_packet_number) {
-  MultipathTransmissionsList* across_paths_transmission_list = nullptr;
-  MultipathTransmissionsMap::iterator it =
-      transmission_map_.find(original_path_id_packet_number);
-  if (it != transmission_map_.end()) {
-    across_paths_transmission_list = it->second;
-  } else {
-    across_paths_transmission_list = new MultipathTransmissionsList();
-    across_paths_transmission_list->push_back(original_path_id_packet_number);
-    transmission_map_[original_path_id_packet_number] =
-        across_paths_transmission_list;
-  }
-
-  across_paths_transmission_list->push_back(path_id_packet_number);
-  transmission_map_[path_id_packet_number] = across_paths_transmission_list;
-}
-
-const QuicMultipathTransmissionsMap::MultipathTransmissionsList*
-QuicMultipathTransmissionsMap::MaybeGetTransmissionsOnOtherPaths(
-    QuicPathIdPacketNumber path_id_packet_number) const {
-  MultipathTransmissionsMap::const_iterator it =
-      transmission_map_.find(path_id_packet_number);
-  if (it == transmission_map_.end()) {
-    return nullptr;
-  }
-
-  return it->second;
-}
-
-void QuicMultipathTransmissionsMap::OnPacketHandled(
-    QuicPathIdPacketNumber path_id_packet_number) {
-  MultipathTransmissionsMap::iterator it =
-      transmission_map_.find(path_id_packet_number);
-  if (it == transmission_map_.end()) {
-    return;
-  }
-
-  MultipathTransmissionsList* transmission_list = it->second;
-  MultipathTransmissionsList::iterator transmission_it;
-  // Remove all across paths transmissions of this packet from the map.
-  for (QuicPathIdPacketNumber path_id_packet_number : *transmission_list) {
-    transmission_map_.erase(path_id_packet_number);
-  }
-  // Remove the multipath transmissions list.
-  delete transmission_list;
-}
-
-}  // namespace net
diff --git a/net/quic/core/quic_multipath_transmissions_map.h b/net/quic/core/quic_multipath_transmissions_map.h
deleted file mode 100644
index 6b40076..0000000
--- a/net/quic/core/quic_multipath_transmissions_map.h
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright (c) 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.
-
-// A map manages packets which are transmitted across multiple paths.
-// For example, a packet is originally transmitted on path 1 with packet number
-// 1. Then this packet is retransmitted on path 2 with packet number 1. (1, 1)
-// and (2, 1) are inserted into this map. Suppose (2, 1) is detected lost and
-// gets retransmitted on path 2 with packet 2. (2, 2) will not be inserted
-// because this transmission does not "across" path compared to (2, 1).
-
-#ifndef NET_QUIC_CORE_QUIC_MULTIPATH_TRANSMISSIONS_MAP_H_
-#define NET_QUIC_CORE_QUIC_MULTIPATH_TRANSMISSIONS_MAP_H_
-
-#include <deque>
-#include <unordered_map>
-
-#include "base/macros.h"
-#include "net/quic/core/quic_packets.h"
-#include "net/quic/core/quic_utils.h"
-#include "net/quic/platform/api/quic_export.h"
-
-namespace net {
-
-typedef std::pair<QuicPathId, QuicPacketNumber> QuicPathIdPacketNumber;
-
-class QUIC_EXPORT_PRIVATE QuicMultipathTransmissionsMap {
- public:
-  struct QuicPathIdPacketNumberHash {
-    size_t operator()(std::pair<QuicPathId, QuicPacketNumber> value) const {
-      return QuicUtils::PackPathIdAndPacketNumber(value.first, value.second);
-    }
-  };
-
-  typedef std::deque<QuicPathIdPacketNumber> MultipathTransmissionsList;
-  typedef std::unordered_map<QuicPathIdPacketNumber,
-                             MultipathTransmissionsList*,
-                             QuicPathIdPacketNumberHash>
-      MultipathTransmissionsMap;
-
-  QuicMultipathTransmissionsMap();
-  ~QuicMultipathTransmissionsMap();
-
-  // Called when a packet is retransmitted on a different path. Adds both
-  // |original_path_id_packet_number| (if not exists) and
-  // |path_id_packet_number| to |transmission_map_|.
-  void OnPacketRetransmittedOnDifferentPath(
-      QuicPathIdPacketNumber original_path_id_packet_number,
-      QuicPathIdPacketNumber path_id_packet_number);
-
-  // Returns all multipath transmissions list if |path_id_packet_number| has
-  // been transmitted across multiple paths, nullptr otherwise.
-  const MultipathTransmissionsList* MaybeGetTransmissionsOnOtherPaths(
-      QuicPathIdPacketNumber path_id_packet_number) const;
-
-  // Called after packet |path_id_packet_number| is received.
-  // If |path_id_packet_number| has been transmitted across multiple paths,
-  // clears all multipath transmissions list and removes each transmission from
-  // |transmission_map_|, does nothing otherwise.
-  void OnPacketHandled(QuicPathIdPacketNumber path_id_packet_number);
-
- private:
-  // Keys of the map are QuicPathIdPacketNumber, and values are pointers to
-  // lists of multipath transmissions of the same packet. For example, if a
-  // packet has been transmitted as (1, 1) and (2, 1), two entries are added
-  // to this map and both values point to the same list: {(1, 1), (2, 1)}.
-  // The MultipathTransmissionsList is owned by the transmission which is
-  // received first (on any path).
-  MultipathTransmissionsMap transmission_map_;
-};
-
-}  // namespace net
-
-#endif  // NET_QUIC_CORE_QUIC_MULTIPATH_TRANSMISSIONS_MAP_H_
diff --git a/net/quic/core/quic_multipath_transmissions_map_test.cc b/net/quic/core/quic_multipath_transmissions_map_test.cc
deleted file mode 100644
index a264b0d7..0000000
--- a/net/quic/core/quic_multipath_transmissions_map_test.cc
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright (c) 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 "net/quic/core/quic_multipath_transmissions_map.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace net {
-namespace test {
-namespace {
-
-TEST(QuicAcrossPathsTransmissionMapTest, OnPacketRetransmittedOnDifferentPath) {
-  QuicMultipathTransmissionsMap transmission_map;
-  // Packet0's original transmission sent on path 1 with packet number 1.
-  QuicPathIdPacketNumber packet0_0(1, 1);
-  // Packet0's retransmission sent on path 2 with packet number 1.
-  QuicPathIdPacketNumber packet0_1(2, 1);
-  // packet0's 2nd retransmission sent on path 3 with packet number 1.
-  QuicPathIdPacketNumber packet0_2(3, 1);
-
-  transmission_map.OnPacketRetransmittedOnDifferentPath(packet0_0, packet0_1);
-  const QuicMultipathTransmissionsMap::MultipathTransmissionsList*
-      transmission_list1 =
-          transmission_map.MaybeGetTransmissionsOnOtherPaths(packet0_0);
-  EXPECT_EQ(packet0_0, (*transmission_list1)[0]);
-  EXPECT_EQ(packet0_1, (*transmission_list1)[1]);
-
-  transmission_map.OnPacketRetransmittedOnDifferentPath(packet0_1, packet0_2);
-  const QuicMultipathTransmissionsMap::MultipathTransmissionsList*
-      transmission_list2 =
-          transmission_map.MaybeGetTransmissionsOnOtherPaths(packet0_0);
-  EXPECT_EQ(packet0_0, (*transmission_list2)[0]);
-  EXPECT_EQ(packet0_1, (*transmission_list2)[1]);
-  EXPECT_EQ(packet0_2, (*transmission_list2)[2]);
-  // Make sure there is no memory leakage.
-}
-
-TEST(QuicAcrossPathsTransmissionMapTest, MaybeGetTransmissionsOnOtherPaths) {
-  QuicMultipathTransmissionsMap transmission_map;
-  // Packet0's original transmission sent on path 1 with packet number 1.
-  QuicPathIdPacketNumber packet0_0(1, 1);
-  // Packet0's retransmission sent on path 2 with packet number 1.
-  QuicPathIdPacketNumber packet0_1(2, 1);
-  // packet0's 2nd retransmission sent on path 3 with packet number 1.
-  QuicPathIdPacketNumber packet0_2(3, 1);
-
-  transmission_map.OnPacketRetransmittedOnDifferentPath(packet0_0, packet0_1);
-  transmission_map.OnPacketRetransmittedOnDifferentPath(packet0_1, packet0_2);
-
-  const QuicMultipathTransmissionsMap::MultipathTransmissionsList*
-      transmission_list1 =
-          transmission_map.MaybeGetTransmissionsOnOtherPaths(packet0_0);
-  const QuicMultipathTransmissionsMap::MultipathTransmissionsList*
-      transmission_list2 =
-          transmission_map.MaybeGetTransmissionsOnOtherPaths(packet0_1);
-  const QuicMultipathTransmissionsMap::MultipathTransmissionsList*
-      transmission_list3 =
-          transmission_map.MaybeGetTransmissionsOnOtherPaths(packet0_2);
-  // Make sure all three pointers point to the same list.
-  EXPECT_EQ(transmission_list1, transmission_list2);
-  EXPECT_EQ(transmission_list2, transmission_list3);
-  EXPECT_EQ(packet0_0, (*transmission_list1)[0]);
-  EXPECT_EQ(packet0_1, (*transmission_list1)[1]);
-  EXPECT_EQ(packet0_2, (*transmission_list1)[2]);
-
-  // Packet1 which is not transmitted across path.
-  QuicPathIdPacketNumber packet1_0(1, 2);
-  EXPECT_EQ(nullptr,
-            transmission_map.MaybeGetTransmissionsOnOtherPaths(packet1_0));
-  // Make sure there is no memory leakage.
-}
-
-TEST(QuicAcrossPathsTransmissionMapTest, OnPacketHandled) {
-  QuicMultipathTransmissionsMap transmission_map;
-
-  // Packet's original transmission sent on path 1 with packet number 1.
-  QuicPathIdPacketNumber packet0_0(1, 1);
-  // Packet's retransmission sent on path 2 with packet number 1.
-  QuicPathIdPacketNumber packet0_1(2, 1);
-  // packet's 2nd retransmission sent on path 3 with packet number 1.
-  QuicPathIdPacketNumber packet0_2(3, 1);
-  transmission_map.OnPacketRetransmittedOnDifferentPath(packet0_0, packet0_1);
-  transmission_map.OnPacketRetransmittedOnDifferentPath(packet0_1, packet0_2);
-
-  // Packet1's original transmission sent on path 1 with packet number 2.
-  QuicPathIdPacketNumber packet1_0(1, 2);
-  // Packet1's retransmission sent on path 2 with packet number 2.
-  QuicPathIdPacketNumber packet1_1(2, 2);
-  transmission_map.OnPacketRetransmittedOnDifferentPath(packet1_0, packet1_1);
-
-  transmission_map.OnPacketHandled(packet0_0);
-  EXPECT_EQ(nullptr,
-            transmission_map.MaybeGetTransmissionsOnOtherPaths(packet0_0));
-  EXPECT_EQ(nullptr,
-            transmission_map.MaybeGetTransmissionsOnOtherPaths(packet0_1));
-  EXPECT_EQ(nullptr,
-            transmission_map.MaybeGetTransmissionsOnOtherPaths(packet0_2));
-  const QuicMultipathTransmissionsMap::MultipathTransmissionsList*
-      transmission_list =
-          transmission_map.MaybeGetTransmissionsOnOtherPaths(packet1_0);
-  EXPECT_EQ(packet1_0, (*transmission_list)[0]);
-  EXPECT_EQ(packet1_1, (*transmission_list)[1]);
-  // Packet 1 is received on path 2.
-  transmission_map.OnPacketHandled(packet1_1);
-  EXPECT_EQ(nullptr,
-            transmission_map.MaybeGetTransmissionsOnOtherPaths(packet1_0));
-  EXPECT_EQ(nullptr,
-            transmission_map.MaybeGetTransmissionsOnOtherPaths(packet1_1));
-  // Make sure there is no memory leakage.
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace net
diff --git a/net/quic/core/quic_packet_creator.cc b/net/quic/core/quic_packet_creator.cc
index 5c4f4f82..7481e1a 100644
--- a/net/quic/core/quic_packet_creator.cc
+++ b/net/quic/core/quic_packet_creator.cc
@@ -39,13 +39,9 @@
       connection_id_length_(PACKET_8BYTE_CONNECTION_ID),
       packet_size_(0),
       connection_id_(connection_id),
-      packet_(kDefaultPathId,
-              0,
-              PACKET_1BYTE_PACKET_NUMBER,
-              nullptr,
-              0,
-              false,
-              false) {
+      packet_(0, PACKET_1BYTE_PACKET_NUMBER, nullptr, 0, false, false),
+      latched_flag_no_stop_waiting_frames_(
+          FLAGS_quic_reloadable_flag_quic_no_stop_waiting_frames) {
   SetMaxPacketLength(kDefaultMaxPacketSize);
 }
 
@@ -341,6 +337,7 @@
   packet_.encrypted_length = 0;
   DCHECK(packet_.retransmittable_frames.empty());
   packet_.listeners.clear();
+  packet_.largest_acked = 0;
 }
 
 void QuicPacketCreator::CreateAndSerializeStreamFrame(
@@ -395,7 +392,7 @@
   }
 
   size_t encrypted_length = framer_->EncryptInPlace(
-      packet_.encryption_level, packet_.path_id, packet_.packet_number,
+      packet_.encryption_level, packet_.packet_number,
       GetStartOfEncryptedData(framer_->version(), header), writer.length(),
       arraysize(encrypted_buffer), encrypted_buffer);
   if (encrypted_length == 0) {
@@ -499,7 +496,7 @@
     DCHECK_EQ(packet_size_, length);
   }
   const size_t encrypted_length = framer_->EncryptInPlace(
-      packet_.encryption_level, packet_.path_id, packet_.packet_number,
+      packet_.encryption_level, packet_.packet_number,
       GetStartOfEncryptedData(framer_->version(), header), length,
       encrypted_buffer_len, encrypted_buffer);
   if (encrypted_length == 0) {
@@ -527,8 +524,8 @@
 
 // TODO(jri): Make this a public method of framer?
 SerializedPacket QuicPacketCreator::NoPacket() {
-  return SerializedPacket(kInvalidPathId, 0, PACKET_1BYTE_PACKET_NUMBER,
-                          nullptr, 0, false, false);
+  return SerializedPacket(0, PACKET_1BYTE_PACKET_NUMBER, nullptr, 0, false,
+                          false);
 }
 
 void QuicPacketCreator::FillPacketHeader(QuicPacketHeader* header) {
@@ -543,7 +540,6 @@
   } else {
     header->public_header.nonce = nullptr;
   }
-  header->path_id = packet_.path_id;
   header->packet_number = ++packet_.packet_number;
   header->public_header.packet_number_length = packet_.packet_number_length;
 }
@@ -600,6 +596,9 @@
 
   if (frame.type == ACK_FRAME) {
     packet_.has_ack = true;
+    if (latched_flag_no_stop_waiting_frames_) {
+      packet_.largest_acked = frame.ack_frame->largest_observed;
+    }
   }
   if (frame.type == STOP_WAITING_FRAME) {
     packet_.has_stop_waiting = true;
diff --git a/net/quic/core/quic_packet_creator.h b/net/quic/core/quic_packet_creator.h
index f7bce4e..f73f7c13 100644
--- a/net/quic/core/quic_packet_creator.h
+++ b/net/quic/core/quic_packet_creator.h
@@ -209,6 +209,10 @@
     debug_delegate_ = debug_delegate;
   }
 
+  bool latched_flag_no_stop_waiting_frames() const {
+    return latched_flag_no_stop_waiting_frames_;
+  }
+
  private:
   friend class test::QuicPacketCreatorPeer;
 
@@ -299,8 +303,8 @@
   // Packet used to invoke OnSerializedPacket.
   SerializedPacket packet_;
 
-  // Map mapping path_id to last sent packet number on the path.
-  std::unordered_map<QuicPathId, QuicPacketNumber> multipath_packet_number_;
+  // The latched value of FLAGS_quic_reloadable_flag_quic_no_stop_waiting_frames
+  bool latched_flag_no_stop_waiting_frames_;
 
   DISALLOW_COPY_AND_ASSIGN(QuicPacketCreator);
 };
diff --git a/net/quic/core/quic_packet_creator_test.cc b/net/quic/core/quic_packet_creator_test.cc
index 69439d3..1934414 100644
--- a/net/quic/core/quic_packet_creator_test.cc
+++ b/net/quic/core/quic_packet_creator_test.cc
@@ -753,7 +753,7 @@
             creator_.BytesFree());
 
   // Add a variety of frame types and then a padding frame.
-  QuicAckFrame ack_frame(MakeAckFrame(0u));
+  QuicAckFrame ack_frame(MakeAckFrame(10u));
   EXPECT_TRUE(creator_.AddSavedFrame(QuicFrame(&ack_frame)));
   EXPECT_TRUE(creator_.HasPendingFrames());
 
@@ -783,6 +783,10 @@
   ASSERT_EQ(1u, retransmittable.size());
   EXPECT_EQ(STREAM_FRAME, retransmittable[0].type);
   ASSERT_TRUE(retransmittable[0].stream_frame);
+  EXPECT_TRUE(serialized_packet_.has_ack);
+  if (FLAGS_quic_reloadable_flag_quic_no_stop_waiting_frames) {
+    EXPECT_EQ(10u, serialized_packet_.largest_acked);
+  }
   DeleteSerializedPacket();
 
   EXPECT_FALSE(creator_.HasPendingFrames());
diff --git a/net/quic/core/quic_packet_generator.h b/net/quic/core/quic_packet_generator.h
index 5821aad..676691c 100644
--- a/net/quic/core/quic_packet_generator.h
+++ b/net/quic/core/quic_packet_generator.h
@@ -176,6 +176,10 @@
     packet_creator_.set_debug_delegate(debug_delegate);
   }
 
+  bool latched_flag_no_stop_waiting_frames() const {
+    return packet_creator_.latched_flag_no_stop_waiting_frames();
+  }
+
  private:
   friend class test::QuicPacketGeneratorPeer;
 
diff --git a/net/quic/core/quic_packets.cc b/net/quic/core/quic_packets.cc
index a88b6e8..a5c4410 100644
--- a/net/quic/core/quic_packets.cc
+++ b/net/quic/core/quic_packets.cc
@@ -64,11 +64,10 @@
 
 QuicPacketPublicHeader::~QuicPacketPublicHeader() {}
 
-QuicPacketHeader::QuicPacketHeader()
-    : packet_number(0), path_id(kDefaultPathId) {}
+QuicPacketHeader::QuicPacketHeader() : packet_number(0) {}
 
 QuicPacketHeader::QuicPacketHeader(const QuicPacketPublicHeader& header)
-    : public_header(header), packet_number(0), path_id(kDefaultPathId) {}
+    : public_header(header), packet_number(0) {}
 
 QuicPacketHeader::QuicPacketHeader(const QuicPacketHeader& other) = default;
 
@@ -98,8 +97,7 @@
               StringPiece(header.public_header.nonce->data(),
                           header.public_header.nonce->size()));
   }
-  os << ", path_id: " << static_cast<int>(header.path_id)
-     << ", packet_number: " << header.packet_number << " }\n";
+  os << ", packet_number: " << header.packet_number << " }\n";
   return os;
 }
 
@@ -200,8 +198,7 @@
                      length() - start_of_encrypted_data);
 }
 
-SerializedPacket::SerializedPacket(QuicPathId path_id,
-                                   QuicPacketNumber packet_number,
+SerializedPacket::SerializedPacket(QuicPacketNumber packet_number,
                                    QuicPacketNumberLength packet_number_length,
                                    const char* encrypted_buffer,
                                    QuicPacketLength encrypted_length,
@@ -211,14 +208,14 @@
       encrypted_length(encrypted_length),
       has_crypto_handshake(NOT_HANDSHAKE),
       num_padding_bytes(0),
-      path_id(path_id),
       packet_number(packet_number),
       packet_number_length(packet_number_length),
       encryption_level(ENCRYPTION_NONE),
       has_ack(has_ack),
       has_stop_waiting(has_stop_waiting),
       transmission_type(NOT_RETRANSMISSION),
-      original_packet_number(0) {}
+      original_packet_number(0),
+      largest_acked(0) {}
 
 SerializedPacket::SerializedPacket(const SerializedPacket& other) = default;
 
@@ -230,6 +227,7 @@
   }
   serialized_packet->encrypted_buffer = nullptr;
   serialized_packet->encrypted_length = 0;
+  serialized_packet->largest_acked = 0;
 }
 
 char* CopyBuffer(const SerializedPacket& packet) {
diff --git a/net/quic/core/quic_packets.h b/net/quic/core/quic_packets.h
index 5f2d863..80398e0 100644
--- a/net/quic/core/quic_packets.h
+++ b/net/quic/core/quic_packets.h
@@ -86,7 +86,6 @@
 
   QuicPacketPublicHeader public_header;
   QuicPacketNumber packet_number;
-  QuicPathId path_id;
 };
 
 struct QUIC_EXPORT_PRIVATE QuicPublicResetPacket {
@@ -212,8 +211,7 @@
 };
 
 struct QUIC_EXPORT_PRIVATE SerializedPacket {
-  SerializedPacket(QuicPathId path_id,
-                   QuicPacketNumber packet_number,
+  SerializedPacket(QuicPacketNumber packet_number,
                    QuicPacketNumberLength packet_number_length,
                    const char* encrypted_buffer,
                    QuicPacketLength encrypted_length,
@@ -231,7 +229,6 @@
   //  0: no padding
   //  otherwise: only pad up to num_padding_bytes bytes
   int16_t num_padding_bytes;
-  QuicPathId path_id;
   QuicPacketNumber packet_number;
   QuicPacketNumberLength packet_number_length;
   EncryptionLevel encryption_level;
@@ -239,6 +236,9 @@
   bool has_stop_waiting;
   TransmissionType transmission_type;
   QuicPacketNumber original_packet_number;
+  // The largest acked of the AckFrame in this packet if has_ack is true,
+  // 0 otherwise.
+  QuicPacketNumber largest_acked;
 
   // Optional notifiers which will be informed when this packet has been ACKed.
   std::list<AckListenerWrapper> listeners;
diff --git a/net/quic/core/quic_received_packet_manager.cc b/net/quic/core/quic_received_packet_manager.cc
index 668301d..2c4ae8f 100644
--- a/net/quic/core/quic_received_packet_manager.cc
+++ b/net/quic/core/quic_received_packet_manager.cc
@@ -26,6 +26,7 @@
 QuicReceivedPacketManager::QuicReceivedPacketManager(QuicConnectionStats* stats)
     : peer_least_packet_awaiting_ack_(0),
       ack_frame_updated_(false),
+      max_ack_ranges_(0),
       time_largest_observed_(QuicTime::Zero()),
       stats_(stats) {
   ack_frame_.largest_observed = 0;
@@ -87,6 +88,10 @@
                                     ? QuicTime::Delta::Zero()
                                     : approximate_now - time_largest_observed_;
   }
+  while (max_ack_ranges_ > 0 &&
+         ack_frame_.packets.NumIntervals() > max_ack_ranges_) {
+    ack_frame_.packets.RemoveSmallestInterval();
+  }
 
   // Clear all packet times if any are too far from largest observed.
   // It's expected this is extremely rare.
diff --git a/net/quic/core/quic_received_packet_manager.h b/net/quic/core/quic_received_packet_manager.h
index 08001a8..4da4a1e0 100644
--- a/net/quic/core/quic_received_packet_manager.h
+++ b/net/quic/core/quic_received_packet_manager.h
@@ -65,6 +65,10 @@
   // For logging purposes.
   const QuicAckFrame& ack_frame() const { return ack_frame_; }
 
+  void set_max_ack_ranges(size_t max_ack_ranges) {
+    max_ack_ranges_ = max_ack_ranges;
+  }
+
  private:
   friend class test::QuicConnectionPeer;
 
@@ -79,6 +83,9 @@
   // last called.
   bool ack_frame_updated_;
 
+  // Maximum number of ack ranges allowed to be stored in the ack frame.
+  size_t max_ack_ranges_;
+
   // The time we received the largest_observed packet number, or zero if
   // no packet numbers have been received since UpdateReceivedPacketInfo.
   // Needed for calculating ack_delay_time.
diff --git a/net/quic/core/quic_received_packet_manager_test.cc b/net/quic/core/quic_received_packet_manager_test.cc
index e7ff3d3..2f2c7a7 100644
--- a/net/quic/core/quic_received_packet_manager_test.cc
+++ b/net/quic/core/quic_received_packet_manager_test.cc
@@ -124,6 +124,23 @@
   EXPECT_EQ(1u, stats_.packets_reordered);
 }
 
+TEST_P(QuicReceivedPacketManagerTest, LimitAckRanges) {
+  received_manager_.set_max_ack_ranges(10);
+  EXPECT_FALSE(received_manager_.ack_frame_updated());
+  for (int i = 0; i < 100; ++i) {
+    RecordPacketReceipt(1 + 2 * i);
+    EXPECT_TRUE(received_manager_.ack_frame_updated());
+    received_manager_.GetUpdatedAckFrame(QuicTime::Zero());
+    EXPECT_GE(10u, received_manager_.ack_frame().packets.NumIntervals());
+    EXPECT_EQ(1u + 2 * i, received_manager_.ack_frame().packets.Max());
+    for (int j = 0; j < std::min(10, i + 1); ++j) {
+      EXPECT_TRUE(
+          received_manager_.ack_frame().packets.Contains(1 + (i - j) * 2));
+      EXPECT_FALSE(received_manager_.ack_frame().packets.Contains((i - j) * 2));
+    }
+  }
+}
+
 }  // namespace
 }  // namespace test
 }  // namespace net
diff --git a/net/quic/core/quic_sent_packet_manager.cc b/net/quic/core/quic_sent_packet_manager.cc
index 3b601e25..b88e532 100644
--- a/net/quic/core/quic_sent_packet_manager.cc
+++ b/net/quic/core/quic_sent_packet_manager.cc
@@ -83,7 +83,8 @@
       conservative_handshake_retransmits_(false),
       largest_newly_acked_(0),
       largest_mtu_acked_(0),
-      handshake_confirmed_(false) {
+      handshake_confirmed_(false),
+      largest_packet_peer_knows_is_acked_(0) {
   SetSendAlgorithm(congestion_control_type);
 }
 
@@ -104,40 +105,18 @@
                           config.GetInitialRoundTripTimeUsToSend())));
   }
   // Configure congestion control.
-  const bool enable_client_connection_options =
-      FLAGS_quic_reloadable_flag_quic_client_connection_options;
-  if (enable_client_connection_options) {
-    if (FLAGS_quic_reloadable_flag_quic_allow_new_bbr &&
-        config.HasClientRequestedIndependentOption(kTBBR, perspective_)) {
-      SetSendAlgorithm(kBBR);
+  if (FLAGS_quic_reloadable_flag_quic_allow_new_bbr &&
+      config.HasClientRequestedIndependentOption(kTBBR, perspective_)) {
+    SetSendAlgorithm(kBBR);
+  }
+  if (config.HasClientRequestedIndependentOption(kRENO, perspective_)) {
+    if (config.HasClientRequestedIndependentOption(kBYTE, perspective_)) {
+      SetSendAlgorithm(kRenoBytes);
+    } else {
+      SetSendAlgorithm(kReno);
     }
-    if (config.HasClientRequestedIndependentOption(kRENO, perspective_)) {
-      if (config.HasClientRequestedIndependentOption(kBYTE, perspective_)) {
-        SetSendAlgorithm(kRenoBytes);
-      } else {
-        SetSendAlgorithm(kReno);
-      }
-    } else if (config.HasClientRequestedIndependentOption(kBYTE,
-                                                          perspective_)) {
-      SetSendAlgorithm(kCubic);
-    }
-  } else {
-    if (FLAGS_quic_reloadable_flag_quic_allow_new_bbr &&
-        config.HasReceivedConnectionOptions() &&
-        ContainsQuicTag(config.ReceivedConnectionOptions(), kTBBR)) {
-      SetSendAlgorithm(kBBR);
-    }
-    if (config.HasReceivedConnectionOptions() &&
-        ContainsQuicTag(config.ReceivedConnectionOptions(), kRENO)) {
-      if (ContainsQuicTag(config.ReceivedConnectionOptions(), kBYTE)) {
-        SetSendAlgorithm(kRenoBytes);
-      } else {
-        SetSendAlgorithm(kReno);
-      }
-    } else if (config.HasReceivedConnectionOptions() &&
-               ContainsQuicTag(config.ReceivedConnectionOptions(), kBYTE)) {
-      SetSendAlgorithm(kCubic);
-    }
+  } else if (config.HasClientRequestedIndependentOption(kBYTE, perspective_)) {
+    SetSendAlgorithm(kCubic);
   }
   using_pacing_ = !FLAGS_quic_disable_pacing_for_perf_tests;
 
@@ -157,37 +136,19 @@
     use_new_rto_ = true;
   }
   // Configure loss detection.
-  if (enable_client_connection_options) {
-    if (config.HasClientRequestedIndependentOption(kTIME, perspective_)) {
-      general_loss_algorithm_.SetLossDetectionType(kTime);
-    }
-    if (config.HasClientRequestedIndependentOption(kATIM, perspective_)) {
-      general_loss_algorithm_.SetLossDetectionType(kAdaptiveTime);
-    }
-    if (FLAGS_quic_reloadable_flag_quic_enable_lazy_fack &&
-        config.HasClientRequestedIndependentOption(kLFAK, perspective_)) {
-      general_loss_algorithm_.SetLossDetectionType(kLazyFack);
-    }
-  } else {
-    if (config.HasReceivedConnectionOptions() &&
-        ContainsQuicTag(config.ReceivedConnectionOptions(), kTIME)) {
-      general_loss_algorithm_.SetLossDetectionType(kTime);
-    }
-    if (config.HasReceivedConnectionOptions() &&
-        ContainsQuicTag(config.ReceivedConnectionOptions(), kATIM)) {
-      general_loss_algorithm_.SetLossDetectionType(kAdaptiveTime);
-    }
-    if (FLAGS_quic_reloadable_flag_quic_enable_lazy_fack &&
-        config.HasReceivedConnectionOptions() &&
-        ContainsQuicTag(config.ReceivedConnectionOptions(), kLFAK)) {
-      general_loss_algorithm_.SetLossDetectionType(kLazyFack);
-    }
+  if (config.HasClientRequestedIndependentOption(kTIME, perspective_)) {
+    general_loss_algorithm_.SetLossDetectionType(kTime);
+  }
+  if (config.HasClientRequestedIndependentOption(kATIM, perspective_)) {
+    general_loss_algorithm_.SetLossDetectionType(kAdaptiveTime);
+  }
+  if (config.HasClientRequestedIndependentOption(kLFAK, perspective_)) {
+    general_loss_algorithm_.SetLossDetectionType(kLazyFack);
   }
   if (config.HasClientSentConnectionOption(kUNDO, perspective_)) {
     undo_pending_retransmits_ = true;
   }
-  if (FLAGS_quic_reloadable_flag_quic_conservative_handshake_retransmits &&
-      config.HasClientSentConnectionOption(kCONH, perspective_)) {
+  if (config.HasClientSentConnectionOption(kCONH, perspective_)) {
     conservative_handshake_retransmits_ = true;
   }
   send_algorithm_->SetFromConfig(config, perspective_);
@@ -339,6 +300,10 @@
     }
     // Packet was acked, so remove it from our unacked packet list.
     QUIC_DVLOG(1) << ENDPOINT << "Got an ack for packet " << packet_number;
+    if (it->largest_acked > 0) {
+      largest_packet_peer_knows_is_acked_ =
+          std::max(largest_packet_peer_knows_is_acked_, it->largest_acked);
+    }
     // If data is associated with the most recent transmission of this
     // packet, then inform the caller.
     if (it->in_flight) {
@@ -741,18 +706,6 @@
   }
 
   QuicTime::Delta send_delta = ack_receive_time - transmission_info.sent_time;
-  const int kMaxSendDeltaSeconds = 30;
-  if (!FLAGS_quic_reloadable_flag_quic_allow_large_send_deltas &&
-      send_delta.ToSeconds() > kMaxSendDeltaSeconds) {
-    // send_delta can be very high if local clock is changed mid-connection.
-    QUIC_LOG_FIRST_N(WARNING, 10)
-        << "Excessive send delta: " << send_delta.ToSeconds()
-        << ", setting to: " << kMaxSendDeltaSeconds
-        << " largest_observed:" << ack_frame.largest_observed
-        << " ack_receive_time:" << ack_receive_time.ToDebuggingValue()
-        << " sent_time:" << transmission_info.sent_time.ToDebuggingValue();
-    return false;
-  }
   rtt_stats_.UpdateRtt(send_delta, ack_frame.ack_delay_time, ack_receive_time);
 
   return true;
diff --git a/net/quic/core/quic_sent_packet_manager.h b/net/quic/core/quic_sent_packet_manager.h
index c135b2f9..e2af107 100644
--- a/net/quic/core/quic_sent_packet_manager.h
+++ b/net/quic/core/quic_sent_packet_manager.h
@@ -79,8 +79,6 @@
 
     // Called with the path may be degrading. Note that the path may only be
     // temporarily degrading.
-    // TODO(jri): With multipath, this method should probably have a path_id
-    // parameter, and should maybe result in the path being marked as inactive.
     virtual void OnPathDegrading() = 0;
 
     // Called when the Path MTU may have increased.
@@ -222,6 +220,10 @@
 
   const SendAlgorithmInterface* GetSendAlgorithm() const;
 
+  QuicPacketNumber largest_packet_peer_knows_is_acked() const {
+    return largest_packet_peer_knows_is_acked_;
+  }
+
  private:
   friend class test::QuicConnectionPeer;
   friend class test::QuicSentPacketManagerPeer;
@@ -402,6 +404,9 @@
   // of time with no loss events.
   QuicSustainedBandwidthRecorder sustained_bandwidth_recorder_;
 
+  // The largest acked value that was sent in an ack, which has then been acked.
+  QuicPacketNumber largest_packet_peer_knows_is_acked_;
+
   DISALLOW_COPY_AND_ASSIGN(QuicSentPacketManager);
 };
 
diff --git a/net/quic/core/quic_sent_packet_manager_test.cc b/net/quic/core/quic_sent_packet_manager_test.cc
index b0f4c34..ac47ba6 100644
--- a/net/quic/core/quic_sent_packet_manager_test.cc
+++ b/net/quic/core/quic_sent_packet_manager_test.cc
@@ -28,7 +28,6 @@
 namespace net {
 namespace test {
 namespace {
-
 // Default packet length.
 const uint32_t kDefaultLength = 1000;
 
@@ -192,9 +191,8 @@
 
   SerializedPacket CreatePacket(QuicPacketNumber packet_number,
                                 bool retransmittable) {
-    SerializedPacket packet(kDefaultPathId, packet_number,
-                            PACKET_6BYTE_PACKET_NUMBER, nullptr, kDefaultLength,
-                            false, false);
+    SerializedPacket packet(packet_number, PACKET_6BYTE_PACKET_NUMBER, nullptr,
+                            kDefaultLength, false, false);
     if (retransmittable) {
       packet.retransmittable_frames.push_back(
           QuicFrame(new QuicStreamFrame(kStreamId, false, 0, StringPiece())));
@@ -226,13 +224,15 @@
                           HAS_RETRANSMITTABLE_DATA);
   }
 
-  void SendAckPacket(QuicPacketNumber packet_number) {
+  void SendAckPacket(QuicPacketNumber packet_number,
+                     QuicPacketNumber largest_acked) {
     EXPECT_CALL(*send_algorithm_,
                 OnPacketSent(_, BytesInFlight(), packet_number, kDefaultLength,
                              NO_RETRANSMITTABLE_DATA))
         .Times(1)
         .WillOnce(Return(false));
     SerializedPacket packet(CreatePacket(packet_number, false));
+    packet.largest_acked = largest_acked;
     manager_.OnPacketSent(&packet, 0, clock_.Now(), NOT_RETRANSMISSION,
                           NO_RETRANSMITTABLE_DATA);
   }
@@ -536,8 +536,10 @@
 }
 
 TEST_F(QuicSentPacketManagerTest, AckAckAndUpdateRtt) {
+  FLAGS_quic_reloadable_flag_quic_no_stop_waiting_frames = true;
+  EXPECT_EQ(0u, manager_.largest_packet_peer_knows_is_acked());
   SendDataPacket(1);
-  SendAckPacket(2);
+  SendAckPacket(2, 1);
 
   // Now ack the ack and expect an RTT update.
   QuicAckFrame ack_frame = InitAckFrame(2);
@@ -545,13 +547,15 @@
 
   ExpectAck(1);
   manager_.OnIncomingAck(ack_frame, clock_.Now());
+  EXPECT_EQ(1u, manager_.largest_packet_peer_knows_is_acked());
 
-  SendAckPacket(3);
+  SendAckPacket(3, 3);
 
   // Now ack the ack and expect only an RTT update.
   ack_frame = InitAckFrame(3);
   ExpectUpdatedRtt(3);
   manager_.OnIncomingAck(ack_frame, clock_.Now());
+  EXPECT_EQ(3u, manager_.largest_packet_peer_knows_is_acked());
 }
 
 TEST_F(QuicSentPacketManagerTest, Rtt) {
@@ -1109,7 +1113,6 @@
 
 TEST_F(QuicSentPacketManagerTest,
        GetConservativeTransmissionTimeCryptoHandshake) {
-  FLAGS_quic_reloadable_flag_quic_conservative_handshake_retransmits = true;
   QuicConfig config;
   QuicTagVector options;
   options.push_back(kCONH);
@@ -1403,7 +1406,6 @@
 
 TEST_F(QuicSentPacketManagerTest, NegotiateClientCongestionControlFromOptions) {
   FLAGS_quic_reloadable_flag_quic_allow_new_bbr = true;
-  FLAGS_quic_reloadable_flag_quic_client_connection_options = true;
   QuicConfig config;
   QuicTagVector options;
 
@@ -1718,8 +1720,8 @@
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, BytesInFlight(), 1, _, _))
       .Times(1)
       .WillOnce(Return(true));
-  SerializedPacket packet(kDefaultPathId, 1, PACKET_6BYTE_PACKET_NUMBER,
-                          nullptr, kDefaultLength + 100, false, false);
+  SerializedPacket packet(1, PACKET_6BYTE_PACKET_NUMBER, nullptr,
+                          kDefaultLength + 100, false, false);
   manager_.OnPacketSent(&packet, 0, clock_.Now(), NOT_RETRANSMISSION,
                         HAS_RETRANSMITTABLE_DATA);
 
diff --git a/net/quic/core/quic_server_session_base_test.cc b/net/quic/core/quic_server_session_base_test.cc
index 6e18cd5..9348fdfd 100644
--- a/net/quic/core/quic_server_session_base_test.cc
+++ b/net/quic/core/quic_server_session_base_test.cc
@@ -474,9 +474,9 @@
 
   // Bandwidth estimate has now changed sufficiently, enough time has passed,
   // and enough packets have been sent.
-  SerializedPacket packet(
-      kDefaultPathId, 1 + kMinPacketsBetweenServerConfigUpdates,
-      PACKET_6BYTE_PACKET_NUMBER, nullptr, 1000, false, false);
+  SerializedPacket packet(1 + kMinPacketsBetweenServerConfigUpdates,
+                          PACKET_6BYTE_PACKET_NUMBER, nullptr, 1000, false,
+                          false);
   sent_packet_manager->OnPacketSent(&packet, 0, now, NOT_RETRANSMISSION,
                                     HAS_RETRANSMITTABLE_DATA);
 
@@ -613,7 +613,7 @@
   chlo.SetVector(kCOPT, QuicTagVector{kSREJ});
   std::vector<QuicVersion> packet_version_list = {version};
   std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
-      1, true, false, false, kDefaultPathId, 1,
+      1, true, false, false, 1,
       chlo.GetSerialized().AsStringPiece().as_string(),
       PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER,
       &packet_version_list));
diff --git a/net/quic/core/quic_stream_sequencer_buffer.cc b/net/quic/core/quic_stream_sequencer_buffer.cc
index 210bf56bd..b4d2736 100644
--- a/net/quic/core/quic_stream_sequencer_buffer.cc
+++ b/net/quic/core/quic_stream_sequencer_buffer.cc
@@ -38,11 +38,7 @@
       blocks_count_(
           ceil(static_cast<double>(max_capacity_bytes) / kBlockSizeBytes)),
       total_bytes_read_(0),
-      reduce_sequencer_buffer_memory_life_time_(
-          FLAGS_quic_reloadable_flag_quic_reduce_sequencer_buffer_memory_life_time),  // NOLINT
-      blocks_(reduce_sequencer_buffer_memory_life_time_
-                  ? nullptr
-                  : new BufferBlock*[blocks_count_]()),
+      blocks_(nullptr),
       destruction_indicator_(123456) {
   CHECK_GT(blocks_count_, 1u)
       << "blocks_count_ = " << blocks_count_
@@ -56,7 +52,7 @@
 }
 
 void QuicStreamSequencerBuffer::Clear() {
-  if (!reduce_sequencer_buffer_memory_life_time_ || blocks_ != nullptr) {
+  if (blocks_ != nullptr) {
     for (size_t i = 0; i < blocks_count_; ++i) {
       if (blocks_[i] != nullptr) {
         RetireBlock(i);
@@ -175,7 +171,7 @@
       bytes_avail = total_bytes_read_ + max_buffer_capacity_bytes_ - offset;
     }
 
-    if (reduce_sequencer_buffer_memory_life_time_ && blocks_ == nullptr) {
+    if (blocks_ == nullptr) {
       blocks_.reset(new BufferBlock*[blocks_count_]());
       for (size_t i = 0; i < blocks_count_; ++i) {
         blocks_[i] = nullptr;
@@ -464,10 +460,6 @@
 }
 
 void QuicStreamSequencerBuffer::ReleaseWholeBuffer() {
-  if (!reduce_sequencer_buffer_memory_life_time_) {
-    // Don't release buffer if flag is off.
-    return;
-  }
   Clear();
   blocks_.reset(nullptr);
 }
diff --git a/net/quic/core/quic_stream_sequencer_buffer.h b/net/quic/core/quic_stream_sequencer_buffer.h
index 14d1014..bd57ac9 100644
--- a/net/quic/core/quic_stream_sequencer_buffer.h
+++ b/net/quic/core/quic_stream_sequencer_buffer.h
@@ -166,10 +166,6 @@
   // Count how many bytes are in buffer at this moment.
   size_t BytesBuffered() const;
 
-  bool reduce_sequencer_buffer_memory_life_time() const {
-    return reduce_sequencer_buffer_memory_life_time_;
-  }
-
  private:
   friend class test::QuicStreamSequencerBufferPeer;
 
@@ -237,10 +233,6 @@
   // Contains Gaps which represents currently missing data.
   std::list<Gap> gaps_;
 
-  // If true, allocate buffer memory upon the first frame arrival and release
-  // the memory when stream is read closed.
-  bool reduce_sequencer_buffer_memory_life_time_;
-
   // An ordered, variable-length list of blocks, with the length limited
   // such that the number of blocks never exceeds blocks_count_.
   // Each list entry can hold up to kBlockSizeBytes bytes.
diff --git a/net/quic/core/quic_stream_sequencer_buffer_test.cc b/net/quic/core/quic_stream_sequencer_buffer_test.cc
index e3be181..1bf04cd 100644
--- a/net/quic/core/quic_stream_sequencer_buffer_test.cc
+++ b/net/quic/core/quic_stream_sequencer_buffer_test.cc
@@ -111,9 +111,7 @@
 }
 
 TEST_F(QuicStreamSequencerBufferTest, OnStreamDataWithinBlock) {
-  if (FLAGS_quic_reloadable_flag_quic_reduce_sequencer_buffer_memory_life_time) {  // NOLINT
-    EXPECT_FALSE(helper_->IsBufferAllocated());
-  }
+  EXPECT_FALSE(helper_->IsBufferAllocated());
   string source(1024, 'a');
   size_t written;
   clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
@@ -472,11 +470,6 @@
 
 TEST_F(QuicStreamSequencerBufferTest, ReleaseWholeBuffer) {
   // Tests that buffer is not deallocated unless ReleaseWholeBuffer() is called.
-  if (!FLAGS_quic_reloadable_flag_quic_reduce_sequencer_buffer_memory_life_time) {  // NOLINT
-    // Won't release buffer when flag is off.
-    return;
-  }
-
   string source(100, 'b');
   clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
   QuicTime t1 = clock_.ApproximateNow();
diff --git a/net/quic/core/quic_transmission_info.cc b/net/quic/core/quic_transmission_info.cc
index 96cbfd24..d5654328 100644
--- a/net/quic/core/quic_transmission_info.cc
+++ b/net/quic/core/quic_transmission_info.cc
@@ -16,7 +16,8 @@
       is_unackable(false),
       has_crypto_handshake(false),
       num_padding_bytes(0),
-      retransmission(0) {}
+      retransmission(0),
+      largest_acked(0) {}
 
 QuicTransmissionInfo::QuicTransmissionInfo(
     EncryptionLevel level,
@@ -35,7 +36,8 @@
       is_unackable(false),
       has_crypto_handshake(has_crypto_handshake),
       num_padding_bytes(num_padding_bytes),
-      retransmission(0) {}
+      retransmission(0),
+      largest_acked(0) {}
 
 QuicTransmissionInfo::QuicTransmissionInfo(const QuicTransmissionInfo& other) =
     default;
diff --git a/net/quic/core/quic_transmission_info.h b/net/quic/core/quic_transmission_info.h
index cce790e..6529f4e 100644
--- a/net/quic/core/quic_transmission_info.h
+++ b/net/quic/core/quic_transmission_info.h
@@ -55,6 +55,8 @@
   QuicPacketNumber retransmission;
   // Non-empty if there is a listener for this packet.
   std::list<AckListenerWrapper> ack_listeners;
+  // The largest_acked in the ack frame, if the packet contains an ack.
+  QuicPacketNumber largest_acked;
 };
 
 }  // namespace net
diff --git a/net/quic/core/quic_unacked_packet_map.cc b/net/quic/core/quic_unacked_packet_map.cc
index 62a687c7..8c5fbf1 100644
--- a/net/quic/core/quic_unacked_packet_map.cc
+++ b/net/quic/core/quic_unacked_packet_map.cc
@@ -43,6 +43,7 @@
   QuicTransmissionInfo info(
       packet->encryption_level, packet->packet_number_length, transmission_type,
       sent_time, bytes_sent, has_crypto_handshake, packet->num_padding_bytes);
+  info.largest_acked = packet->largest_acked;
   if (old_packet_number > 0) {
     TransferRetransmissionInfo(old_packet_number, packet_number,
                                transmission_type, &info);
diff --git a/net/quic/core/quic_unacked_packet_map_test.cc b/net/quic/core/quic_unacked_packet_map_test.cc
index 443cae6..29c75bb 100644
--- a/net/quic/core/quic_unacked_packet_map_test.cc
+++ b/net/quic/core/quic_unacked_packet_map_test.cc
@@ -30,9 +30,8 @@
   SerializedPacket CreateRetransmittablePacketForStream(
       QuicPacketNumber packet_number,
       QuicStreamId stream_id) {
-    SerializedPacket packet(kDefaultPathId, packet_number,
-                            PACKET_1BYTE_PACKET_NUMBER, nullptr, kDefaultLength,
-                            false, false);
+    SerializedPacket packet(packet_number, PACKET_1BYTE_PACKET_NUMBER, nullptr,
+                            kDefaultLength, false, false);
     QuicStreamFrame* frame = new QuicStreamFrame();
     frame->stream_id = stream_id;
     packet.retransmittable_frames.push_back(QuicFrame(frame));
@@ -41,9 +40,8 @@
 
   SerializedPacket CreateNonRetransmittablePacket(
       QuicPacketNumber packet_number) {
-    return SerializedPacket(kDefaultPathId, packet_number,
-                            PACKET_1BYTE_PACKET_NUMBER, nullptr, kDefaultLength,
-                            false, false);
+    return SerializedPacket(packet_number, PACKET_1BYTE_PACKET_NUMBER, nullptr,
+                            kDefaultLength, false, false);
   }
 
   void VerifyInFlightPackets(QuicPacketNumber* packets, size_t num_packets) {
diff --git a/net/quic/core/quic_utils.cc b/net/quic/core/quic_utils.cc
index 861ee3d6..0667768 100644
--- a/net/quic/core/quic_utils.cc
+++ b/net/quic/core/quic_utils.cc
@@ -176,21 +176,6 @@
 }
 
 // static
-uint64_t QuicUtils::PackPathIdAndPacketNumber(QuicPathId path_id,
-                                              QuicPacketNumber packet_number) {
-  // Setting the nonce below relies on QuicPathId and QuicPacketNumber being
-  // specific sizes.
-  static_assert(sizeof(path_id) == 1, "Size of QuicPathId changed.");
-  static_assert(sizeof(packet_number) == 8,
-                "Size of QuicPacketNumber changed.");
-  // Use path_id and lower 7 bytes of packet_number as lower 8 bytes of nonce.
-  uint64_t path_id_packet_number =
-      (static_cast<uint64_t>(path_id) << 56) | packet_number;
-  DCHECK(path_id != kDefaultPathId || path_id_packet_number == packet_number);
-  return path_id_packet_number;
-}
-
-// static
 PeerAddressChangeType QuicUtils::DetermineAddressChangeType(
     const QuicSocketAddress& old_address,
     const QuicSocketAddress& new_address) {
diff --git a/net/quic/core/quic_utils.h b/net/quic/core/quic_utils.h
index c32e865..fe504551 100644
--- a/net/quic/core/quic_utils.h
+++ b/net/quic/core/quic_utils.h
@@ -53,12 +53,6 @@
   // Returns PeerAddressChangeType as a std::string.
   static std::string PeerAddressChangeTypeToString(PeerAddressChangeType type);
 
-  // Returns a packed representation of |path_id| and |packet_number| in which
-  // the highest byte is set to |path_id| and the lower 7 bytes are the lower
-  // 7 bytes of |packet_number|.
-  static uint64_t PackPathIdAndPacketNumber(QuicPathId path_id,
-                                            QuicPacketNumber packet_number);
-
   // Determines and returns change type of address change from |old_address| to
   // |new_address|.
   static PeerAddressChangeType DetermineAddressChangeType(
diff --git a/net/quic/test_tools/mock_crypto_client_stream.cc b/net/quic/test_tools/mock_crypto_client_stream.cc
index 25ba8684..0197307 100644
--- a/net/quic/test_tools/mock_crypto_client_stream.cc
+++ b/net/quic/test_tools/mock_crypto_client_stream.cc
@@ -44,9 +44,8 @@
 
 void MockCryptoClientStream::CryptoConnect() {
   if (proof_verify_details_) {
-    bool unused = false;
     if (!proof_verify_details_->cert_verify_result.verified_cert
-             ->VerifyNameMatch(server_id_.host(), &unused)) {
+             ->VerifyNameMatch(server_id_.host(), false)) {
       handshake_confirmed_ = false;
       encryption_established_ = false;
       session()->connection()->CloseConnection(
diff --git a/net/quic/test_tools/quic_connection_peer.cc b/net/quic/test_tools/quic_connection_peer.cc
index 8c2e195..454bcb8 100644
--- a/net/quic/test_tools/quic_connection_peer.cc
+++ b/net/quic/test_tools/quic_connection_peer.cc
@@ -252,11 +252,16 @@
 // static
 bool QuicConnectionPeer::HasRetransmittableFrames(
     QuicConnection* connection,
-    QuicPathId path_id,
     QuicPacketNumber packet_number) {
   return QuicSentPacketManagerPeer::HasRetransmittableFrames(
       GetSentPacketManager(connection), packet_number);
 }
 
+// static
+void QuicConnectionPeer::SetNoStopWaitingFrames(QuicConnection* connection,
+                                                bool no_stop_waiting_frames) {
+  connection->no_stop_waiting_frames_ = no_stop_waiting_frames;
+}
+
 }  // namespace test
 }  // namespace net
diff --git a/net/quic/test_tools/quic_connection_peer.h b/net/quic/test_tools/quic_connection_peer.h
index 64e0685..347f21b 100644
--- a/net/quic/test_tools/quic_connection_peer.h
+++ b/net/quic/test_tools/quic_connection_peer.h
@@ -113,8 +113,9 @@
   static void SetAckDecimationDelay(QuicConnection* connection,
                                     float ack_decimation_delay);
   static bool HasRetransmittableFrames(QuicConnection* connection,
-                                       QuicPathId path_id,
                                        QuicPacketNumber packet_number);
+  static void SetNoStopWaitingFrames(QuicConnection* connection,
+                                     bool no_stop_waiting_frames);
 
  private:
   DISALLOW_COPY_AND_ASSIGN(QuicConnectionPeer);
diff --git a/net/quic/test_tools/quic_packet_creator_peer.cc b/net/quic/test_tools/quic_packet_creator_peer.cc
index 840eec8..e8788d6 100644
--- a/net/quic/test_tools/quic_packet_creator_peer.cc
+++ b/net/quic/test_tools/quic_packet_creator_peer.cc
@@ -82,10 +82,5 @@
   return creator->packet_.encryption_level;
 }
 
-// static
-QuicPathId QuicPacketCreatorPeer::GetCurrentPath(QuicPacketCreator* creator) {
-  return creator->packet_.path_id;
-}
-
 }  // namespace test
 }  // namespace net
diff --git a/net/quic/test_tools/quic_packet_creator_peer.h b/net/quic/test_tools/quic_packet_creator_peer.h
index 5c190918..c798cb1 100644
--- a/net/quic/test_tools/quic_packet_creator_peer.h
+++ b/net/quic/test_tools/quic_packet_creator_peer.h
@@ -40,7 +40,6 @@
                                              char* buffer,
                                              size_t buffer_len);
   static EncryptionLevel GetEncryptionLevel(QuicPacketCreator* creator);
-  static QuicPathId GetCurrentPath(QuicPacketCreator* creator);
 
  private:
   DISALLOW_COPY_AND_ASSIGN(QuicPacketCreatorPeer);
diff --git a/net/quic/test_tools/quic_stream_sequencer_buffer_peer.cc b/net/quic/test_tools/quic_stream_sequencer_buffer_peer.cc
index e7f38b2..a759104 100644
--- a/net/quic/test_tools/quic_stream_sequencer_buffer_peer.cc
+++ b/net/quic/test_tools/quic_stream_sequencer_buffer_peer.cc
@@ -42,8 +42,7 @@
 }
 
 bool QuicStreamSequencerBufferPeer::IsBlockArrayEmpty() {
-  if (FLAGS_quic_reloadable_flag_quic_reduce_sequencer_buffer_memory_life_time &&  // NOLINT
-      buffer_->blocks_ == nullptr) {
+  if (buffer_->blocks_ == nullptr) {
     return true;
   }
 
diff --git a/net/quic/test_tools/quic_test_utils.cc b/net/quic/test_tools/quic_test_utils.cc
index 6f9ab7e..7c9fb11 100644
--- a/net/quic/test_tools/quic_test_utils.cc
+++ b/net/quic/test_tools/quic_test_utils.cc
@@ -557,13 +557,11 @@
                                               bool version_flag,
                                               bool multipath_flag,
                                               bool reset_flag,
-                                              QuicPathId path_id,
                                               QuicPacketNumber packet_number,
                                               const string& data) {
-  return ConstructEncryptedPacket(connection_id, version_flag, multipath_flag,
-                                  reset_flag, path_id, packet_number, data,
-                                  PACKET_8BYTE_CONNECTION_ID,
-                                  PACKET_6BYTE_PACKET_NUMBER);
+  return ConstructEncryptedPacket(
+      connection_id, version_flag, multipath_flag, reset_flag, packet_number,
+      data, PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER);
 }
 
 QuicEncryptedPacket* ConstructEncryptedPacket(
@@ -571,14 +569,13 @@
     bool version_flag,
     bool multipath_flag,
     bool reset_flag,
-    QuicPathId path_id,
     QuicPacketNumber packet_number,
     const string& data,
     QuicConnectionIdLength connection_id_length,
     QuicPacketNumberLength packet_number_length) {
   return ConstructEncryptedPacket(
-      connection_id, version_flag, multipath_flag, reset_flag, path_id,
-      packet_number, data, connection_id_length, packet_number_length, nullptr);
+      connection_id, version_flag, multipath_flag, reset_flag, packet_number,
+      data, connection_id_length, packet_number_length, nullptr);
 }
 
 QuicEncryptedPacket* ConstructEncryptedPacket(
@@ -586,14 +583,13 @@
     bool version_flag,
     bool multipath_flag,
     bool reset_flag,
-    QuicPathId path_id,
     QuicPacketNumber packet_number,
     const string& data,
     QuicConnectionIdLength connection_id_length,
     QuicPacketNumberLength packet_number_length,
     QuicVersionVector* versions) {
   return ConstructEncryptedPacket(connection_id, version_flag, multipath_flag,
-                                  reset_flag, path_id, packet_number, data,
+                                  reset_flag, packet_number, data,
                                   connection_id_length, packet_number_length,
                                   versions, Perspective::IS_CLIENT);
 }
@@ -602,7 +598,6 @@
     bool version_flag,
     bool multipath_flag,
     bool reset_flag,
-    QuicPathId path_id,
     QuicPacketNumber packet_number,
     const string& data,
     QuicConnectionIdLength connection_id_length,
@@ -616,7 +611,6 @@
   header.public_header.multipath_flag = multipath_flag;
   header.public_header.reset_flag = reset_flag;
   header.public_header.packet_number_length = packet_number_length;
-  header.path_id = path_id;
   header.packet_number = packet_number;
   QuicStreamFrame stream_frame(1, false, 0, StringPiece(data));
   QuicFrame frame(&stream_frame);
@@ -649,7 +643,6 @@
     QuicConnectionId connection_id,
     bool version_flag,
     bool reset_flag,
-    QuicPathId path_id,
     QuicPacketNumber packet_number,
     const string& data,
     QuicConnectionIdLength connection_id_length,
@@ -662,7 +655,6 @@
   header.public_header.version_flag = version_flag;
   header.public_header.reset_flag = reset_flag;
   header.public_header.packet_number_length = packet_number_length;
-  header.path_id = path_id;
   header.packet_number = packet_number;
   QuicStreamFrame stream_frame(1, false, 0, StringPiece(data));
   QuicFrame frame(&stream_frame);
diff --git a/net/quic/test_tools/quic_test_utils.h b/net/quic/test_tools/quic_test_utils.h
index 5b53b4a6..d404341 100644
--- a/net/quic/test_tools/quic_test_utils.h
+++ b/net/quic/test_tools/quic_test_utils.h
@@ -74,7 +74,6 @@
     bool version_flag,
     bool multipath_flag,
     bool reset_flag,
-    QuicPathId path_id,
     QuicPacketNumber packet_number,
     const std::string& data,
     QuicConnectionIdLength connection_id_length,
@@ -91,7 +90,6 @@
     bool version_flag,
     bool multipath_flag,
     bool reset_flag,
-    QuicPathId path_id,
     QuicPacketNumber packet_number,
     const std::string& data,
     QuicConnectionIdLength connection_id_length,
@@ -104,7 +102,6 @@
     bool version_flag,
     bool multipath_flag,
     bool reset_flag,
-    QuicPathId path_id,
     QuicPacketNumber packet_number,
     const std::string& data,
     QuicConnectionIdLength connection_id_length,
@@ -117,7 +114,6 @@
                                               bool version_flag,
                                               bool multipath_flag,
                                               bool reset_flag,
-                                              QuicPathId path_id,
                                               QuicPacketNumber packet_number,
                                               const std::string& data);
 
@@ -136,7 +132,6 @@
     QuicConnectionId connection_id,
     bool version_flag,
     bool reset_flag,
-    QuicPathId path_id,
     QuicPacketNumber packet_number,
     const std::string& data,
     QuicConnectionIdLength connection_id_length,
diff --git a/net/spdy/spdy_header_block.cc b/net/spdy/spdy_header_block.cc
index 2683a1ca..d3d1fe2 100644
--- a/net/spdy/spdy_header_block.cc
+++ b/net/spdy/spdy_header_block.cc
@@ -343,7 +343,7 @@
        it != headers->end(); ++it) {
     headers_dict->SetWithoutPathExpansion(
         it->first.as_string(),
-        new base::StringValue(ElideHeaderValueForNetLog(
+        new base::Value(ElideHeaderValueForNetLog(
             capture_mode, it->first.as_string(), it->second.as_string())));
   }
   dict->Set("headers", headers_dict);
diff --git a/net/spdy/spdy_network_transaction_unittest.cc b/net/spdy/spdy_network_transaction_unittest.cc
index e856c55d..785319e 100644
--- a/net/spdy/spdy_network_transaction_unittest.cc
+++ b/net/spdy/spdy_network_transaction_unittest.cc
@@ -3578,7 +3578,7 @@
   for (std::vector<std::string>::const_iterator it = expected.begin();
        it != expected.end();
        ++it) {
-    base::StringValue header(*it);
+    base::Value header(*it);
     EXPECT_NE(header_list->end(), header_list->Find(header)) <<
         "Header not found: " << *it;
   }
diff --git a/net/spdy/spdy_session.cc b/net/spdy/spdy_session.cc
index 0173abd..220a5001 100644
--- a/net/spdy/spdy_session.cc
+++ b/net/spdy/spdy_session.cc
@@ -695,8 +695,7 @@
     return false;
   }
 
-  bool unused = false;
-  if (!ssl_info.cert->VerifyNameMatch(new_hostname, &unused))
+  if (!ssl_info.cert->VerifyNameMatch(new_hostname, false))
     return false;
 
   std::string pinning_failure_log;
diff --git a/net/ssl/ssl_config.cc b/net/ssl/ssl_config.cc
index 62e192e1..726ce48 100644
--- a/net/ssl/ssl_config.cc
+++ b/net/ssl/ssl_config.cc
@@ -24,6 +24,7 @@
     : rev_checking_enabled(false),
       rev_checking_required_local_anchors(false),
       sha1_local_anchors_enabled(true),
+      common_name_fallback_local_anchors_enabled(true),
       version_min(kDefaultSSLVersionMin),
       version_max(kDefaultSSLVersionMax),
       deprecated_cipher_suites_enabled(false),
@@ -64,6 +65,8 @@
     flags |= CertVerifier::VERIFY_REV_CHECKING_REQUIRED_LOCAL_ANCHORS;
   if (sha1_local_anchors_enabled)
     flags |= CertVerifier::VERIFY_ENABLE_SHA1_LOCAL_ANCHORS;
+  if (common_name_fallback_local_anchors_enabled)
+    flags |= CertVerifier::VERIFY_ENABLE_COMMON_NAME_FALLBACK_LOCAL_ANCHORS;
   return flags;
 }
 
diff --git a/net/ssl/ssl_config.h b/net/ssl/ssl_config.h
index 1188a0d..7e6283d 100644
--- a/net/ssl/ssl_config.h
+++ b/net/ssl/ssl_config.h
@@ -78,6 +78,12 @@
   // local (non-public) trust anchor should be allowed.
   bool sha1_local_anchors_enabled;
 
+  // common_name_fallback_local_anchors_enabled is true if certificates which
+  // only have a commonName in the Subject (i.e. lacking a subjectAltName)
+  // should be checked if the name matches. Only those issued by a local
+  // (non-public) trust anchor will be allowed to match.
+  bool common_name_fallback_local_anchors_enabled;
+
   // The minimum and maximum protocol versions that are enabled.
   // (Use the SSL_PROTOCOL_VERSION_xxx enumerators defined above.)
   // SSL 2.0 and SSL 3.0 are not supported. If version_max < version_min, it
diff --git a/net/ssl/ssl_config_service.cc b/net/ssl/ssl_config_service.cc
index 2b4388ef..6afef76e 100644
--- a/net/ssl/ssl_config_service.cc
+++ b/net/ssl/ssl_config_service.cc
@@ -83,21 +83,23 @@
 SSLConfigService::~SSLConfigService() {
 }
 
-void SSLConfigService::ProcessConfigUpdate(const SSLConfig& orig_config,
+void SSLConfigService::ProcessConfigUpdate(const SSLConfig& old_config,
                                            const SSLConfig& new_config) {
   bool config_changed =
-      std::tie(orig_config.rev_checking_enabled,
-               orig_config.rev_checking_required_local_anchors,
-               orig_config.sha1_local_anchors_enabled, orig_config.version_min,
-               orig_config.version_max, orig_config.disabled_cipher_suites,
-               orig_config.channel_id_enabled, orig_config.false_start_enabled,
-               orig_config.require_ecdhe) !=
+      std::tie(old_config.rev_checking_enabled,
+               old_config.rev_checking_required_local_anchors,
+               old_config.sha1_local_anchors_enabled,
+               old_config.common_name_fallback_local_anchors_enabled,
+               old_config.version_min, old_config.version_max,
+               old_config.disabled_cipher_suites, old_config.channel_id_enabled,
+               old_config.false_start_enabled, old_config.require_ecdhe) !=
       std::tie(new_config.rev_checking_enabled,
                new_config.rev_checking_required_local_anchors,
-               new_config.sha1_local_anchors_enabled, new_config.version_min,
-               new_config.version_max, new_config.disabled_cipher_suites,
-               new_config.channel_id_enabled, new_config.false_start_enabled,
-               new_config.require_ecdhe);
+               new_config.sha1_local_anchors_enabled,
+               new_config.common_name_fallback_local_anchors_enabled,
+               new_config.version_min, new_config.version_max,
+               new_config.disabled_cipher_suites, new_config.channel_id_enabled,
+               new_config.false_start_enabled, new_config.require_ecdhe);
 
   if (config_changed)
     NotifySSLConfigChange();
diff --git a/net/ssl/ssl_config_service_unittest.cc b/net/ssl/ssl_config_service_unittest.cc
index 72041ff..a4d4f9f6a 100644
--- a/net/ssl/ssl_config_service_unittest.cc
+++ b/net/ssl/ssl_config_service_unittest.cc
@@ -67,6 +67,7 @@
   initial_config.rev_checking_enabled = true;
   initial_config.rev_checking_required_local_anchors = false;
   initial_config.sha1_local_anchors_enabled = true;
+  initial_config.common_name_fallback_local_anchors_enabled = true;
   initial_config.false_start_enabled = false;
   initial_config.require_ecdhe = false;
   initial_config.version_min = SSL_PROTOCOL_VERSION_TLS1;
@@ -90,6 +91,10 @@
   EXPECT_CALL(observer, OnSSLConfigChanged()).Times(1);
   mock_service->SetSSLConfig(initial_config);
 
+  initial_config.common_name_fallback_local_anchors_enabled = false;
+  EXPECT_CALL(observer, OnSSLConfigChanged()).Times(1);
+  mock_service->SetSSLConfig(initial_config);
+
   initial_config.false_start_enabled = true;
   EXPECT_CALL(observer, OnSSLConfigChanged()).Times(1);
   mock_service->SetSSLConfig(initial_config);
diff --git a/net/test/spawned_test_server/base_test_server.cc b/net/test/spawned_test_server/base_test_server.cc
index c3ffc07b..afc77f3 100644
--- a/net/test/spawned_test_server/base_test_server.cc
+++ b/net/test/spawned_test_server/base_test_server.cc
@@ -84,18 +84,18 @@
     values->AppendString("aes128gcm");
 }
 
-base::StringValue* GetTLSIntoleranceType(
+base::Value* GetTLSIntoleranceType(
     BaseTestServer::SSLOptions::TLSIntoleranceType type) {
   switch (type) {
     case BaseTestServer::SSLOptions::TLS_INTOLERANCE_ALERT:
-      return new base::StringValue("alert");
+      return new base::Value("alert");
     case BaseTestServer::SSLOptions::TLS_INTOLERANCE_CLOSE:
-      return new base::StringValue("close");
+      return new base::Value("close");
     case BaseTestServer::SSLOptions::TLS_INTOLERANCE_RESET:
-      return new base::StringValue("reset");
+      return new base::Value("reset");
     default:
       NOTREACHED();
-      return new base::StringValue("");
+      return new base::Value("");
   }
 }
 
diff --git a/net/tools/quic/end_to_end_test.cc b/net/tools/quic/end_to_end_test.cc
index 93ed695..6f12b97 100644
--- a/net/tools/quic/end_to_end_test.cc
+++ b/net/tools/quic/end_to_end_test.cc
@@ -598,20 +598,16 @@
   QuicCryptoStream* crypto_stream =
       QuicSessionPeer::GetCryptoStream(client_->client()->session());
   QuicStreamSequencer* sequencer = QuicStreamPeer::sequencer(crypto_stream);
-  EXPECT_NE(
-      FLAGS_quic_reloadable_flag_quic_release_crypto_stream_buffer &&
-          FLAGS_quic_reloadable_flag_quic_reduce_sequencer_buffer_memory_life_time,  // NOLINT
-      QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer));
+  EXPECT_NE(FLAGS_quic_reloadable_flag_quic_release_crypto_stream_buffer,
+            QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer));
   server_thread_->Pause();
   QuicDispatcher* dispatcher =
       QuicServerPeer::GetDispatcher(server_thread_->server());
   QuicSession* server_session = dispatcher->session_map().begin()->second.get();
   crypto_stream = QuicSessionPeer::GetCryptoStream(server_session);
   sequencer = QuicStreamPeer::sequencer(crypto_stream);
-  EXPECT_NE(
-      FLAGS_quic_reloadable_flag_quic_release_crypto_stream_buffer &&
-          FLAGS_quic_reloadable_flag_quic_reduce_sequencer_buffer_memory_life_time,  // NOLINT
-      QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer));
+  EXPECT_NE(FLAGS_quic_reloadable_flag_quic_release_crypto_stream_buffer,
+            QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer));
 }
 
 TEST_P(EndToEndTest, SimpleRequestResponsev6) {
@@ -2213,8 +2209,8 @@
 
   std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
       client_->client()->session()->connection()->connection_id(), false, false,
-      false, kDefaultPathId, 1, "At least 20 characters.",
-      PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER));
+      false, 1, "At least 20 characters.", PACKET_8BYTE_CONNECTION_ID,
+      PACKET_6BYTE_PACKET_NUMBER));
   // Damage the encrypted data.
   string damaged_packet(packet->data(), packet->length());
   damaged_packet[30] ^= 0x01;
@@ -2709,10 +2705,7 @@
     QUIC_DVLOG(1) << "response body " << response_body;
     EXPECT_EQ(expected_body, response_body);
   }
-  EXPECT_NE(
-      FLAGS_quic_reloadable_flag_quic_headers_stream_release_sequencer_buffer &&
-          FLAGS_quic_reloadable_flag_quic_reduce_sequencer_buffer_memory_life_time,  // NOLINT
-      QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer));
+  EXPECT_FALSE(QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer));
 }
 
 TEST_P(EndToEndTestServerPush, ServerPushUnderLimit) {
@@ -3017,10 +3010,7 @@
   QuicHeadersStream* headers_stream =
       QuicSpdySessionPeer::GetHeadersStream(client_->client()->session());
   QuicStreamSequencer* sequencer = QuicStreamPeer::sequencer(headers_stream);
-  EXPECT_NE(
-      FLAGS_quic_reloadable_flag_quic_headers_stream_release_sequencer_buffer &&
-          FLAGS_quic_reloadable_flag_quic_reduce_sequencer_buffer_memory_life_time,  // NOLINT
-      QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer));
+  EXPECT_FALSE(QuicStreamSequencerPeer::IsUnderlyingBufferAllocated(sequencer));
 }
 
 class EndToEndBufferedPacketsTest : public EndToEndTest {
diff --git a/net/tools/quic/quic_client_session_test.cc b/net/tools/quic/quic_client_session_test.cc
index b0cbb52..1ed9bd9b 100644
--- a/net/tools/quic/quic_client_session_test.cc
+++ b/net/tools/quic/quic_client_session_test.cc
@@ -267,7 +267,7 @@
   // Verify that a non-decryptable packet doesn't close the connection.
   QuicConnectionId connection_id = session_->connection()->connection_id();
   std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
-      connection_id, false, false, false, kDefaultPathId, 100, "data",
+      connection_id, false, false, false, 100, "data",
       PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, nullptr,
       Perspective::IS_SERVER));
   std::unique_ptr<QuicReceivedPacket> received(
@@ -293,9 +293,8 @@
   QuicConnectionId connection_id = session_->connection()->connection_id();
   QuicVersionVector versions = {GetParam()};
   std::unique_ptr<QuicEncryptedPacket> packet(ConstructMisFramedEncryptedPacket(
-      connection_id, false, false, kDefaultPathId, 100, "data",
-      PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, &versions,
-      Perspective::IS_SERVER));
+      connection_id, false, false, 100, "data", PACKET_8BYTE_CONNECTION_ID,
+      PACKET_6BYTE_PACKET_NUMBER, &versions, Perspective::IS_SERVER));
   std::unique_ptr<QuicReceivedPacket> received(
       ConstructReceivedPacket(*packet, QuicTime::Zero()));
   EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(1);
diff --git a/net/tools/quic/quic_dispatcher_test.cc b/net/tools/quic/quic_dispatcher_test.cc
index 8470575..7aab02f 100644
--- a/net/tools/quic/quic_dispatcher_test.cc
+++ b/net/tools/quic/quic_dispatcher_test.cc
@@ -227,7 +227,7 @@
                      QuicPacketNumberLength packet_number_length) {
     ProcessPacket(client_address, connection_id, has_version_flag,
                   has_multipath_flag, data, connection_id_length,
-                  packet_number_length, kDefaultPathId, 1);
+                  packet_number_length, 1);
   }
 
   // Process a packet using the first supported version.
@@ -238,7 +238,6 @@
                      const string& data,
                      QuicConnectionIdLength connection_id_length,
                      QuicPacketNumberLength packet_number_length,
-                     QuicPathId path_id,
                      QuicPacketNumber packet_number) {
     ProcessPacket(client_address, connection_id, has_version_flag,
                   CurrentSupportedVersions().front(), data,
@@ -256,7 +255,7 @@
                      QuicPacketNumber packet_number) {
     QuicVersionVector versions(SupportedVersions(version));
     std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
-        connection_id, has_version_flag, false, false, 0, packet_number, data,
+        connection_id, has_version_flag, false, false, packet_number, data,
         connection_id_length, packet_number_length, &versions));
     std::unique_ptr<QuicReceivedPacket> received_packet(
         ConstructReceivedPacket(*packet, helper_.GetClock()->Now()));
@@ -505,7 +504,6 @@
   // connection.
   ProcessPacket(client_address, connection_id, true, false, SerializeCHLO(),
                 PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER,
-                kDefaultPathId,
                 QuicDispatcher::kMaxReasonableInitialPacketNumber);
   EXPECT_EQ(client_address, dispatcher_->current_client_address());
   EXPECT_EQ(server_address_, dispatcher_->current_server_address());
@@ -528,7 +526,6 @@
   // connection.
   ProcessPacket(client_address, connection_id, true, false, SerializeCHLO(),
                 PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER,
-                kDefaultPathId,
                 QuicDispatcher::kMaxReasonableInitialPacketNumber + 1);
 }
 
@@ -1201,8 +1198,7 @@
   for (size_t i = 1; i <= kDefaultMaxUndecryptablePackets + 1; ++i) {
     ProcessPacket(client_address, conn_id, true, false,
                   QuicStrCat("data packet ", i + 1), PACKET_8BYTE_CONNECTION_ID,
-                  PACKET_6BYTE_PACKET_NUMBER, kDefaultPathId,
-                  /*packet_number=*/i + 1);
+                  PACKET_6BYTE_PACKET_NUMBER, /*packet_number=*/i + 1);
   }
   EXPECT_EQ(0u, dispatcher_->session_map().size())
       << "No session should be created before CHLO arrives.";
@@ -1256,7 +1252,6 @@
     ProcessPacket(client_address, conn_id, true, false,
                   QuicStrCat("data packet on connection ", i),
                   PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER,
-                  kDefaultPathId,
                   /*packet_number=*/2);
   }
 
@@ -1331,8 +1326,7 @@
   QuicConnectionId conn_id = 1;
   ProcessPacket(client_address, conn_id, true, false,
                 QuicStrCat("data packet ", 2), PACKET_8BYTE_CONNECTION_ID,
-                PACKET_6BYTE_PACKET_NUMBER, kDefaultPathId,
-                /*packet_number=*/2);
+                PACKET_6BYTE_PACKET_NUMBER, /*packet_number=*/2);
 
   // When CHLO arrives, a new session should be created, and all packets
   // buffered should be delivered to the session.
@@ -1366,8 +1360,7 @@
   QuicConnectionId conn_id = 1;
   ProcessPacket(client_address, conn_id, true, false,
                 QuicStrCat("data packet ", 2), PACKET_8BYTE_CONNECTION_ID,
-                PACKET_6BYTE_PACKET_NUMBER, kDefaultPathId,
-                /*packet_number=*/2);
+                PACKET_6BYTE_PACKET_NUMBER, /*packet_number=*/2);
 
   mock_helper_.AdvanceTime(
       QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs));
@@ -1561,7 +1554,6 @@
   QuicConnectionId conn_id = 1;
   ProcessPacket(client_addr_, conn_id, true, false, "data packet",
                 PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER,
-                kDefaultPathId,
                 /*packet_number=*/1);
   // Fill packet buffer to full with CHLOs on other connections. Need to feed
   // extra CHLOs because the first |kMaxNumSessionsToCreate| are going to create
diff --git a/net/tools/quic/quic_packet_writer_wrapper.h b/net/tools/quic/quic_packet_writer_wrapper.h
index 4fc75c6..50cc547 100644
--- a/net/tools/quic/quic_packet_writer_wrapper.h
+++ b/net/tools/quic/quic_packet_writer_wrapper.h
@@ -38,6 +38,8 @@
   // Takes ownership of |writer|.
   void set_writer(QuicPacketWriter* writer);
 
+  virtual void set_peer_address(const QuicSocketAddress& peer_address) {}
+
  private:
   std::unique_ptr<QuicPacketWriter> writer_;
 
diff --git a/net/tools/quic/quic_spdy_client_stream.cc b/net/tools/quic/quic_spdy_client_stream.cc
index 47097a6..132720c 100644
--- a/net/tools/quic/quic_spdy_client_stream.cc
+++ b/net/tools/quic/quic_spdy_client_stream.cc
@@ -62,8 +62,7 @@
     return;
   }
 
-  if (FLAGS_quic_restart_flag_quic_supports_100_continue &&
-      response_code_ == 100 && !has_preliminary_headers_) {
+  if (response_code_ == 100 && !has_preliminary_headers_) {
     // These are preliminary 100 Continue headers, not the actual response
     // headers.
     set_headers_decompressed(false);
diff --git a/net/tools/quic/quic_spdy_client_stream_test.cc b/net/tools/quic/quic_spdy_client_stream_test.cc
index 915d539..8ac3680 100644
--- a/net/tools/quic/quic_spdy_client_stream_test.cc
+++ b/net/tools/quic/quic_spdy_client_stream_test.cc
@@ -111,7 +111,6 @@
 
 TEST_F(QuicSpdyClientStreamTest, TestFraming100Continue) {
   headers_[":status"] = "100";
-  FLAGS_quic_restart_flag_quic_supports_100_continue = true;
   auto headers = AsHeaderList(headers_);
   stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
                               headers);
@@ -123,20 +122,6 @@
   EXPECT_EQ("", stream_->data());
 }
 
-TEST_F(QuicSpdyClientStreamTest, TestFraming100ContinueNoFlag) {
-  headers_[":status"] = "100";
-  FLAGS_quic_restart_flag_quic_supports_100_continue = false;
-  auto headers = AsHeaderList(headers_);
-  stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
-                              headers);
-  stream_->OnStreamFrame(
-      QuicStreamFrame(stream_->id(), /*fin=*/false, /*offset=*/0, body_));
-  EXPECT_EQ(0u, stream_->preliminary_headers().size());
-  EXPECT_EQ("100", stream_->response_headers().find(":status")->second);
-  EXPECT_EQ(100, stream_->response_code());
-  EXPECT_EQ(body_, stream_->data());
-}
-
 TEST_F(QuicSpdyClientStreamTest, TestFramingOnePacket) {
   auto headers = AsHeaderList(headers_);
   stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(),
diff --git a/net/tools/quic/quic_time_wait_list_manager.cc b/net/tools/quic/quic_time_wait_list_manager.cc
index da49cfc3..1b6039a 100644
--- a/net/tools/quic/quic_time_wait_list_manager.cc
+++ b/net/tools/quic/quic_time_wait_list_manager.cc
@@ -15,7 +15,6 @@
 #include "net/quic/core/quic_flags.h"
 #include "net/quic/core/quic_framer.h"
 #include "net/quic/core/quic_packets.h"
-#include "net/quic/core/quic_server_session_base.h"
 #include "net/quic/core/quic_utils.h"
 #include "net/quic/platform/api/quic_clock.h"
 #include "net/quic/platform/api/quic_logging.h"
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 a870e30..78fb04d 100644
--- a/net/tools/quic/quic_time_wait_list_manager_test.cc
+++ b/net/tools/quic/quic_time_wait_list_manager_test.cc
@@ -125,8 +125,7 @@
       QuicConnectionId connection_id,
       QuicPacketNumber packet_number) {
     return net::test::ConstructEncryptedPacket(connection_id, false, false,
-                                               false, kDefaultPathId,
-                                               packet_number, "data");
+                                               false, packet_number, "data");
   }
 
   QuicFlagSaver flags_;  // Save/restore all QUIC flag values.
diff --git a/net/tools/quic/test_tools/quic_test_client.cc b/net/tools/quic/test_tools/quic_test_client.cc
index 56fe712..1aa3a82 100644
--- a/net/tools/quic/test_tools/quic_test_client.cc
+++ b/net/tools/quic/test_tools/quic_test_client.cc
@@ -194,6 +194,11 @@
   override_connection_id_ = connection_id;
 }
 
+void MockableQuicClient::set_peer_address(const QuicSocketAddress& address) {
+  CHECK(test_writer_ != nullptr);
+  test_writer_->set_peer_address(address);
+}
+
 QuicTestClient::QuicTestClient(QuicSocketAddress server_address,
                                const string& server_hostname,
                                const QuicVersionVector& supported_versions)
diff --git a/net/tools/quic/test_tools/quic_test_client.h b/net/tools/quic/test_tools/quic_test_client.h
index 9066b59..90610228 100644
--- a/net/tools/quic/test_tools/quic_test_client.h
+++ b/net/tools/quic/test_tools/quic_test_client.h
@@ -63,6 +63,7 @@
   void set_track_last_incoming_packet(bool track) {
     track_last_incoming_packet_ = track;
   }
+  void set_peer_address(const QuicSocketAddress& address);
 
  private:
   QuicConnectionId override_connection_id_;  // ConnectionId to use, if nonzero
@@ -247,6 +248,10 @@
     client_->set_server_address(server_address);
   }
 
+  void set_peer_address(const QuicSocketAddress& address) {
+    client_->set_peer_address(address);
+  }
+
   // Explicitly set the SNI value for this client, overriding the default
   // behavior which extracts the SNI value from the request URL.
   void OverrideSni(const std::string& sni) {
diff --git a/net/tools/testserver/minica.py b/net/tools/testserver/minica.py
index 3395daf9..62991ffb 100644
--- a/net/tools/testserver/minica.py
+++ b/net/tools/testserver/minica.py
@@ -216,11 +216,12 @@
 ORGANIZATION = asn1.OID([2, 5, 4, 10])
 PUBLIC_KEY_RSA = asn1.OID([1, 2, 840, 113549, 1, 1, 1])
 SHA256_WITH_RSA_ENCRYPTION = asn1.OID([1, 2, 840, 113549, 1, 1, 11])
-
+SUBJECT_ALTERNATIVE_NAME = asn1.OID([2, 5, 29, 17])
 
 def MakeCertificate(
     issuer_cn, subject_cn, serial, pubkey, privkey, ocsp_url = None,
-    ca_issuers_url = None, is_ca=False, path_len=None):
+    ca_issuers_url = None, is_ca=False, path_len=None, ip_sans=None,
+    dns_sans=None):
   '''MakeCertificate returns a DER encoded certificate, signed by privkey.'''
   extensions = asn1.SEQUENCE([])
 
@@ -242,6 +243,24 @@
         ))),
       ]))
 
+  if ip_sans is not None or dns_sans is not None:
+    sans = []
+    if dns_sans is not None:
+      for dns_name in dns_sans:
+        sans.append(
+          asn1.Raw(asn1.TagAndLength(0x82, len(dns_name)) + dns_name))
+    if ip_sans is not None:
+      for ip_addr in ip_sans:
+        sans.append(
+          asn1.Raw(asn1.TagAndLength(0x87, len(ip_addr)) + ip_addr))
+    extensions.children.append(
+      asn1.SEQUENCE([
+        SUBJECT_ALTERNATIVE_NAME,
+        # There is implicitly a critical=False here. Since false is the
+        # default, encoding the value would be invalid DER.
+        asn1.OCTETSTRING(asn1.ToDER(asn1.SEQUENCE(sans)))
+      ]))
+
   if ocsp_url is not None or ca_issuers_url is not None:
     aia_entries = []
     if ocsp_url is not None:
@@ -426,6 +445,8 @@
                            ocsp_states = None,
                            ocsp_dates = None,
                            ocsp_produced = OCSP_PRODUCED_VALID,
+                           ip_sans = ["\x7F\x00\x00\x01"],
+                           dns_sans = None,
                            serial = 0):
   '''GenerateCertKeyAndOCSP returns a (cert_and_key_pem, ocsp_der) where:
        * cert_and_key_pem contains a certificate and private key in PEM format
@@ -441,7 +462,8 @@
   if serial == 0:
     serial = RandomNumber(16)
   cert_der = MakeCertificate(ROOT_CN, bytes(subject), serial, LEAF_KEY,
-                             ROOT_KEY, bytes(ocsp_url))
+                             ROOT_KEY, bytes(ocsp_url), ip_sans=ip_sans,
+                             dns_sans=dns_sans)
   cert_pem = DERToPEM(cert_der)
 
   ocsp_der = None
diff --git a/remoting/protocol/connection_unittest.cc b/remoting/protocol/connection_unittest.cc
index 1794f2fd..c3527831 100644
--- a/remoting/protocol/connection_unittest.cc
+++ b/remoting/protocol/connection_unittest.cc
@@ -635,6 +635,8 @@
   client_audio_player_.Verify();
 }
 
+#if !defined(MEMORY_SANITIZER)
+// Test fails under msan, https://crbug.com/697178
 TEST_P(ConnectionTest, FirstCaptureFailed) {
   Connect();
 
@@ -667,6 +669,7 @@
     EXPECT_EQ(event_timestamp, stats.host_stats.latest_event_timestamp);
   }
 }
+#endif
 
 TEST_P(ConnectionTest, SecondCaptureFailed) {
   Connect();
diff --git a/remoting/test/chromoting_test_driver.cc b/remoting/test/chromoting_test_driver.cc
index 1e7d73e..b75ce58 100644
--- a/remoting/test/chromoting_test_driver.cc
+++ b/remoting/test/chromoting_test_driver.cc
@@ -27,6 +27,7 @@
 const char kPinSwitchName[] = "pin";
 const char kRefreshTokenPathSwitchName[] = "refresh-token-path";
 const char kSingleProcessTestsSwitchName[] = "single-process-tests";
+const char kShowHostListSwitchName[] = "show-host-list";
 const char kTestEnvironmentSwitchName[] = "use-test-env";
 const char kUserNameSwitchName[] = "username";
 }
@@ -68,6 +69,10 @@
          switches::kUserNameSwitchName);
   printf("  %s: Specifies which host to connect to when running tests\n",
          switches::kHostNameSwitchName);
+  printf(
+      "  %s: Retrieves and displays the connection status for all known "
+      "hosts, no tests will be run\n",
+      switches::kShowHostListSwitchName);
   printf("\nOptional Parameters:\n");
   printf("  %s: Exchanged for a refresh and access token for authentication\n",
          switches::kAuthCodeSwitchName);
@@ -220,11 +225,14 @@
   options.host_name =
       command_line->GetSwitchValueASCII(switches::kHostNameSwitchName);
 
-  if (options.host_name.empty()) {
+  if (!options.host_name.empty()) {
+    VLOG(1) << "host_name: '" << options.host_name << "'";
+  } else if (command_line->HasSwitch(switches::kShowHostListSwitchName)) {
+    options.host_name = "unspecified";
+  } else {
     LOG(ERROR) << "No hostname passed in, connect to host requires hostname!";
     return -1;
   }
-  VLOG(1) << "host_name: '" << options.host_name << "'";
 
   options.host_jid =
       command_line->GetSwitchValueASCII(switches::kHostJidSwitchName);
@@ -247,14 +255,25 @@
     return -1;
   }
 
+  if (command_line->HasSwitch(switches::kShowHostListSwitchName)) {
+    // When this flag is specified, we will show the host list and exit.
+    shared_data->RefreshHostList();
+    shared_data->DisplayHostList();
+    return 0;
+  }
+
   // This method is necessary as there are occasional propagation delays in the
   // backend and we don't want the test to fail because of that.
-  if (!shared_data->WaitForHostOnline(options.host_jid, options.host_name)) {
+  if (!shared_data->WaitForHostOnline()) {
     VLOG(1) << "The expected host was not available for connections.";
     // Host is not online. No point running further tests.
     return -1;
   }
 
+  if (options.pin.empty()) {
+    LOG(WARNING) << "No PIN specified, tests may not run reliably.";
+  }
+
   // Since we've successfully set up our shared_data object, we'll assign the
   // value to our global* and transfer ownership to the framework.
   remoting::test::g_chromoting_shared_data = shared_data.release();
diff --git a/remoting/test/chromoting_test_driver_environment.cc b/remoting/test/chromoting_test_driver_environment.cc
index 356e901..2cb53d7 100644
--- a/remoting/test/chromoting_test_driver_environment.cc
+++ b/remoting/test/chromoting_test_driver_environment.cc
@@ -86,12 +86,10 @@
 }
 
 void ChromotingTestDriverEnvironment::DisplayHostList() {
-  const char kHostAvailabilityFormatString[] = "%-45s%-15s%-35s";
+  const char kHostAvailabilityFormatString[] = "%-25s%-15s%-35s\n";
 
-  LOG(INFO) << base::StringPrintf(kHostAvailabilityFormatString,
-                                  "Host Name", "Host Status", "Host JID");
-  LOG(INFO) << base::StringPrintf(kHostAvailabilityFormatString,
-                                  "---------", "-----------", "--------");
+  printf(kHostAvailabilityFormatString, "Host Name", "Host Status", "Host JID");
+  printf(kHostAvailabilityFormatString, "---------", "-----------", "--------");
 
   std::string status;
   for (const HostInfo& host_info : host_list_) {
@@ -104,31 +102,34 @@
       status = "UNKNOWN";
     }
 
-    LOG(INFO) << base::StringPrintf(
-        kHostAvailabilityFormatString, host_info.host_name.c_str(),
-        status.c_str(), host_info.host_jid.c_str());
+    printf(kHostAvailabilityFormatString, host_info.host_name.c_str(),
+           status.c_str(), host_info.host_jid.c_str());
   }
 }
 
-bool ChromotingTestDriverEnvironment::WaitForHostOnline(
-    const std::string& host_jid,
-    const std::string& host_name) {
+bool ChromotingTestDriverEnvironment::WaitForHostOnline() {
   if (host_list_.empty()) {
     RetrieveHostList();
   }
 
+  DisplayHostList();
+
   // Refresh the |host_list_| periodically to check if expected JID is online.
   const base::TimeDelta kTotalTimeInSeconds = base::TimeDelta::FromSeconds(60);
   const base::TimeDelta kSleepTimeInSeconds = base::TimeDelta::FromSeconds(5);
   const int kMaxIterations = kTotalTimeInSeconds / kSleepTimeInSeconds;
 
-  int num_iterations = 0;
-  while (num_iterations < kMaxIterations) {
+  for (int iterations = 0; iterations < kMaxIterations; iterations++) {
+    if (!FindHostInHostList()) {
+      LOG(WARNING) << "Host '" << host_name_ << "' with JID '" << host_jid_
+                   << "' not found in host list.";
+      return false;
+    }
+
     if (host_info_.IsReadyForConnection()) {
-      if (num_iterations > 0) {
+      if (iterations > 0) {
         VLOG(0) << "Host online after: "
-                << num_iterations * kSleepTimeInSeconds.InSeconds()
-                << " seconds.";
+                << iterations * kSleepTimeInSeconds.InSeconds() << " seconds.";
       }
       return true;
     }
@@ -136,14 +137,31 @@
     // Wait a while before refreshing host list.
     base::PlatformThread::Sleep(kSleepTimeInSeconds);
     RefreshHostList();
-    ++num_iterations;
   }
 
-  LOG(ERROR) << "Host with JID '" << host_jid << "' still not online after "
-             << num_iterations * kSleepTimeInSeconds.InSeconds() << " seconds.";
+  LOG(ERROR) << "Host '" << host_name_ << "' with JID '" << host_jid_
+             << "' still not online after "
+             << kMaxIterations * kSleepTimeInSeconds.InSeconds() << " seconds.";
   return false;
 }
 
+bool ChromotingTestDriverEnvironment::FindHostInHostList() {
+  bool host_found = false;
+  for (HostInfo& host_info : host_list_) {
+    // The JID is optional so we consider an empty string to be a '*' match.
+    bool host_jid_match =
+        host_jid_.empty() || (host_jid_ == host_info.host_jid);
+    bool host_name_match = host_name_ == host_info.host_name;
+
+    if (host_name_match && host_jid_match) {
+      host_info_ = host_info;
+      host_found = true;
+      break;
+    }
+  }
+  return host_found;
+}
+
 void ChromotingTestDriverEnvironment::SetAccessTokenFetcherForTest(
     AccessTokenFetcher* access_token_fetcher) {
   DCHECK(access_token_fetcher);
@@ -306,28 +324,7 @@
     return false;
   }
 
-  DisplayHostList();
-  for (HostInfo& host_info : host_list_) {
-    // The JID is optional so we consider an empty string to be a '*' match.
-    bool host_jid_match =
-        host_jid_.empty() || (host_jid_ == host_info.host_jid);
-    bool host_name_match = host_name_ == host_info.host_name;
-
-    if (host_name_match && host_jid_match) {
-      host_info_ = host_info;
-
-      if (host_info.IsReadyForConnection()) {
-        return true;
-      } else {
-        LOG(WARNING) << "Host '" << host_name_ << "' with JID '" << host_jid_
-                     << "' not online.";
-        return false;
-      }
-    }
-  }
-  LOG(WARNING) << "Host '" << host_name_ << "' with JID '" << host_jid_
-               << "' not found in host list.";
-  return false;
+  return true;
 }
 
 void ChromotingTestDriverEnvironment::OnHostListRetrieved(
diff --git a/remoting/test/chromoting_test_driver_environment.h b/remoting/test/chromoting_test_driver_environment.h
index df2cb21e..90d1134 100644
--- a/remoting/test/chromoting_test_driver_environment.h
+++ b/remoting/test/chromoting_test_driver_environment.h
@@ -49,14 +49,16 @@
   // Returns false if a valid access token cannot be retrieved.
   bool Initialize(const std::string& auth_code);
 
+  // Clears and then retrieves a new host list.
+  bool RefreshHostList();
+
   // Retrieves connection information for all known hosts and displays
   // their availability to STDOUT.
   void DisplayHostList();
 
   // Waits for either the host to come online or a maximum timeout. Returns true
-  // if host is found online.
-  bool WaitForHostOnline(const std::string& host_jid,
-                         const std::string& host_name);
+  // if host is found online and |host_info_| is valid.
+  bool WaitForHostOnline();
 
   // Used to set fake/mock objects for ChromotingTestDriverEnvironment tests.
   // The caller retains ownership of the supplied objects, and must ensure that
@@ -95,12 +97,11 @@
                               const std::string& retrieved_refresh_token);
 
   // Used to retrieve a host list from the directory service.
-  // Returns true if the request was successful, |host_list_| is valid, and
-  // |host_info_| has been set.
+  // Returns true if the request was successful and |host_list_| is valid.
   bool RetrieveHostList();
 
-  // Clears and then retrieves a new host list.
-  bool RefreshHostList();
+  // Sets |host_info_| if the requested host exists in the host list.
+  bool FindHostInHostList();
 
   // Called after the host info fetcher completes.
   void OnHostListRetrieved(base::Closure done_closure,
diff --git a/remoting/test/chromoting_test_driver_environment_unittest.cc b/remoting/test/chromoting_test_driver_environment_unittest.cc
index 843be6d..63add746 100644
--- a/remoting/test/chromoting_test_driver_environment_unittest.cc
+++ b/remoting/test/chromoting_test_driver_environment_unittest.cc
@@ -81,7 +81,8 @@
 }
 
 bool ChromotingTestDriverEnvironmentTest::RefreshHostList() {
-  return environment_object_->RefreshHostList();
+  return environment_object_->RefreshHostList() &&
+         environment_object_->FindHostInHostList();
 }
 
 HostInfo ChromotingTestDriverEnvironmentTest::CreateFakeHostInfo() {
@@ -113,9 +114,8 @@
             kFakeAccessTokenFetcherAccessTokenValue);
   EXPECT_EQ(environment_object_->host_list().size(), 0u);
 
-  // Now Retrieve the host list.
-  EXPECT_TRUE(environment_object_->WaitForHostOnline(kFakeHostJidValue,
-                                                     kFakeHostNameValue));
+  // Now retrieve the host list.
+  EXPECT_TRUE(environment_object_->WaitForHostOnline());
 
   // Should only have one host in the list.
   EXPECT_EQ(environment_object_->host_list().size(), kExpectedHostListSize);
@@ -152,9 +152,8 @@
             kFakeAccessTokenFetcherAccessTokenValue);
   EXPECT_EQ(environment_object_->host_list().size(), 0u);
 
-  // Now Retrieve the host list.
-  EXPECT_TRUE(environment_object_->WaitForHostOnline(kFakeHostJidValue,
-                                                     kFakeHostNameValue));
+  // Now retrieve the host list.
+  EXPECT_TRUE(environment_object_->WaitForHostOnline());
 
   // Should only have one host in the list.
   EXPECT_EQ(environment_object_->host_list().size(), kExpectedHostListSize);
@@ -262,7 +261,7 @@
 
   environment_object_->SetHostNameForTest(kFakeHostNameValue);
   environment_object_->SetHostJidForTest(kFakeHostJidValue);
-  EXPECT_FALSE(RefreshHostList());
+  EXPECT_TRUE(RefreshHostList());
   EXPECT_FALSE(environment_object_->host_info().IsReadyForConnection());
 }
 
diff --git a/rlz/chromeos/lib/rlz_value_store_chromeos.cc b/rlz/chromeos/lib/rlz_value_store_chromeos.cc
index 84167aa..6c72bff 100644
--- a/rlz/chromeos/lib/rlz_value_store_chromeos.cc
+++ b/rlz/chromeos/lib/rlz_value_store_chromeos.cc
@@ -148,7 +148,7 @@
                                             const char* event_rlz) {
   DCHECK(CalledOnValidThread());
   return AddValueToList(GetKeyName(kProductEventKey, product),
-                        base::MakeUnique<base::StringValue>(event_rlz));
+                        base::MakeUnique<base::Value>(event_rlz));
 }
 
 bool RlzValueStoreChromeOS::ReadProductEvents(
@@ -170,7 +170,7 @@
 bool RlzValueStoreChromeOS::ClearProductEvent(Product product,
                                               const char* event_rlz) {
   DCHECK(CalledOnValidThread());
-  base::StringValue event_value(event_rlz);
+  base::Value event_value(event_rlz);
   return RemoveValueFromList(GetKeyName(kProductEventKey, product),
                              event_value);
 }
@@ -185,13 +185,13 @@
                                              const char* event_rlz) {
   DCHECK(CalledOnValidThread());
   return AddValueToList(GetKeyName(kStatefulEventKey, product),
-                        base::MakeUnique<base::StringValue>(event_rlz));
+                        base::MakeUnique<base::Value>(event_rlz));
 }
 
 bool RlzValueStoreChromeOS::IsStatefulEvent(Product product,
                                             const char* event_rlz) {
   DCHECK(CalledOnValidThread());
-  base::StringValue event_value(event_rlz);
+  base::Value event_value(event_rlz);
   base::ListValue* events_list = NULL;
   return rlz_store_->GetList(GetKeyName(kStatefulEventKey, product),
                              &events_list) &&
diff --git a/services/catalog/public/tools/catalog.cc.tmpl b/services/catalog/public/tools/catalog.cc.tmpl
index 2edab79..f905080 100644
--- a/services/catalog/public/tools/catalog.cc.tmpl
+++ b/services/catalog/public/tools/catalog.cc.tmpl
@@ -39,7 +39,7 @@
 {%-   elif source|is_bool -%}
 base::MakeUnique<base::Value>({{source|lower}})
 {%-   elif source|is_string or source|is_unicode -%}
-base::MakeUnique<base::StringValue>("{{source|make_ascii}}")
+base::MakeUnique<base::Value>("{{source|make_ascii}}")
 {%-   else %}
 {{raise("Unknown value type: %s" % source, source)}}
 {%-   endif %}
diff --git a/services/preferences/public/cpp/tests/pref_client_store_unittest.cc b/services/preferences/public/cpp/tests/pref_client_store_unittest.cc
index ac21660c..a044b03 100644
--- a/services/preferences/public/cpp/tests/pref_client_store_unittest.cc
+++ b/services/preferences/public/cpp/tests/pref_client_store_unittest.cc
@@ -210,7 +210,7 @@
   const int kValue = 42;
   base::Value pref1(kValue);
   const std::string kStringValue("look");
-  base::StringValue pref2(kStringValue);
+  base::Value pref2(kStringValue);
 
   base::DictionaryValue prefs;
   prefs.Set(key1, pref1.CreateDeepCopy());
diff --git a/services/ui/gpu/gpu_main.cc b/services/ui/gpu/gpu_main.cc
index bc04ac5..3e4015a 100644
--- a/services/ui/gpu/gpu_main.cc
+++ b/services/ui/gpu/gpu_main.cc
@@ -71,6 +71,7 @@
   thread_options.priority = base::ThreadPriority::DISPLAY;
 #endif
   CHECK(gpu_thread_.StartWithOptions(thread_options));
+  gpu_thread_task_runner_ = gpu_thread_.task_runner();
 
   // TODO(sad): We do not need the IO thread once gpu has a separate process. It
   // should be possible to use |main_task_runner_| for doing IO tasks.
@@ -85,11 +86,12 @@
 
   // Start the compositor thread.
   compositor_thread_.Start();
+  compositor_thread_task_runner_ = compositor_thread_.task_runner();
 }
 
 GpuMain::~GpuMain() {
   // Unretained() is OK here since the thread/task runner is owned by |this|.
-  compositor_thread_.task_runner()->PostTask(
+  compositor_thread_task_runner_->PostTask(
       FROM_HERE,
       base::Bind(&GpuMain::TearDownOnCompositorThread, base::Unretained(this)));
 
@@ -98,7 +100,7 @@
   // thread to avoid deadlock.
   compositor_thread_.Stop();
 
-  gpu_thread_.task_runner()->PostTask(
+  gpu_thread_task_runner_->PostTask(
       FROM_HERE,
       base::Bind(&GpuMain::TearDownOnGpuThread, base::Unretained(this)));
   gpu_thread_.Stop();
@@ -108,10 +110,10 @@
 void GpuMain::OnStart() {
   // |this| will outlive the gpu thread and so it's safe to use
   // base::Unretained here.
-  gpu_thread_.task_runner()->PostTask(
+  gpu_thread_task_runner_->PostTask(
       FROM_HERE,
       base::Bind(&GpuMain::InitOnGpuThread, base::Unretained(this),
-                 io_thread_.task_runner(), compositor_thread_.task_runner()));
+                 io_thread_.task_runner(), compositor_thread_task_runner_));
 }
 
 void GpuMain::CreateGpuService(mojom::GpuServiceRequest request,
@@ -119,7 +121,7 @@
                                const gpu::GpuPreferences& preferences) {
   // |this| will outlive the gpu thread and so it's safe to use
   // base::Unretained here.
-  gpu_thread_.task_runner()->PostTask(
+  gpu_thread_task_runner_->PostTask(
       FROM_HERE,
       base::Bind(&GpuMain::CreateGpuServiceOnGpuThread, base::Unretained(this),
                  base::Passed(std::move(request)),
@@ -163,7 +165,7 @@
     cc::mojom::DisplayCompositorClientPtrInfo client_info) {
   DCHECK(!gpu_command_service_);
   gpu_command_service_ = new gpu::GpuInProcessThreadService(
-      gpu_thread_.task_runner(), gpu_service_->sync_point_manager(),
+      gpu_thread_task_runner_, gpu_service_->sync_point_manager(),
       gpu_service_->mailbox_manager(), gpu_service_->share_group());
 
   // |gpu_memory_buffer_factory_| is null in tests.
@@ -174,19 +176,19 @@
   mojom::GpuServicePtr gpu_service;
   mojom::GpuServiceRequest gpu_service_request(&gpu_service);
 
-  if (gpu_thread_.task_runner()->BelongsToCurrentThread()) {
+  if (gpu_thread_task_runner_->BelongsToCurrentThread()) {
     // If the DisplayCompositor creation was delayed because GpuService
     // had not been created yet, then this is called, in gpu thread, right after
     // GpuService is created.
     BindGpuInternalOnGpuThread(std::move(gpu_service_request));
   } else {
-    gpu_thread_.task_runner()->PostTask(
+    gpu_thread_task_runner_->PostTask(
         FROM_HERE,
         base::Bind(&GpuMain::BindGpuInternalOnGpuThread, base::Unretained(this),
                    base::Passed(std::move(gpu_service_request))));
   }
 
-  compositor_thread_.task_runner()->PostTask(
+  compositor_thread_task_runner_->PostTask(
       FROM_HERE, base::Bind(&GpuMain::CreateDisplayCompositorOnCompositorThread,
                             base::Unretained(this), image_factory,
                             base::Passed(gpu_service.PassInterface()),
diff --git a/services/ui/gpu/gpu_main.h b/services/ui/gpu/gpu_main.h
index a5c859d..fb9adb49 100644
--- a/services/ui/gpu/gpu_main.h
+++ b/services/ui/gpu/gpu_main.h
@@ -86,6 +86,7 @@
 
   // The main thread for Gpu.
   base::Thread gpu_thread_;
+  scoped_refptr<base::SingleThreadTaskRunner> gpu_thread_task_runner_;
 
   // The thread that handles IO events for Gpu.
   base::Thread io_thread_;
@@ -96,6 +97,7 @@
   // and GLRenderer block on sync tokens from other command buffers. Thus,
   // the gpu service must live on a separate thread.
   base::Thread compositor_thread_;
+  scoped_refptr<base::SingleThreadTaskRunner> compositor_thread_task_runner_;
 
   mojo::Binding<mojom::GpuMain> binding_;
 
diff --git a/services/ui/public/interfaces/window_tree.mojom b/services/ui/public/interfaces/window_tree.mojom
index ab53d13..6449eb4 100644
--- a/services/ui/public/interfaces/window_tree.mojom
+++ b/services/ui/public/interfaces/window_tree.mojom
@@ -4,6 +4,7 @@
 
 module ui.mojom;
 
+import "cc/ipc/local_surface_id.mojom";
 import "cc/ipc/surface_info.mojom";
 import "cc/ipc/mojo_compositor_frame_sink.mojom";
 import "services/ui/public/interfaces/cursor.mojom";
@@ -100,8 +101,10 @@
   // Stops the pointer watcher for all events.
   StopPointerWatcher();
 
-  // Sets the specified bounds of the specified window.
-  SetWindowBounds(uint32 change_id, uint32 window_id, gfx.mojom.Rect bounds);
+  // Sets the specified bounds of the specified window. The window will paint
+  // the frame in the provided |local_frame_id|, if any.
+  SetWindowBounds(uint32 change_id, uint32 window_id, gfx.mojom.Rect bounds,
+                  cc.mojom.LocalSurfaceId? local_surface_id);
 
   // Sets the client area of the specified window. The client area is specified
   // by way of insets. Everything outside of the insets, and not in
@@ -344,10 +347,12 @@
                     int64 display_id,
                     bool parent_drawn);
 
-  // Invoked when a window's bounds have changed.
+  // Invoked when a window's bounds have changed. Only the client embedded in
+  // |window| gets a non_empty |local_surface_id|.
   OnWindowBoundsChanged(uint32 window,
                         gfx.mojom.Rect old_bounds,
-                        gfx.mojom.Rect new_bounds);
+                        gfx.mojom.Rect new_bounds,
+                        cc.mojom.LocalSurfaceId? local_surface_id);
 
   OnClientAreaChanged(uint32 window_id,
                       gfx.mojom.Insets new_client_area,
diff --git a/services/ui/ws/display.cc b/services/ui/ws/display.cc
index b3981b8..976b84c 100644
--- a/services/ui/ws/display.cc
+++ b/services/ui/ws/display.cc
@@ -258,7 +258,7 @@
       ServerWindow::Properties()));
   root_->set_event_targeting_policy(
       mojom::EventTargetingPolicy::DESCENDANTS_ONLY);
-  root_->SetBounds(gfx::Rect(size));
+  root_->SetBounds(gfx::Rect(size), allocator_.GenerateId());
   root_->SetVisible(true);
   focus_controller_ = base::MakeUnique<FocusController>(this, root_.get());
   focus_controller_->AddObserver(this);
@@ -303,9 +303,9 @@
     return;
 
   gfx::Rect new_bounds(metrics.pixel_size);
-  root_->SetBounds(new_bounds);
+  root_->SetBounds(new_bounds, allocator_.GenerateId());
   for (auto& pair : window_manager_display_root_map_)
-    pair.second->root()->SetBounds(new_bounds);
+    pair.second->root()->SetBounds(new_bounds, allocator_.GenerateId());
 }
 
 ServerWindow* Display::GetActiveRootWindow() {
diff --git a/services/ui/ws/display.h b/services/ui/ws/display.h
index 2fae94d..478f16a 100644
--- a/services/ui/ws/display.h
+++ b/services/ui/ws/display.h
@@ -14,6 +14,7 @@
 
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
+#include "cc/surfaces/local_surface_id_allocator.h"
 #include "services/ui/common/types.h"
 #include "services/ui/public/interfaces/window_manager_constants.mojom.h"
 #include "services/ui/public/interfaces/window_tree_host.mojom.h"
@@ -202,6 +203,8 @@
 
   ServerWindowTracker activation_parents_;
 
+  cc::LocalSurfaceIdAllocator allocator_;
+
   WindowManagerDisplayRootMap window_manager_display_root_map_;
 
   DISALLOW_COPY_AND_ASSIGN(Display);
diff --git a/services/ui/ws/server_window.cc b/services/ui/ws/server_window.cc
index 42bdcab..30d9116 100644
--- a/services/ui/ws/server_window.cc
+++ b/services/ui/ws/server_window.cc
@@ -172,13 +172,16 @@
   child->Reorder(children_.back(), mojom::OrderDirection::ABOVE);
 }
 
-void ServerWindow::SetBounds(const gfx::Rect& bounds) {
-  if (bounds_ == bounds)
+void ServerWindow::SetBounds(
+    const gfx::Rect& bounds,
+    const base::Optional<cc::LocalSurfaceId>& local_surface_id) {
+  if (bounds_ == bounds && current_local_surface_id_ == local_surface_id)
     return;
 
-  // TODO(fsamuel): figure out how will this work with CompositorFrames.
-
   const gfx::Rect old_bounds = bounds_;
+
+  current_local_surface_id_ = local_surface_id;
+
   bounds_ = bounds;
   for (auto& observer : observers_)
     observer.OnWindowBoundsChanged(this, old_bounds, bounds);
diff --git a/services/ui/ws/server_window.h b/services/ui/ws/server_window.h
index c600aa7..a8a9fdf 100644
--- a/services/ui/ws/server_window.h
+++ b/services/ui/ws/server_window.h
@@ -74,6 +74,10 @@
 
   const cc::FrameSinkId& frame_sink_id() const { return frame_sink_id_; }
 
+  const base::Optional<cc::LocalSurfaceId>& current_local_surface_id() const {
+    return current_local_surface_id_;
+  }
+
   void Add(ServerWindow* child);
   void Remove(ServerWindow* child);
   void Reorder(ServerWindow* relative, mojom::OrderDirection diretion);
@@ -83,7 +87,9 @@
   const gfx::Rect& bounds() const { return bounds_; }
   // Sets the bounds. If the size changes this implicitly resets the client
   // area to fill the whole bounds.
-  void SetBounds(const gfx::Rect& bounds);
+  void SetBounds(const gfx::Rect& bounds,
+                 const base::Optional<cc::LocalSurfaceId>& local_surface_id =
+                     base::nullopt);
 
   const std::vector<gfx::Rect>& additional_client_areas() const {
     return additional_client_areas_;
@@ -227,6 +233,8 @@
   ServerWindowDelegate* delegate_;
   const WindowId id_;
   cc::FrameSinkId frame_sink_id_;
+  base::Optional<cc::LocalSurfaceId> current_local_surface_id_;
+
   ServerWindow* parent_;
   Windows children_;
 
diff --git a/services/ui/ws/test_change_tracker.cc b/services/ui/ws/test_change_tracker.cc
index eb393854..172c9b8 100644
--- a/services/ui/ws/test_change_tracker.cc
+++ b/services/ui/ws/test_change_tracker.cc
@@ -60,9 +60,12 @@
 
     case CHANGE_TYPE_NODE_BOUNDS_CHANGED:
       return base::StringPrintf(
-          "BoundsChanged window=%s old_bounds=%s new_bounds=%s",
+          "BoundsChanged window=%s old_bounds=%s new_bounds=%s "
+          "local_surface_id=%s",
           WindowIdToString(change.window_id).c_str(),
-          change.bounds.ToString().c_str(), change.bounds2.ToString().c_str());
+          change.bounds.ToString().c_str(), change.bounds2.ToString().c_str(),
+          change.local_surface_id ? change.local_surface_id->ToString().c_str()
+                                  : "(none)");
 
     case CHANGE_TYPE_NODE_HIERARCHY_CHANGED:
       return base::StringPrintf(
@@ -249,14 +252,17 @@
   AddChange(change);
 }
 
-void TestChangeTracker::OnWindowBoundsChanged(Id window_id,
-                                              const gfx::Rect& old_bounds,
-                                              const gfx::Rect& new_bounds) {
+void TestChangeTracker::OnWindowBoundsChanged(
+    Id window_id,
+    const gfx::Rect& old_bounds,
+    const gfx::Rect& new_bounds,
+    const base::Optional<cc::LocalSurfaceId>& local_surface_id) {
   Change change;
   change.type = CHANGE_TYPE_NODE_BOUNDS_CHANGED;
   change.window_id = window_id;
   change.bounds = old_bounds;
   change.bounds2 = new_bounds;
+  change.local_surface_id = local_surface_id;
   AddChange(change);
 }
 
diff --git a/services/ui/ws/test_change_tracker.h b/services/ui/ws/test_change_tracker.h
index 7158f51..3421441e 100644
--- a/services/ui/ws/test_change_tracker.h
+++ b/services/ui/ws/test_change_tracker.h
@@ -77,6 +77,7 @@
   Id window_id3;
   gfx::Rect bounds;
   gfx::Rect bounds2;
+  base::Optional<cc::LocalSurfaceId> local_surface_id;
   int32_t event_action;
   bool matches_pointer_watcher;
   std::string embed_url;
@@ -144,9 +145,11 @@
   void OnCaptureChanged(Id new_capture_window_id, Id old_capture_window_id);
   void OnTransientWindowAdded(Id window_id, Id transient_window_id);
   void OnTransientWindowRemoved(Id window_id, Id transient_window_id);
-  void OnWindowBoundsChanged(Id window_id,
-                             const gfx::Rect& old_bounds,
-                             const gfx::Rect& new_bounds);
+  void OnWindowBoundsChanged(
+      Id window_id,
+      const gfx::Rect& old_bounds,
+      const gfx::Rect& new_bounds,
+      const base::Optional<cc::LocalSurfaceId>& local_surface_id);
   void OnWindowHierarchyChanged(Id window_id,
                                 Id old_parent_id,
                                 Id new_parent_id,
diff --git a/services/ui/ws/test_utils.cc b/services/ui/ws/test_utils.cc
index 23d10b7..d444e0c6 100644
--- a/services/ui/ws/test_utils.cc
+++ b/services/ui/ws/test_utils.cc
@@ -312,11 +312,13 @@
   tracker_.OnTopLevelCreated(change_id, std::move(data), drawn);
 }
 
-void TestWindowTreeClient::OnWindowBoundsChanged(uint32_t window,
-                                                 const gfx::Rect& old_bounds,
-                                                 const gfx::Rect& new_bounds) {
+void TestWindowTreeClient::OnWindowBoundsChanged(
+    uint32_t window,
+    const gfx::Rect& old_bounds,
+    const gfx::Rect& new_bounds,
+    const base::Optional<cc::LocalSurfaceId>& local_surface_id) {
   tracker_.OnWindowBoundsChanged(window, std::move(old_bounds),
-                                 std::move(new_bounds));
+                                 std::move(new_bounds), local_surface_id);
 }
 
 void TestWindowTreeClient::OnClientAreaChanged(
@@ -537,7 +539,7 @@
   EXPECT_TRUE(wm_tree->NewWindow(embed_window_id, ServerWindow::Properties()));
   EXPECT_TRUE(wm_tree->SetWindowVisibility(embed_window_id, true));
   EXPECT_TRUE(wm_tree->AddWindow(FirstRootId(wm_tree), embed_window_id));
-  display_->root_window()->SetBounds(root_window_bounds);
+  display_->root_window()->SetBounds(root_window_bounds, base::nullopt);
   mojom::WindowTreeClientPtr client;
   mojom::WindowTreeClientRequest client_request(&client);
   ws_test_helper_.window_server_delegate()->last_client()->Bind(
@@ -552,7 +554,7 @@
   EXPECT_NE(tree1, wm_tree);
   WindowTreeTestApi(tree1).set_user_id(wm_tree->user_id());
 
-  embed_window->SetBounds(window_bounds);
+  embed_window->SetBounds(window_bounds, base::nullopt);
 
   return embed_window;
 }
@@ -575,7 +577,7 @@
   tree1->GetDisplay(embed_window)->AddActivationParent(embed_window);
 
   child1->SetVisible(true);
-  child1->SetBounds(window_bounds);
+  child1->SetBounds(window_bounds, base::nullopt);
 
   TestWindowTreeClient* embed_client =
       ws_test_helper_.window_server_delegate()->last_client();
diff --git a/services/ui/ws/test_utils.h b/services/ui/ws/test_utils.h
index 7e2cb3f..aa0c3ee5 100644
--- a/services/ui/ws/test_utils.h
+++ b/services/ui/ws/test_utils.h
@@ -414,9 +414,11 @@
                          mojom::WindowDataPtr data,
                          int64_t display_id,
                          bool drawn) override;
-  void OnWindowBoundsChanged(uint32_t window,
-                             const gfx::Rect& old_bounds,
-                             const gfx::Rect& new_bounds) override;
+  void OnWindowBoundsChanged(
+      uint32_t window,
+      const gfx::Rect& old_bounds,
+      const gfx::Rect& new_bounds,
+      const base::Optional<cc::LocalSurfaceId>& local_surface_id) override;
   void OnClientAreaChanged(
       uint32_t window_id,
       const gfx::Insets& new_client_area,
diff --git a/services/ui/ws/window_finder_unittest.cc b/services/ui/ws/window_finder_unittest.cc
index 717dcd0..102057f 100644
--- a/services/ui/ws/window_finder_unittest.cc
+++ b/services/ui/ws/window_finder_unittest.cc
@@ -20,17 +20,17 @@
       mojom::EventTargetingPolicy::DESCENDANTS_ONLY);
   window_delegate.set_root_window(&root);
   root.SetVisible(true);
-  root.SetBounds(gfx::Rect(0, 0, 100, 100));
+  root.SetBounds(gfx::Rect(0, 0, 100, 100), base::nullopt);
 
   ServerWindow child1(&window_delegate, WindowId(1, 3));
   root.Add(&child1);
   child1.SetVisible(true);
-  child1.SetBounds(gfx::Rect(10, 10, 20, 20));
+  child1.SetBounds(gfx::Rect(10, 10, 20, 20), base::nullopt);
 
   ServerWindow child2(&window_delegate, WindowId(1, 4));
   root.Add(&child2);
   child2.SetVisible(true);
-  child2.SetBounds(gfx::Rect(15, 15, 20, 20));
+  child2.SetBounds(gfx::Rect(15, 15, 20, 20), base::nullopt);
 
   EXPECT_EQ(
       &child2,
@@ -56,12 +56,12 @@
   ServerWindow root(&window_delegate, WindowId(1, 2));
   window_delegate.set_root_window(&root);
   root.SetVisible(true);
-  root.SetBounds(gfx::Rect(0, 0, 100, 100));
+  root.SetBounds(gfx::Rect(0, 0, 100, 100), base::nullopt);
 
   ServerWindow child1(&window_delegate, WindowId(1, 3));
   root.Add(&child1);
   child1.SetVisible(true);
-  child1.SetBounds(gfx::Rect(10, 10, 20, 20));
+  child1.SetBounds(gfx::Rect(10, 10, 20, 20), base::nullopt);
 
   DeepestWindow result =
       FindDeepestVisibleWindowForEvents(&root, gfx::Point(13, 14));
@@ -102,12 +102,12 @@
   ServerWindow root(&window_delegate, WindowId(1, 2));
   window_delegate.set_root_window(&root);
   root.SetVisible(true);
-  root.SetBounds(gfx::Rect(0, 0, 100, 100));
+  root.SetBounds(gfx::Rect(0, 0, 100, 100), base::nullopt);
 
   ServerWindow child_with_mask(&window_delegate, WindowId(1, 4));
   root.Add(&child_with_mask);
   child_with_mask.SetVisible(true);
-  child_with_mask.SetBounds(gfx::Rect(10, 10, 20, 20));
+  child_with_mask.SetBounds(gfx::Rect(10, 10, 20, 20), base::nullopt);
   child_with_mask.SetHitTestMask(gfx::Rect(2, 2, 16, 16));
 
   // Test a point inside the window but outside the mask.
@@ -126,20 +126,20 @@
   ServerWindow root(&window_delegate, WindowId(1, 2));
   window_delegate.set_root_window(&root);
   root.SetVisible(true);
-  root.SetBounds(gfx::Rect(0, 0, 100, 100));
+  root.SetBounds(gfx::Rect(0, 0, 100, 100), base::nullopt);
 
   // Create two windows, |child1| and |child2|. The two overlap but |child2| is
   // not a valid event target.
   ServerWindow child1(&window_delegate, WindowId(1, 3));
   root.Add(&child1);
   child1.SetVisible(true);
-  child1.SetBounds(gfx::Rect(10, 10, 20, 20));
+  child1.SetBounds(gfx::Rect(10, 10, 20, 20), base::nullopt);
 
   ServerWindow child2(&window_delegate, WindowId(1, 4));
   root.Add(&child2);
   child2.set_event_targeting_policy(mojom::EventTargetingPolicy::NONE);
   child2.SetVisible(true);
-  child2.SetBounds(gfx::Rect(15, 15, 20, 20));
+  child2.SetBounds(gfx::Rect(15, 15, 20, 20), base::nullopt);
 
   // 16, 16 is over |child2| and |child1|, but as |child2| isn't a valid event
   // target |child1| should be picked.
@@ -153,7 +153,7 @@
   ServerWindow root(&window_delegate, WindowId(1, 2));
   window_delegate.set_root_window(&root);
   root.SetVisible(true);
-  root.SetBounds(gfx::Rect(0, 0, 100, 100));
+  root.SetBounds(gfx::Rect(0, 0, 100, 100), base::nullopt);
 
   // Create two windows, |child| and |child_child|; |child| is a child of the
   // root and |child_child| and child of |child|. All share the same size with
@@ -161,13 +161,13 @@
   ServerWindow child(&window_delegate, WindowId(1, 3));
   root.Add(&child);
   child.SetVisible(true);
-  child.SetBounds(gfx::Rect(0, 0, 100, 100));
+  child.SetBounds(gfx::Rect(0, 0, 100, 100), base::nullopt);
   child.SetClientArea(gfx::Insets(2, 3, 4, 5), std::vector<gfx::Rect>());
 
   ServerWindow child_child(&window_delegate, WindowId(1, 4));
   child.Add(&child_child);
   child_child.SetVisible(true);
-  child_child.SetBounds(gfx::Rect(0, 0, 100, 100));
+  child_child.SetBounds(gfx::Rect(0, 0, 100, 100), base::nullopt);
 
   // |child| was should be returned as the event is over the non-client area.
   EXPECT_EQ(&child,
diff --git a/services/ui/ws/window_manager_display_root.cc b/services/ui/ws/window_manager_display_root.cc
index 7248714..5a933de 100644
--- a/services/ui/ws/window_manager_display_root.cc
+++ b/services/ui/ws/window_manager_display_root.cc
@@ -31,7 +31,8 @@
   // Our root is always a child of the Display's root. Do this
   // before the WindowTree has been created so that the client doesn't get
   // notified of the add, bounds change and visibility change.
-  root_->SetBounds(gfx::Rect(display->root_window()->bounds().size()));
+  root_->SetBounds(gfx::Rect(display->root_window()->bounds().size()),
+                   allocator_.GenerateId());
   root_->SetVisible(true);
   display->root_window()->Add(root_.get());
 }
diff --git a/services/ui/ws/window_manager_display_root.h b/services/ui/ws/window_manager_display_root.h
index 2ba39a0..1eacb3a 100644
--- a/services/ui/ws/window_manager_display_root.h
+++ b/services/ui/ws/window_manager_display_root.h
@@ -10,6 +10,7 @@
 #include <memory>
 
 #include "base/macros.h"
+#include "cc/surfaces/local_surface_id_allocator.h"
 
 namespace ui {
 namespace ws {
@@ -49,6 +50,7 @@
   // the root ServerWindow of the Display.
   std::unique_ptr<ServerWindow> root_;
   WindowManagerState* window_manager_state_ = nullptr;
+  cc::LocalSurfaceIdAllocator allocator_;
 
   DISALLOW_COPY_AND_ASSIGN(WindowManagerDisplayRoot);
 };
diff --git a/services/ui/ws/window_server.cc b/services/ui/ws/window_server.cc
index 8bcba9b..a1a6718 100644
--- a/services/ui/ws/window_server.cc
+++ b/services/ui/ws/window_server.cc
@@ -346,12 +346,15 @@
                                              change.client_change_id, window);
 }
 
-void WindowServer::ProcessWindowBoundsChanged(const ServerWindow* window,
-                                              const gfx::Rect& old_bounds,
-                                              const gfx::Rect& new_bounds) {
+void WindowServer::ProcessWindowBoundsChanged(
+    const ServerWindow* window,
+    const gfx::Rect& old_bounds,
+    const gfx::Rect& new_bounds,
+    const base::Optional<cc::LocalSurfaceId>& local_surface_id) {
   for (auto& pair : tree_map_) {
     pair.second->ProcessWindowBoundsChanged(window, old_bounds, new_bounds,
-                                            IsOperationSource(pair.first));
+                                            IsOperationSource(pair.first),
+                                            local_surface_id);
   }
 }
 
@@ -686,7 +689,8 @@
   if (in_destructor_)
     return;
 
-  ProcessWindowBoundsChanged(window, old_bounds, new_bounds);
+  ProcessWindowBoundsChanged(window, old_bounds, new_bounds,
+                             window->current_local_surface_id());
   if (!window->parent())
     return;
 
diff --git a/services/ui/ws/window_server.h b/services/ui/ws/window_server.h
index fce14fa..2949e88c 100644
--- a/services/ui/ws/window_server.h
+++ b/services/ui/ws/window_server.h
@@ -167,9 +167,11 @@
 
   // These functions trivially delegate to all WindowTrees, which in
   // term notify their clients.
-  void ProcessWindowBoundsChanged(const ServerWindow* window,
-                                  const gfx::Rect& old_bounds,
-                                  const gfx::Rect& new_bounds);
+  void ProcessWindowBoundsChanged(
+      const ServerWindow* window,
+      const gfx::Rect& old_bounds,
+      const gfx::Rect& new_bounds,
+      const base::Optional<cc::LocalSurfaceId>& local_surface_id);
   void ProcessClientAreaChanged(
       const ServerWindow* window,
       const gfx::Insets& new_client_area,
diff --git a/services/ui/ws/window_tree.cc b/services/ui/ws/window_tree.cc
index f642e1f..ebb5bf6 100644
--- a/services/ui/ws/window_tree.cc
+++ b/services/ui/ws/window_tree.cc
@@ -548,14 +548,17 @@
   }
 }
 
-void WindowTree::ProcessWindowBoundsChanged(const ServerWindow* window,
-                                            const gfx::Rect& old_bounds,
-                                            const gfx::Rect& new_bounds,
-                                            bool originated_change) {
+void WindowTree::ProcessWindowBoundsChanged(
+    const ServerWindow* window,
+    const gfx::Rect& old_bounds,
+    const gfx::Rect& new_bounds,
+    bool originated_change,
+    const base::Optional<cc::LocalSurfaceId>& local_surface_id) {
   ClientWindowId client_window_id;
   if (originated_change || !IsWindowKnown(window, &client_window_id))
     return;
-  client()->OnWindowBoundsChanged(client_window_id.id, old_bounds, new_bounds);
+  client()->OnWindowBoundsChanged(client_window_id.id, old_bounds, new_bounds,
+                                  local_surface_id);
 }
 
 void WindowTree::ProcessClientAreaChanged(
@@ -1336,9 +1339,11 @@
   pointer_watcher_want_moves_ = false;
 }
 
-void WindowTree::SetWindowBounds(uint32_t change_id,
-                                 Id window_id,
-                                 const gfx::Rect& bounds) {
+void WindowTree::SetWindowBounds(
+    uint32_t change_id,
+    Id window_id,
+    const gfx::Rect& bounds,
+    const base::Optional<cc::LocalSurfaceId>& local_surface_id) {
   ServerWindow* window = GetWindowByClientId(ClientWindowId(window_id));
   if (window && ShouldRouteToWindowManager(window)) {
     const uint32_t wm_change_id =
@@ -1362,7 +1367,7 @@
   bool success = window && access_policy_->CanSetWindowBounds(window);
   if (success) {
     Operation op(this, window_server_, OperationType::SET_WINDOW_BOUNDS);
-    window->SetBounds(bounds);
+    window->SetBounds(bounds, local_surface_id);
   }
   client()->OnChangeCompleted(change_id, success);
 }
@@ -1974,7 +1979,8 @@
     if (!response && window) {
       // Our move loop didn't succeed, which means that we must restore the
       // original bounds of the window.
-      window->SetBounds(window_server_->GetCurrentMoveLoopRevertBounds());
+      window->SetBounds(window_server_->GetCurrentMoveLoopRevertBounds(),
+                        base::nullopt);
     }
 
     window_server_->EndMoveLoop();
diff --git a/services/ui/ws/window_tree.h b/services/ui/ws/window_tree.h
index 6fc0a96..127ec8e 100644
--- a/services/ui/ws/window_tree.h
+++ b/services/ui/ws/window_tree.h
@@ -211,10 +211,12 @@
   // The following methods are invoked after the corresponding change has been
   // processed. They do the appropriate bookkeeping and update the client as
   // necessary.
-  void ProcessWindowBoundsChanged(const ServerWindow* window,
-                                  const gfx::Rect& old_bounds,
-                                  const gfx::Rect& new_bounds,
-                                  bool originated_change);
+  void ProcessWindowBoundsChanged(
+      const ServerWindow* window,
+      const gfx::Rect& old_bounds,
+      const gfx::Rect& new_bounds,
+      bool originated_change,
+      const base::Optional<cc::LocalSurfaceId>& local_surface_id);
   void ProcessClientAreaChanged(
       const ServerWindow* window,
       const gfx::Insets& new_client_area,
@@ -402,9 +404,11 @@
   void ReleaseCapture(uint32_t change_id, Id window_id) override;
   void StartPointerWatcher(bool want_moves) override;
   void StopPointerWatcher() override;
-  void SetWindowBounds(uint32_t change_id,
-                       Id window_id,
-                       const gfx::Rect& bounds) override;
+  void SetWindowBounds(
+      uint32_t change_id,
+      Id window_id,
+      const gfx::Rect& bounds,
+      const base::Optional<cc::LocalSurfaceId>& local_surface_id) override;
   void SetWindowVisibility(uint32_t change_id,
                            Id window_id,
                            bool visible) override;
diff --git a/services/ui/ws/window_tree_client_unittest.cc b/services/ui/ws/window_tree_client_unittest.cc
index dbdbc4b..edb216a 100644
--- a/services/ui/ws/window_tree_client_unittest.cc
+++ b/services/ui/ws/window_tree_client_unittest.cc
@@ -11,6 +11,7 @@
 #include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
 #include "base/strings/stringprintf.h"
+#include "cc/surfaces/local_surface_id_allocator.h"
 #include "mojo/public/cpp/bindings/associated_binding.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "services/service_manager/public/cpp/interface_factory.h"
@@ -302,15 +303,18 @@
                          bool drawn) override {
     tracker()->OnTopLevelCreated(change_id, std::move(data), drawn);
   }
-  void OnWindowBoundsChanged(Id window_id,
-                             const gfx::Rect& old_bounds,
-                             const gfx::Rect& new_bounds) override {
+  void OnWindowBoundsChanged(
+      Id window_id,
+      const gfx::Rect& old_bounds,
+      const gfx::Rect& new_bounds,
+      const base::Optional<cc::LocalSurfaceId>& local_surface_id) override {
     // The bounds of the root may change during startup on Android at random
     // times. As this doesn't matter, and shouldn't impact test exepctations,
     // it is ignored.
     if (window_id == root_window_id_ && !track_root_bounds_changes_)
       return;
-    tracker()->OnWindowBoundsChanged(window_id, old_bounds, new_bounds);
+    tracker()->OnWindowBoundsChanged(window_id, old_bounds, new_bounds,
+                                     local_surface_id);
   }
   void OnClientAreaChanged(
       uint32_t window_id,
@@ -1321,17 +1325,21 @@
 
   wt_client2_->set_track_root_bounds_changes(true);
 
-  wt1()->SetWindowBounds(10, window_1_1, gfx::Rect(0, 0, 100, 100));
+  cc::LocalSurfaceIdAllocator allocator;
+  cc::LocalSurfaceId local_surface_id = allocator.GenerateId();
+  wt1()->SetWindowBounds(10, window_1_1, gfx::Rect(0, 0, 100, 100),
+                         local_surface_id);
   ASSERT_TRUE(wt_client1()->WaitForChangeCompleted(10));
 
   wt_client2_->WaitForChangeCount(1);
   EXPECT_EQ("BoundsChanged window=" + IdToString(window_1_1) +
-                " old_bounds=0,0 0x0 new_bounds=0,0 100x100",
+                " old_bounds=0,0 0x0 new_bounds=0,0 100x100 local_surface_id=" +
+                local_surface_id.ToString(),
             SingleChangeToDescription(*changes2()));
 
   // Should not be possible to change the bounds of a window created by another
   // client.
-  wt2()->SetWindowBounds(11, window_1_1, gfx::Rect(0, 0, 0, 0));
+  wt2()->SetWindowBounds(11, window_1_1, gfx::Rect(0, 0, 0, 0), base::nullopt);
   ASSERT_FALSE(wt_client2()->WaitForChangeCompleted(11));
 }
 
@@ -2068,12 +2076,14 @@
   changes1()->clear();
 
   // Change the bounds of window_2_101 and make sure server gets it.
-  wt2()->SetWindowBounds(11, window_2_101, gfx::Rect(1, 2, 3, 4));
+  wt2()->SetWindowBounds(11, window_2_101, gfx::Rect(1, 2, 3, 4),
+                         base::nullopt);
   ASSERT_TRUE(wt_client2()->WaitForChangeCompleted(11));
   wt_client1()->WaitForChangeCount(1);
-  EXPECT_EQ("BoundsChanged window=" + IdToString(window_2_101_in_ws1) +
-                " old_bounds=0,0 0x0 new_bounds=1,2 3x4",
-            SingleChangeToDescription(*changes1()));
+  EXPECT_EQ(
+      "BoundsChanged window=" + IdToString(window_2_101_in_ws1) +
+          " old_bounds=0,0 0x0 new_bounds=1,2 3x4 local_surface_id=(none)",
+      SingleChangeToDescription(*changes1()));
   changes2()->clear();
 
   // Remove 2_101 from wm, client1 should see the change.
diff --git a/skia/BUILD.gn b/skia/BUILD.gn
index 35dc6e2..c262cbb 100644
--- a/skia/BUILD.gn
+++ b/skia/BUILD.gn
@@ -390,7 +390,7 @@
     deps += [
       "//third_party/android_tools:cpu_features",
       "//third_party/expat",
-      "//third_party/freetype-android:freetype",
+      "//third_party/freetype",
     ]
   }
 
diff --git a/skia/ext/benchmarking_canvas.cc b/skia/ext/benchmarking_canvas.cc
index 60a47a8..bcd1043 100644
--- a/skia/ext/benchmarking_canvas.cc
+++ b/skia/ext/benchmarking_canvas.cc
@@ -117,8 +117,7 @@
 }
 
 std::unique_ptr<base::Value> AsValue(SkBlendMode mode) {
-  std::unique_ptr<base::StringValue> val(
-      new base::StringValue(SkBlendMode_Name(mode)));
+  std::unique_ptr<base::Value> val(new base::Value(SkBlendMode_Name(mode)));
 
   return val;
 }
@@ -127,8 +126,7 @@
   static const char* gModeStrings[] = { "Points", "Lines", "Polygon" };
   DCHECK_LT(static_cast<size_t>(mode), SK_ARRAY_COUNT(gModeStrings));
 
-  std::unique_ptr<base::StringValue> val(
-      new base::StringValue(gModeStrings[mode]));
+  std::unique_ptr<base::Value> val(new base::Value(gModeStrings[mode]));
 
   return val;
 }
@@ -256,7 +254,7 @@
   builder.addFlag(flags & SkCanvas::kPreserveLCDText_SaveLayerFlag,
                   "kPreserveLCDText");
 
-  std::unique_ptr<base::StringValue> val(new base::StringValue(builder.str()));
+  std::unique_ptr<base::Value> val(new base::Value(builder.str()));
 
   return val;
 }
@@ -271,8 +269,7 @@
                                     };
   size_t index = static_cast<size_t>(op);
   DCHECK_LT(index, SK_ARRAY_COUNT(gOpStrings));
-  std::unique_ptr<base::StringValue> val(
-      new base::StringValue(gOpStrings[index]));
+  std::unique_ptr<base::Value> val(new base::Value(gOpStrings[index]));
   return val;
 }
 
diff --git a/skia/ext/raster_handle_allocator_win.cc b/skia/ext/raster_handle_allocator_win.cc
index 22d9bf4..fed059f 100644
--- a/skia/ext/raster_handle_allocator_win.cc
+++ b/skia/ext/raster_handle_allocator_win.cc
@@ -19,23 +19,24 @@
 
 namespace {
 
+struct HDCContextRec {
+  HDC hdc_;
+  HBITMAP prev_bitmap_;
+};
+
 static void DeleteHDCCallback(void*, void* context) {
   DCHECK_NE(context, nullptr);
-  HDC hdc = static_cast<HDC>(context);
+  const HDCContextRec* rec = static_cast<const HDCContextRec*>(context);
 
-  // We must get this before we call RestoreDC, as that will drop hbitmap and
-  // reselect the original/default bitmap.
-  HGDIOBJ hbitmap = GetCurrentObject(hdc, OBJ_BITMAP);
-  DCHECK_NE(hbitmap, nullptr);
-
-  bool success = RestoreDC(hdc, -1); // effectly performs the deselect of hbitmap
+  // Must select back in the old bitmap before we delete the hdc, and so we can
+  // recover the new_bitmap that we allocated, so we can delete it.
+  HBITMAP new_bitmap =
+      static_cast<HBITMAP>(SelectObject(rec->hdc_, rec->prev_bitmap_));
+  bool success = DeleteObject(new_bitmap);
   DCHECK(success);
-
-  // Now we are the only owner, so we can delete our bitmap
-  success = DeleteObject(hbitmap);
+  success = DeleteDC(rec->hdc_);
   DCHECK(success);
-  success = DeleteDC(hdc);
-  DCHECK(success);
+  delete rec;
 }
 
 // Allocate the layer and fill in the fields for the Rec, or return false
@@ -47,9 +48,9 @@
                    bool do_clear,
                    SkRasterHandleAllocator::Rec* rec) {
   void* pixels;
-  HBITMAP hbitmap =
+  HBITMAP new_bitmap =
       skia::CreateHBitmap(width, height, is_opaque, shared_section, &pixels);
-  if (!hbitmap) {
+  if (!new_bitmap) {
     LOG(ERROR) << "CreateHBitmap failed";
     return false;
   }
@@ -60,21 +61,16 @@
 
   HDC hdc = CreateCompatibleDC(nullptr);
   if (!hdc) {
-    DeleteObject(hbitmap);
+    DeleteObject(new_bitmap);
     return false;
   }
   SetGraphicsMode(hdc, GM_ADVANCED);
 
-  int saveIndex = SaveDC(hdc);  // so we can Restore in the delete callback
-  DCHECK_NE(saveIndex, 0);
-
-  // Be sure to select *after* we called SaveDC.
-  // Because we're using save/restore, we don't need to explicitly track the
-  // returned "previous" value.
-  SelectObject(hdc, hbitmap);
+  HBITMAP prev_bitmap = static_cast<HBITMAP>(SelectObject(hdc, new_bitmap));
+  DCHECK(prev_bitmap);
 
   rec->fReleaseProc = DeleteHDCCallback;
-  rec->fReleaseCtx = hdc;
+  rec->fReleaseCtx = new HDCContextRec{hdc, prev_bitmap};
   rec->fPixels = pixels;
   rec->fRowBytes = row_bytes;
   rec->fHandle = hdc;
diff --git a/testing/android/junit/java/src/org/chromium/testing/local/AnnotationProcessor.java b/testing/android/junit/java/src/org/chromium/testing/local/AnnotationProcessor.java
index 86ac990..8b60b1a 100644
--- a/testing/android/junit/java/src/org/chromium/testing/local/AnnotationProcessor.java
+++ b/testing/android/junit/java/src/org/chromium/testing/local/AnnotationProcessor.java
@@ -47,7 +47,7 @@
     @Override
     public Statement apply(Statement base, Description description) {
         mTestDescription = description;
-        mAnnotation = description.getAnnotation(mAnnotationClass);
+        mAnnotation = getAnnotation(description);
         if (mAnnotation == null) return base;
 
         // Return the wrapped statement to execute before() and after().
@@ -63,4 +63,12 @@
     protected T getAnnotation() {
         return mAnnotation;
     }
+
+    private T getAnnotation(Description description) {
+        T annotation = description.getAnnotation(mAnnotationClass);
+        if (annotation != null) return annotation;
+
+        annotation = description.getTestClass().getAnnotation(mAnnotationClass);
+        return annotation;
+    }
 }
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index c4c4150..3e89315 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -223,8 +223,8 @@
     "gtest_tests": [
       {
         "args": [
-          "--shared-prefs-file=chrome/android/shared_preference_files/test/vr_cardboard_skipdon_setupcomplete.json",
-          "--additional-apk=third_party/gvr-android-sdk/test-apks/vr_services/vr_services_current.apk"
+          "--shared-prefs-file=src/chrome/android/shared_preference_files/test/vr_cardboard_skipdon_setupcomplete.json",
+          "--additional-apk=src/third_party/gvr-android-sdk/test-apks/vr_services/vr_services_current.apk"
         ],
         "name": "nonddready-cardboard-current_chrome_public_test_vr_apk",
         "override_compile_targets": [
@@ -254,15 +254,16 @@
     "instrumentation_tests": [
       {
         "args": [
-          "--shared-prefs-file=chrome/android/shared_preference_files/test/vr_cardboard_skipdon_setupcomplete.json",
-          "--additional-apk=third_party/gvr-android-sdk/test-apks/vr_services/vr_services_current.apk"
+          "--shared-prefs-file=src/chrome/android/shared_preference_files/test/vr_cardboard_skipdon_setupcomplete.json",
+          "--additional-apk=src/third_party/gvr-android-sdk/test-apks/vr_services/vr_services_current.apk"
         ],
         "test": "chrome_public_test_vr_apk"
       },
       {
         "args": [
-          "--shared-prefs-file=chrome/android/shared_preference_files/test/vr_ddview_skipdon_setupcomplete.json",
-          "--additional-apk=third_party/gvr-android-sdk/test-apks/vr_services/vr_services_current.apk"
+          "--shared-prefs-file=src/chrome/android/shared_preference_files/test/vr_ddview_skipdon_setupcomplete.json",
+          "--additional-apk=src/third_party/gvr-android-sdk/test-apks/vr_services/vr_services_current.apk",
+          "--additional-apk=src/third_party/gvr-android-sdk/test-apks/daydream_home/daydream_home_current.apk"
         ],
         "test": "chrome_public_test_vr_apk"
       }
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json
index 43a3595..4a1b34e 100644
--- a/testing/buildbot/chromium.gpu.fyi.json
+++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -1,6 +1,363 @@
 {
   "AAAAA1 AUTOGENERATED FILE DO NOT EDIT": {},
   "AAAAA2 See generate_buildbot_json.py to make changes": {},
+  "Android Release (NVIDIA Shield)": {
+    "gtest_tests": [
+      {
+        "override_isolate_target": "angle_end2end_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": false,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "gpu": "0000:0000",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "angle_end2end_tests",
+        "use_xvfb": false
+      },
+      {
+        "override_isolate_target": "angle_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": false,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "gpu": "0000:0000",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "angle_unittests",
+        "use_xvfb": false
+      },
+      {
+        "override_isolate_target": "gl_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": false,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "gpu": "0000:0000",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "gl_tests",
+        "use_xvfb": false
+      },
+      {
+        "override_isolate_target": "gl_unittests",
+        "swarming": {
+          "can_use_on_swarming_builders": false,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "gpu": "0000:0000",
+              "os": "Android"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ]
+        },
+        "test": "gl_unittests",
+        "use_xvfb": false
+      }
+    ],
+    "isolated_scripts": [
+      {
+        "args": [
+          "context_lost",
+          "--show-stdout",
+          "--browser=android-chromium",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "context_lost_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": false,
+          "dimension_sets": [
+            {
+              "gpu": "0000:0000",
+              "os": "Android"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "depth_capture",
+          "--show-stdout",
+          "--browser=android-chromium",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "depth_capture_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": false,
+          "dimension_sets": [
+            {
+              "gpu": "0000:0000",
+              "os": "Android"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "gpu_process",
+          "--show-stdout",
+          "--browser=android-chromium",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "gpu_process_launch_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": false,
+          "dimension_sets": [
+            {
+              "gpu": "0000:0000",
+              "os": "Android"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "hardware_accelerated_feature",
+          "--show-stdout",
+          "--browser=android-chromium",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "hardware_accelerated_feature_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": false,
+          "dimension_sets": [
+            {
+              "gpu": "0000:0000",
+              "os": "Android"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "maps",
+          "--show-stdout",
+          "--browser=android-chromium",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
+          "--os-type",
+          "android",
+          "--build-revision",
+          "${got_revision}",
+          "--test-machine-name",
+          "${buildername}"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "maps_pixel_test",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": false,
+          "dimension_sets": [
+            {
+              "gpu": "0000:0000",
+              "os": "Android"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "pixel",
+          "--show-stdout",
+          "--browser=android-chromium",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
+          "--refimg-cloud-storage-bucket",
+          "chromium-gpu-archive/reference-images",
+          "--os-type",
+          "android",
+          "--build-revision",
+          "${got_revision}",
+          "--test-machine-name",
+          "${buildername}"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "pixel_test",
+        "non_precommit_args": [
+          "--upload-refimg-to-cloud-storage"
+        ],
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test_run"
+        ],
+        "precommit_args": [
+          "--download-refimg-from-cloud-storage"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": false,
+          "dimension_sets": [
+            {
+              "gpu": "0000:0000",
+              "os": "Android"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "screenshot_sync",
+          "--show-stdout",
+          "--browser=android-chromium",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "screenshot_sync_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": false,
+          "dimension_sets": [
+            {
+              "gpu": "0000:0000",
+              "os": "Android"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "trace_test",
+          "--show-stdout",
+          "--browser=android-chromium",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "trace_test",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": false,
+          "dimension_sets": [
+            {
+              "gpu": "0000:0000",
+              "os": "Android"
+            }
+          ]
+        }
+      },
+      {
+        "args": [
+          "webgl_conformance",
+          "--show-stdout",
+          "--browser=android-chromium",
+          "-v",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
+        ],
+        "isolate_name": "telemetry_gpu_integration_test",
+        "name": "webgl_conformance_tests",
+        "override_compile_targets": [
+          "telemetry_gpu_integration_test_run"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": false,
+          "dimension_sets": [
+            {
+              "gpu": "0000:0000",
+              "os": "Android"
+            }
+          ]
+        }
+      }
+    ]
+  },
   "Android Release (Nexus 5)": {
     "gtest_tests": [
       {
@@ -2989,22 +3346,6 @@
         },
         "test": "swiftshader_unittests",
         "use_xvfb": false
-      },
-      {
-        "override_compile_targets": [
-          "tab_capture_end2end_tests_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:104a",
-              "os": "Ubuntu"
-            }
-          ]
-        },
-        "test": "tab_capture_end2end_tests",
-        "use_xvfb": false
       }
     ],
     "isolated_scripts": [
@@ -3023,308 +3364,6 @@
             }
           ]
         }
-      },
-      {
-        "args": [
-          "context_lost",
-          "--show-stdout",
-          "--browser=release",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "context_lost_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:104a",
-              "os": "Ubuntu"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "depth_capture",
-          "--show-stdout",
-          "--browser=release",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "depth_capture_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:104a",
-              "os": "Ubuntu"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "gpu_process",
-          "--show-stdout",
-          "--browser=release",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "gpu_process_launch_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:104a",
-              "os": "Ubuntu"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "hardware_accelerated_feature",
-          "--show-stdout",
-          "--browser=release",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "hardware_accelerated_feature_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:104a",
-              "os": "Ubuntu"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "maps",
-          "--show-stdout",
-          "--browser=release",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
-          "--os-type",
-          "linux",
-          "--build-revision",
-          "${got_revision}",
-          "--test-machine-name",
-          "${buildername}"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "maps_pixel_test",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:104a",
-              "os": "Ubuntu"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "pixel",
-          "--show-stdout",
-          "--browser=release",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
-          "--refimg-cloud-storage-bucket",
-          "chromium-gpu-archive/reference-images",
-          "--os-type",
-          "linux",
-          "--build-revision",
-          "${got_revision}",
-          "--test-machine-name",
-          "${buildername}"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "pixel_test",
-        "non_precommit_args": [
-          "--upload-refimg-to-cloud-storage"
-        ],
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "precommit_args": [
-          "--download-refimg-from-cloud-storage"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:104a",
-              "os": "Ubuntu"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "screenshot_sync",
-          "--show-stdout",
-          "--browser=release",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "screenshot_sync_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:104a",
-              "os": "Ubuntu"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "trace_test",
-          "--show-stdout",
-          "--browser=release",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "trace_test",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:104a",
-              "os": "Ubuntu"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "webgl_conformance",
-          "--show-stdout",
-          "--browser=release",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-gl=angle",
-          "--webgl-conformance-version=2.0.1",
-          "--read-abbreviated-json-results-from=../../content/test/data/gpu/webgl2_conformance_tests_output.json"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "webgl2_conformance_angle_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:104a",
-              "os": "Ubuntu"
-            }
-          ],
-          "shards": 15
-        }
-      },
-      {
-        "args": [
-          "webgl_conformance",
-          "--show-stdout",
-          "--browser=release",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
-          "--webgl-conformance-version=2.0.1",
-          "--read-abbreviated-json-results-from=../../content/test/data/gpu/webgl2_conformance_tests_output.json"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "webgl2_conformance_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:104a",
-              "os": "Ubuntu"
-            }
-          ],
-          "shards": 15
-        }
-      },
-      {
-        "args": [
-          "webgl_conformance",
-          "--show-stdout",
-          "--browser=release",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-gl=angle"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "webgl_conformance_angle_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:104a",
-              "os": "Ubuntu"
-            }
-          ]
-        }
-      },
-      {
-        "args": [
-          "webgl_conformance",
-          "--show-stdout",
-          "--browser=release",
-          "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
-        ],
-        "isolate_name": "telemetry_gpu_integration_test",
-        "name": "webgl_conformance_tests",
-        "override_compile_targets": [
-          "telemetry_gpu_integration_test_run"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:104a",
-              "os": "Ubuntu"
-            }
-          ]
-        }
       }
     ]
   },
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index c7e419c..3289732 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -1093,8 +1093,8 @@
             ],
             "experiments": [
                 {
-                    "name": "Enabled",
-                    "enable_features": [
+                    "name": "Control",
+                    "disable_features": [
                         "LazyParseCSS"
                     ]
                 }
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-browser-side-navigation b/third_party/WebKit/LayoutTests/FlagExpectations/enable-browser-side-navigation
index 8c23947..a7e3a80 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-browser-side-navigation
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-browser-side-navigation
@@ -4,9 +4,6 @@
 # https://crbug.com/551000: PlzNavigate: DevTools support
 crbug.com/551000 http/tests/inspector/network/x-frame-options-deny.html [ Failure ]
 crbug.com/551000 virtual/mojo-loading/http/tests/inspector/network/x-frame-options-deny.html [ Failure ]
-#  Console error messages are wrongly ordered.
-crbug.com/551000 http/tests/inspector/console-resource-errors.html [ Failure ]
-crbug.com/551000 virtual/mojo-loading/http/tests/inspector/console-resource-errors.html [ Failure ]
 
 # Flipped order between diStartProvisionalLoad & willSendRequest
 crbug.com/647698 http/tests/loading/307-after-303-after-post.html [ Failure ]
@@ -17,10 +14,8 @@
 # https://crbug.com/555418: Move `X-Frame-Options` and CSP's `frame-ancestor`
 # checks up out of the renderer.
 crbug.com/555418 http/tests/security/contentSecurityPolicy/1.1/form-action-src-redirect-blocked.html [ Failure ]
-crbug.com/555418 http/tests/security/contentSecurityPolicy/redirect-does-not-match-paths.html [ Timeout ]
 crbug.com/555418 http/tests/security/isolatedWorld/bypass-main-world-csp-iframes.html [ Failure ]
 crbug.com/555418 virtual/mojo-loading/http/tests/security/contentSecurityPolicy/1.1/form-action-src-redirect-blocked.html [ Failure ]
-crbug.com/555418 virtual/mojo-loading/http/tests/security/contentSecurityPolicy/redirect-does-not-match-paths.html [ Timeout ]
 crbug.com/555418 virtual/mojo-loading/http/tests/security/isolatedWorld/bypass-main-world-csp-iframes.html [ Failure ]
 
 # Missing console warning about usage of legacy protocol.
@@ -31,8 +26,15 @@
 
 # https://crbug.com/695072: Preserve SourceLocation information.
 # This results in a missing line number in console error messages.
-Bug(695072) http/tests/security/location-href-clears-username-password.html [ Failure ]
-Bug(695072) virtual/mojo-loading/http/tests/security/location-href-clears-username-password.html [ Failure ]
+# Fixed by https://codereview.chromium.org/2720763002/
+crbug.com/551000 http/tests/inspector/console-resource-errors.html [ Failure ]
+crbug.com/555418 http/tests/security/contentSecurityPolicy/redirect-does-not-match-paths.html [ Timeout ]
+crbug.com/695072 http/tests/security/location-href-clears-username-password.html [ Failure ]
+crbug.com/695072 http/tests/security/mixedContent/insecure-iframe-with-hsts.https.html [ Failure ]
+crbug.com/551000 virtual/mojo-loading/http/tests/inspector/console-resource-errors.html [ Failure ]
+crbug.com/555418 virtual/mojo-loading/http/tests/security/contentSecurityPolicy/redirect-does-not-match-paths.html [ Timeout ]
+crbug.com/695072 virtual/mojo-loading/http/tests/security/location-href-clears-username-password.html [ Failure ]
+crbug.com/695072 virtual/mojo-loading/http/tests/security/mixedContent/insecure-iframe-with-hsts.https.html [ Failure ]
 
 # These tests are flaky.
 Bug(none) external/wpt/service-workers/service-worker/fetch-event-redirect.https.html [ Crash ]
diff --git a/third_party/WebKit/LayoutTests/NeverFixTests b/third_party/WebKit/LayoutTests/NeverFixTests
index bd38a71c..85de59e 100644
--- a/third_party/WebKit/LayoutTests/NeverFixTests
+++ b/third_party/WebKit/LayoutTests/NeverFixTests
@@ -216,7 +216,6 @@
 external/wpt/css-values [ WontFix ]
 external/wpt/gyroscope [ WontFix ]
 external/wpt/magnetometer [ WontFix ]
-external/wpt/preload [ WontFix ]
 external/wpt/upgrade-insecure-requests [ WontFix ]
 
 # WPT manual tests without automation
diff --git a/third_party/WebKit/LayoutTests/SlowTests b/third_party/WebKit/LayoutTests/SlowTests
index 05fbe0f..4485b557 100644
--- a/third_party/WebKit/LayoutTests/SlowTests
+++ b/third_party/WebKit/LayoutTests/SlowTests
@@ -102,7 +102,6 @@
 crbug.com/451577 [ Mac ] inspector/layers/layer-canvas-log.html [ Slow ]
 crbug.com/451577 [ Mac ] inspector/network/network-domain-filter.html [ Slow ]
 
-crbug.com/474121 editing/deleting/password-delete-performance.html [ Slow ]
 crbug.com/237245 [ Debug Win7 ] editing/selection/programmatic-selection-on-mac-is-directionless.html [ Slow ]
 
 # Most inspector tests are slow in Debug.
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index 0c8b8db..55f7756c 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -848,6 +848,8 @@
 crbug.com/698135 external/wpt/editing/run/delete.html [ Crash Failure Timeout ]
 crbug.com/698165 external/wpt/editing/run/forwarddelete.html [ Pass Timeout ]
 crbug.com/698165 external/wpt/editing/run/justifycenter.html [ Pass Timeout ]
+crbug.com/698165 external/wpt/editing/run/multitest.html [ Pass Timeout ]
+crbug.com/698165 external/wpt/editing/run/removeformat.html [ Pass Timeout ]
 
 crbug.com/688613 external/wpt/mediacapture-streams/MediaStreamTrack-MediaElement-disabled-audio-is-silence.https.html [ Skip ]
 
@@ -1611,15 +1613,6 @@
 
 crbug.com/596752 virtual/threaded/inspector/tracing/decode-resize.html [ Pass Failure ]
 
-crbug.com/610300 css3/fonts/font-style-matching-0.html [ Failure Pass ]
-crbug.com/610300 css3/fonts/font-style-matching-1.html [ Failure Pass ]
-crbug.com/610300 css3/fonts/font-style-matching-2.html [ Failure Pass ]
-crbug.com/610300 css3/fonts/font-style-matching-3.html [ Failure Pass ]
-crbug.com/610300 css3/fonts/font-style-matching-4.html [ Failure Pass ]
-crbug.com/610300 css3/fonts/font-style-matching-5.html [ Failure Pass ]
-crbug.com/610300 css3/fonts/font-style-matching-6.html [ Failure Pass ]
-crbug.com/610300 css3/fonts/font-style-matching-7.html [ Failure Pass ]
-crbug.com/610300 css3/fonts/font-style-matching-8.html [ Failure Pass ]
 crbug.com/524646 [ Mac10.10 ] fast/dom/shadow/shadowdom-for-button.html [ Failure ]
 
 crbug.com/538717 [ Win Mac Linux ] http/tests/permissions/chromium/test-request-multiple-window.html [ Failure Pass Timeout ]
@@ -1777,14 +1770,6 @@
 # 2017-02-17: These directories were just imported but expectations and baselines haven't been set yet.
 crbug.com/692105 external/wpt/service-workers/service-worker/fetch-event-within-sw-manual.https.html [ Skip ]
 crbug.com/692105 external/wpt/service-workers/service-worker/fetch-event-within-sw.https.html [ Skip ]
-crbug.com/692105 external/wpt/streams/readable-streams/floating-point-total-queue-size.dedicatedworker.html [ Skip ]
-crbug.com/692105 external/wpt/streams/readable-streams/floating-point-total-queue-size.html [ Skip ]
-crbug.com/692105 external/wpt/streams/readable-streams/floating-point-total-queue-size.serviceworker.https.html [ Skip ]
-crbug.com/692105 external/wpt/streams/readable-streams/floating-point-total-queue-size.sharedworker.html [ Skip ]
-crbug.com/692105 external/wpt/streams/writable-streams/floating-point-total-queue-size.dedicatedworker.html [ Skip ]
-crbug.com/692105 external/wpt/streams/writable-streams/floating-point-total-queue-size.html [ Skip ]
-crbug.com/692105 external/wpt/streams/writable-streams/floating-point-total-queue-size.serviceworker.https.html [ Skip ]
-crbug.com/692105 external/wpt/streams/writable-streams/floating-point-total-queue-size.sharedworker.html [ Skip ]
 
 # These policies are not implemented yet.
 crbug.com/627968 external/wpt/referrer-policy/origin-when-cross-origin/http-rp/same-origin/ [ Skip ]
@@ -1839,6 +1824,10 @@
 crbug.com/695270 [ Linux ] external/csswg-test/css-writing-modes-3/overconstrained-rel-pos-rtl-top-bottom-vrl-006.xht [ Failure ]
 
 # ====== New tests from w3c-test-autoroller added here ======
+crbug.com/626703 external/wpt/streams/readable-streams/floating-point-total-queue-size.dedicatedworker.html [ Timeout ]
+crbug.com/626703 external/wpt/streams/readable-streams/floating-point-total-queue-size.sharedworker.html [ Timeout ]
+crbug.com/626703 external/wpt/streams/writable-streams/floating-point-total-queue-size.dedicatedworker.html [ Timeout ]
+crbug.com/626703 external/wpt/streams/writable-streams/floating-point-total-queue-size.sharedworker.html [ Timeout ]
 crbug.com/626703 external/wpt/mediacapture-streams/MediaStreamTrack-end-manual.https.html [ Timeout ]
 crbug.com/626703 external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_with_class_object_specific_selector.html [ Failure ]
 crbug.com/626703 external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/default_styles/inherit_as_default_value_inherits_values_from_media_element.html [ Failure ]
@@ -2146,7 +2135,6 @@
 crbug.com/626703 external/wpt/streams/readable-streams/count-queuing-strategy-integration.html [ Failure Timeout ]
 crbug.com/626703 external/wpt/streams/readable-streams/garbage-collection.html [ Failure Timeout ]
 crbug.com/626703 external/wpt/streams/readable-streams/general.html [ Failure Timeout ]
-crbug.com/626703 external/wpt/streams/readable-streams/pipe-through.html [ Failure Timeout ]
 crbug.com/626703 external/wpt/streams/readable-streams/readable-stream-reader.html [ Failure Timeout ]
 crbug.com/626703 external/wpt/streams/readable-streams/tee.html [ Failure Timeout ]
 crbug.com/626703 external/wpt/streams/readable-streams/templated.html [ Failure Timeout ]
@@ -2283,17 +2271,6 @@
 crbug.com/508734 external/wpt/html/browsers/browsing-the-web/history-traversal/browsing_context_name_cross_origin_3.html [ Failure ]
 crbug.com/508734 external/wpt/html/browsers/origin/cross-origin-objects/cross-origin-objects.html [ Pass Failure Timeout ]
 
-crbug.com/686159 crypto/subtle/hkdf/cloneKey.html [ NeedsManualRebaseline ]
-crbug.com/686159 crypto/subtle/aes-kw/cloneKey.html [ NeedsManualRebaseline ]
-crbug.com/686159 crypto/subtle/aes-ctr/cloneKey.html [ NeedsManualRebaseline ]
-crbug.com/686159 crypto/subtle/pbkdf2/cloneKey.html [ NeedsManualRebaseline ]
-crbug.com/686159 crypto/subtle/aes-cbc/cloneKey.html [ NeedsManualRebaseline ]
-crbug.com/686159 crypto/subtle/hmac/cloneKey.html [ NeedsManualRebaseline ]
-crbug.com/686159 crypto/subtle/aes-gcm/cloneKey.html [ NeedsManualRebaseline ]
-crbug.com/686159 crypto/subtle/rsassa-pkcs1-v1_5/cloneKey.html [ NeedsManualRebaseline ]
-crbug.com/686159 crypto/subtle/ecdsa/cloneKey.html [ NeedsManualRebaseline ]
-crbug.com/686159 crypto/subtle/ecdh/cloneKey.html [ NeedsManualRebaseline ]
-
 # Fail differently when run with --enable-wptserve: (crbug.com/508728)
 crbug.com/508728 crbug.com/664268 external/wpt/html/browsers/history/the-location-interface/reload_post_1.html [ Failure Timeout ]
 crbug.com/508728 external/wpt/webstorage/document-domain.html [ Failure Timeout ]
@@ -2357,12 +2334,6 @@
 # Added 2016-12-22
 crbug.com/676537 fast/css/imageTileOpacity.html [ Pass Failure ]
 
-crbug.com/642376 virtual/gpu/fast/canvas/canvas-arc-circumference-fill.html [ Failure ]
-crbug.com/642376 virtual/gpu/fast/canvas/canvas-arc-circumference.html [ Failure ]
-crbug.com/642376 virtual/gpu/fast/canvas/canvas-ellipse-circumference-fill.html [ Failure ]
-crbug.com/642376 virtual/gpu/fast/canvas/canvas-ellipse-circumference.html [ Failure ]
-crbug.com/642376 virtual/gpu/fast/canvas/canvas-incremental-repaint.html [ Failure ]
-
 # ====== Random order flaky tests from here ======
 # These tests are flaky when run in random order, which is the default on Linux & Mac since since 2016-12-16.
 
@@ -2456,8 +2427,6 @@
 crbug.com/681468 fast/forms/suggestion-picker/date-suggestion-picker-appearance-zoom125.html [ Failure Pass ]
 crbug.com/681468 fast/forms/suggestion-picker/date-suggestion-picker-appearance-zoom200.html [ Failure Pass ]
 
-crbug.com/v8/6005 inspector/console/console-format.html [ NeedsManualRebaseline ]
-
 crbug.com/683800 [ Win7 Debug ] external/wpt/selection/ [ Failure Pass ]
 
 # CQ and Rebaseline-cl for crrev.com/2626973005 does not include this
@@ -2504,3 +2473,6 @@
 
 crbug.com/697342 http/tests/push_messaging/permission-state-granted-in-document.html [ Pass Failure ]
 crbug.com/697342 virtual/mojo-loading/http/tests/push_messaging/permission-state-granted-in-document.html [ Pass Failure ]
+
+crbug.com/698520 external/wpt/preload/fetch-destination.https.html [ Failure Pass ]
+crbug.com/698521 external/wpt/preload/preload-with-type.html [ Failure Pass ]
diff --git a/third_party/WebKit/LayoutTests/bluetooth/server/getPrimaryService/two-iframes-from-same-origin.html b/third_party/WebKit/LayoutTests/bluetooth/server/getPrimaryService/two-iframes-from-same-origin.html
index b3da705a..898cd7c 100644
--- a/third_party/WebKit/LayoutTests/bluetooth/server/getPrimaryService/two-iframes-from-same-origin.html
+++ b/third_party/WebKit/LayoutTests/bluetooth/server/getPrimaryService/two-iframes-from-same-origin.html
@@ -25,6 +25,10 @@
         }
         firstIframe = false;
       } else if (messageEvent.data === 'Iframe1Connected') {
+        callWithKeyDown(() => {
+          iframe1.contentWindow.postMessage('Iframe1TryAccessGenericAccessService', '*');
+        });
+      } else if (messageEvent.data === 'Iframe1AccessGenericAccessServiceFailed') {
         document.body.appendChild(iframe2);
       } else if (messageEvent.data === 'Iframe2Connected') {
         callWithKeyDown(() => {
diff --git a/third_party/WebKit/LayoutTests/crypto/subtle/aes-cbc/cloneKey-expected.txt b/third_party/WebKit/LayoutTests/crypto/subtle/aes-cbc/cloneKey-expected.txt
index aa954b3..79a4e55 100644
--- a/third_party/WebKit/LayoutTests/crypto/subtle/aes-cbc/cloneKey-expected.txt
+++ b/third_party/WebKit/LayoutTests/crypto/subtle/aes-cbc/cloneKey-expected.txt
@@ -18,7 +18,7 @@
 PASS clonedKey.algorithm.name is "AES-CBC"
 PASS clonedKey.algorithm.length is 128
 PASS clonedKey.usages.join(',') is "encrypt"
-Serialized key bytes: 4b010110031030112233445566778899aabbccddeeff
+Serialized key bytes: 5c4b010110031030112233445566778899aabbccddeeff00
 PASS: Cloned key exported data should be [30112233445566778899aabbccddeeff] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -36,7 +36,7 @@
 PASS clonedKey.algorithm.name is "AES-CBC"
 PASS clonedKey.algorithm.length is 256
 PASS clonedKey.usages.join(',') is "encrypt"
-Serialized key bytes: 4b010120032000112233445546778899aabbccddeeff000102030405060708090a0b0c0d0e0f
+Serialized key bytes: 5c4b010120032000112233445546778899aabbccddeeff000102030405060708090a0b0c0d0e0f00
 PASS: Cloned key exported data should be [00112233445546778899aabbccddeeff000102030405060708090a0b0c0d0e0f] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -54,7 +54,7 @@
 PASS clonedKey.algorithm.name is "AES-CBC"
 PASS clonedKey.algorithm.length is 128
 PASS clonedKey.usages.join(',') is "decrypt,wrapKey"
-Serialized key bytes: 4b010110451030112233445566778899aabbccddeeff
+Serialized key bytes: 5c4b010110451030112233445566778899aabbccddeeff00
 PASS: Cloned key exported data should be [30112233445566778899aabbccddeeff] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -72,7 +72,7 @@
 PASS clonedKey.algorithm.name is "AES-CBC"
 PASS clonedKey.algorithm.length is 256
 PASS clonedKey.usages.join(',') is "decrypt,wrapKey"
-Serialized key bytes: 4b010120452000112233445546778899aabbccddeeff000102030405060708090a0b0c0d0e0f
+Serialized key bytes: 5c4b010120452000112233445546778899aabbccddeeff000102030405060708090a0b0c0d0e0f00
 PASS: Cloned key exported data should be [00112233445546778899aabbccddeeff000102030405060708090a0b0c0d0e0f] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -90,7 +90,7 @@
 PASS clonedKey.algorithm.name is "AES-CBC"
 PASS clonedKey.algorithm.length is 128
 PASS clonedKey.usages.join(',') is "encrypt,wrapKey,unwrapKey"
-Serialized key bytes: 4b010110c3011030112233445566778899aabbccddeeff00
+Serialized key bytes: 5c4b010110c3011030112233445566778899aabbccddeeff
 PASS: Cloned key exported data should be [30112233445566778899aabbccddeeff] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -108,7 +108,7 @@
 PASS clonedKey.algorithm.name is "AES-CBC"
 PASS clonedKey.algorithm.length is 256
 PASS clonedKey.usages.join(',') is "encrypt,wrapKey,unwrapKey"
-Serialized key bytes: 4b010120c3012000112233445546778899aabbccddeeff000102030405060708090a0b0c0d0e0f00
+Serialized key bytes: 5c4b010120c3012000112233445546778899aabbccddeeff000102030405060708090a0b0c0d0e0f
 PASS: Cloned key exported data should be [00112233445546778899aabbccddeeff000102030405060708090a0b0c0d0e0f] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -126,7 +126,7 @@
 PASS clonedKey.algorithm.name is "AES-CBC"
 PASS clonedKey.algorithm.length is 128
 PASS clonedKey.usages.join(',') is "encrypt"
-Serialized key bytes: 4b010110021030112233445566778899aabbccddeeff
+Serialized key bytes: 5c4b010110021030112233445566778899aabbccddeeff00
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -143,7 +143,7 @@
 PASS clonedKey.algorithm.name is "AES-CBC"
 PASS clonedKey.algorithm.length is 256
 PASS clonedKey.usages.join(',') is "encrypt"
-Serialized key bytes: 4b010120022000112233445546778899aabbccddeeff000102030405060708090a0b0c0d0e0f
+Serialized key bytes: 5c4b010120022000112233445546778899aabbccddeeff000102030405060708090a0b0c0d0e0f00
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -160,7 +160,7 @@
 PASS clonedKey.algorithm.name is "AES-CBC"
 PASS clonedKey.algorithm.length is 128
 PASS clonedKey.usages.join(',') is "decrypt,wrapKey"
-Serialized key bytes: 4b010110441030112233445566778899aabbccddeeff
+Serialized key bytes: 5c4b010110441030112233445566778899aabbccddeeff00
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -177,7 +177,7 @@
 PASS clonedKey.algorithm.name is "AES-CBC"
 PASS clonedKey.algorithm.length is 256
 PASS clonedKey.usages.join(',') is "decrypt,wrapKey"
-Serialized key bytes: 4b010120442000112233445546778899aabbccddeeff000102030405060708090a0b0c0d0e0f
+Serialized key bytes: 5c4b010120442000112233445546778899aabbccddeeff000102030405060708090a0b0c0d0e0f00
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -194,7 +194,7 @@
 PASS clonedKey.algorithm.name is "AES-CBC"
 PASS clonedKey.algorithm.length is 128
 PASS clonedKey.usages.join(',') is "encrypt,wrapKey,unwrapKey"
-Serialized key bytes: 4b010110c2011030112233445566778899aabbccddeeff00
+Serialized key bytes: 5c4b010110c2011030112233445566778899aabbccddeeff
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -211,7 +211,7 @@
 PASS clonedKey.algorithm.name is "AES-CBC"
 PASS clonedKey.algorithm.length is 256
 PASS clonedKey.usages.join(',') is "encrypt,wrapKey,unwrapKey"
-Serialized key bytes: 4b010120c2012000112233445546778899aabbccddeeff000102030405060708090a0b0c0d0e0f00
+Serialized key bytes: 5c4b010120c2012000112233445546778899aabbccddeeff000102030405060708090a0b0c0d0e0f
 
 PASS successfullyParsed is true
 
diff --git a/third_party/WebKit/LayoutTests/crypto/subtle/aes-ctr/cloneKey-expected.txt b/third_party/WebKit/LayoutTests/crypto/subtle/aes-ctr/cloneKey-expected.txt
index 8e90c6b..fd70462 100644
--- a/third_party/WebKit/LayoutTests/crypto/subtle/aes-ctr/cloneKey-expected.txt
+++ b/third_party/WebKit/LayoutTests/crypto/subtle/aes-ctr/cloneKey-expected.txt
@@ -18,7 +18,7 @@
 PASS clonedKey.algorithm.name is "AES-CTR"
 PASS clonedKey.algorithm.length is 128
 PASS clonedKey.usages.join(',') is "wrapKey,unwrapKey"
-Serialized key bytes: 4b010b10c1011030112233445566778899aabbccddeeff00
+Serialized key bytes: 5c4b010b10c1011030112233445566778899aabbccddeeff
 PASS: Cloned key exported data should be [30112233445566778899aabbccddeeff] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -36,7 +36,7 @@
 PASS clonedKey.algorithm.name is "AES-CTR"
 PASS clonedKey.algorithm.length is 256
 PASS clonedKey.usages.join(',') is "wrapKey,unwrapKey"
-Serialized key bytes: 4b010b20c1012000112233445546778899aabbccddeeff000102030405060708090a0b0c0d0e0f00
+Serialized key bytes: 5c4b010b20c1012000112233445546778899aabbccddeeff000102030405060708090a0b0c0d0e0f
 PASS: Cloned key exported data should be [00112233445546778899aabbccddeeff000102030405060708090a0b0c0d0e0f] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -54,7 +54,7 @@
 PASS clonedKey.algorithm.name is "AES-CTR"
 PASS clonedKey.algorithm.length is 128
 PASS clonedKey.usages.join(',') is "wrapKey,unwrapKey"
-Serialized key bytes: 4b010b10c0011030112233445566778899aabbccddeeff00
+Serialized key bytes: 5c4b010b10c0011030112233445566778899aabbccddeeff
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -71,7 +71,7 @@
 PASS clonedKey.algorithm.name is "AES-CTR"
 PASS clonedKey.algorithm.length is 256
 PASS clonedKey.usages.join(',') is "wrapKey,unwrapKey"
-Serialized key bytes: 4b010b20c0012000112233445546778899aabbccddeeff000102030405060708090a0b0c0d0e0f00
+Serialized key bytes: 5c4b010b20c0012000112233445546778899aabbccddeeff000102030405060708090a0b0c0d0e0f
 
 PASS successfullyParsed is true
 
diff --git a/third_party/WebKit/LayoutTests/crypto/subtle/aes-gcm/cloneKey-expected.txt b/third_party/WebKit/LayoutTests/crypto/subtle/aes-gcm/cloneKey-expected.txt
index ca5251a..c66d1b7 100644
--- a/third_party/WebKit/LayoutTests/crypto/subtle/aes-gcm/cloneKey-expected.txt
+++ b/third_party/WebKit/LayoutTests/crypto/subtle/aes-gcm/cloneKey-expected.txt
@@ -18,7 +18,7 @@
 PASS clonedKey.algorithm.name is "AES-GCM"
 PASS clonedKey.algorithm.length is 128
 PASS clonedKey.usages.join(',') is "encrypt"
-Serialized key bytes: 4b010910031030112233445566778899aabbccddeeff
+Serialized key bytes: 5c4b010910031030112233445566778899aabbccddeeff00
 PASS: Cloned key exported data should be [30112233445566778899aabbccddeeff] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -36,7 +36,7 @@
 PASS clonedKey.algorithm.name is "AES-GCM"
 PASS clonedKey.algorithm.length is 256
 PASS clonedKey.usages.join(',') is "encrypt"
-Serialized key bytes: 4b010920032000112233445546778899aabbccddeeff000102030405060708090a0b0c0d0e0f
+Serialized key bytes: 5c4b010920032000112233445546778899aabbccddeeff000102030405060708090a0b0c0d0e0f00
 PASS: Cloned key exported data should be [00112233445546778899aabbccddeeff000102030405060708090a0b0c0d0e0f] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -54,7 +54,7 @@
 PASS clonedKey.algorithm.name is "AES-GCM"
 PASS clonedKey.algorithm.length is 128
 PASS clonedKey.usages.join(',') is "decrypt,wrapKey"
-Serialized key bytes: 4b010910451030112233445566778899aabbccddeeff
+Serialized key bytes: 5c4b010910451030112233445566778899aabbccddeeff00
 PASS: Cloned key exported data should be [30112233445566778899aabbccddeeff] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -72,7 +72,7 @@
 PASS clonedKey.algorithm.name is "AES-GCM"
 PASS clonedKey.algorithm.length is 256
 PASS clonedKey.usages.join(',') is "decrypt,wrapKey"
-Serialized key bytes: 4b010920452000112233445546778899aabbccddeeff000102030405060708090a0b0c0d0e0f
+Serialized key bytes: 5c4b010920452000112233445546778899aabbccddeeff000102030405060708090a0b0c0d0e0f00
 PASS: Cloned key exported data should be [00112233445546778899aabbccddeeff000102030405060708090a0b0c0d0e0f] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -90,7 +90,7 @@
 PASS clonedKey.algorithm.name is "AES-GCM"
 PASS clonedKey.algorithm.length is 128
 PASS clonedKey.usages.join(',') is "encrypt,wrapKey,unwrapKey"
-Serialized key bytes: 4b010910c3011030112233445566778899aabbccddeeff00
+Serialized key bytes: 5c4b010910c3011030112233445566778899aabbccddeeff
 PASS: Cloned key exported data should be [30112233445566778899aabbccddeeff] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -108,7 +108,7 @@
 PASS clonedKey.algorithm.name is "AES-GCM"
 PASS clonedKey.algorithm.length is 256
 PASS clonedKey.usages.join(',') is "encrypt,wrapKey,unwrapKey"
-Serialized key bytes: 4b010920c3012000112233445546778899aabbccddeeff000102030405060708090a0b0c0d0e0f00
+Serialized key bytes: 5c4b010920c3012000112233445546778899aabbccddeeff000102030405060708090a0b0c0d0e0f
 PASS: Cloned key exported data should be [00112233445546778899aabbccddeeff000102030405060708090a0b0c0d0e0f] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -126,7 +126,7 @@
 PASS clonedKey.algorithm.name is "AES-GCM"
 PASS clonedKey.algorithm.length is 128
 PASS clonedKey.usages.join(',') is "encrypt"
-Serialized key bytes: 4b010910021030112233445566778899aabbccddeeff
+Serialized key bytes: 5c4b010910021030112233445566778899aabbccddeeff00
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -143,7 +143,7 @@
 PASS clonedKey.algorithm.name is "AES-GCM"
 PASS clonedKey.algorithm.length is 256
 PASS clonedKey.usages.join(',') is "encrypt"
-Serialized key bytes: 4b010920022000112233445546778899aabbccddeeff000102030405060708090a0b0c0d0e0f
+Serialized key bytes: 5c4b010920022000112233445546778899aabbccddeeff000102030405060708090a0b0c0d0e0f00
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -160,7 +160,7 @@
 PASS clonedKey.algorithm.name is "AES-GCM"
 PASS clonedKey.algorithm.length is 128
 PASS clonedKey.usages.join(',') is "decrypt,wrapKey"
-Serialized key bytes: 4b010910441030112233445566778899aabbccddeeff
+Serialized key bytes: 5c4b010910441030112233445566778899aabbccddeeff00
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -177,7 +177,7 @@
 PASS clonedKey.algorithm.name is "AES-GCM"
 PASS clonedKey.algorithm.length is 256
 PASS clonedKey.usages.join(',') is "decrypt,wrapKey"
-Serialized key bytes: 4b010920442000112233445546778899aabbccddeeff000102030405060708090a0b0c0d0e0f
+Serialized key bytes: 5c4b010920442000112233445546778899aabbccddeeff000102030405060708090a0b0c0d0e0f00
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -194,7 +194,7 @@
 PASS clonedKey.algorithm.name is "AES-GCM"
 PASS clonedKey.algorithm.length is 128
 PASS clonedKey.usages.join(',') is "encrypt,wrapKey,unwrapKey"
-Serialized key bytes: 4b010910c2011030112233445566778899aabbccddeeff00
+Serialized key bytes: 5c4b010910c2011030112233445566778899aabbccddeeff
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -211,7 +211,7 @@
 PASS clonedKey.algorithm.name is "AES-GCM"
 PASS clonedKey.algorithm.length is 256
 PASS clonedKey.usages.join(',') is "encrypt,wrapKey,unwrapKey"
-Serialized key bytes: 4b010920c2012000112233445546778899aabbccddeeff000102030405060708090a0b0c0d0e0f00
+Serialized key bytes: 5c4b010920c2012000112233445546778899aabbccddeeff000102030405060708090a0b0c0d0e0f
 
 PASS successfullyParsed is true
 
diff --git a/third_party/WebKit/LayoutTests/crypto/subtle/aes-kw/cloneKey-expected.txt b/third_party/WebKit/LayoutTests/crypto/subtle/aes-kw/cloneKey-expected.txt
index e7414d31..1be6f63 100644
--- a/third_party/WebKit/LayoutTests/crypto/subtle/aes-kw/cloneKey-expected.txt
+++ b/third_party/WebKit/LayoutTests/crypto/subtle/aes-kw/cloneKey-expected.txt
@@ -18,7 +18,7 @@
 PASS clonedKey.algorithm.name is "AES-KW"
 PASS clonedKey.algorithm.length is 128
 PASS clonedKey.usages.join(',') is "wrapKey,unwrapKey"
-Serialized key bytes: 4b010c10c1011030112233445566778899aabbccddeeff00
+Serialized key bytes: 5c4b010c10c1011030112233445566778899aabbccddeeff
 PASS: Cloned key exported data should be [30112233445566778899aabbccddeeff] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -36,7 +36,7 @@
 PASS clonedKey.algorithm.name is "AES-KW"
 PASS clonedKey.algorithm.length is 256
 PASS clonedKey.usages.join(',') is "wrapKey,unwrapKey"
-Serialized key bytes: 4b010c20c1012000112233445546778899aabbccddeeff000102030405060708090a0b0c0d0e0f00
+Serialized key bytes: 5c4b010c20c1012000112233445546778899aabbccddeeff000102030405060708090a0b0c0d0e0f
 PASS: Cloned key exported data should be [00112233445546778899aabbccddeeff000102030405060708090a0b0c0d0e0f] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -54,7 +54,7 @@
 PASS clonedKey.algorithm.name is "AES-KW"
 PASS clonedKey.algorithm.length is 128
 PASS clonedKey.usages.join(',') is "wrapKey,unwrapKey"
-Serialized key bytes: 4b010c10c0011030112233445566778899aabbccddeeff00
+Serialized key bytes: 5c4b010c10c0011030112233445566778899aabbccddeeff
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -71,7 +71,7 @@
 PASS clonedKey.algorithm.name is "AES-KW"
 PASS clonedKey.algorithm.length is 256
 PASS clonedKey.usages.join(',') is "wrapKey,unwrapKey"
-Serialized key bytes: 4b010c20c0012000112233445546778899aabbccddeeff000102030405060708090a0b0c0d0e0f00
+Serialized key bytes: 5c4b010c20c0012000112233445546778899aabbccddeeff000102030405060708090a0b0c0d0e0f
 
 PASS successfullyParsed is true
 
diff --git a/third_party/WebKit/LayoutTests/crypto/subtle/ecdh/cloneKey-expected.txt b/third_party/WebKit/LayoutTests/crypto/subtle/ecdh/cloneKey-expected.txt
index 22828f6..af00cab 100644
--- a/third_party/WebKit/LayoutTests/crypto/subtle/ecdh/cloneKey-expected.txt
+++ b/third_party/WebKit/LayoutTests/crypto/subtle/ecdh/cloneKey-expected.txt
@@ -18,7 +18,7 @@
 PASS clonedKey.algorithm.name is "ECDH"
 PASS clonedKey.algorithm.namedCurve is "P-256"
 PASS clonedKey.usages.join(',') is ""
-Serialized key bytes: 4b050f0101015b3059301306072a8648ce3d020106082a8648ce3d030107034200049cb0cf69303dafc761d4e4687b4ecf039e6d34ab964af80810d8d558a4a8d6f72d51233a1788920a86ee08a1962c79efa317fb7879e297dad2146db995fa1c78
+Serialized key bytes: 5c4b050f0101015b3059301306072a8648ce3d020106082a8648ce3d030107034200049cb0cf69303dafc761d4e4687b4ecf039e6d34ab964af80810d8d558a4a8d6f72d51233a1788920a86ee08a1962c79efa317fb7879e297dad2146db995fa1c7800
 PASS: Cloned key exported data should be [3059301306072a8648ce3d020106082a8648ce3d030107034200049cb0cf69303dafc761d4e4687b4ecf039e6d34ab964af80810d8d558a4a8d6f72d51233a1788920a86ee08a1962c79efa317fb7879e297dad2146db995fa1c78] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -36,7 +36,7 @@
 PASS clonedKey.algorithm.name is "ECDH"
 PASS clonedKey.algorithm.namedCurve is "P-256"
 PASS clonedKey.usages.join(',') is ""
-Serialized key bytes: 4b050f0101005b3059301306072a8648ce3d020106082a8648ce3d030107034200049cb0cf69303dafc761d4e4687b4ecf039e6d34ab964af80810d8d558a4a8d6f72d51233a1788920a86ee08a1962c79efa317fb7879e297dad2146db995fa1c78
+Serialized key bytes: 5c4b050f0101005b3059301306072a8648ce3d020106082a8648ce3d030107034200049cb0cf69303dafc761d4e4687b4ecf039e6d34ab964af80810d8d558a4a8d6f72d51233a1788920a86ee08a1962c79efa317fb7879e297dad2146db995fa1c7800
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "public"
@@ -53,7 +53,7 @@
 PASS clonedKey.algorithm.name is "ECDH"
 PASS clonedKey.algorithm.namedCurve is "P-384"
 PASS clonedKey.usages.join(',') is ""
-Serialized key bytes: 4b050f010201783076301006072a8648ce3d020106052b81040022036200040874a2e0b8ff448f0e54321e27f4f1e64d064cdeb7d26f458c32e930120f4e57dc85c2693f977eed4a8ecc8db981b4d91f69446df4f4c6f5de19003f45f891d0ebcd2fffdb5c81c040e8d6994c43c7feedb98a4a31edfb35e89a30013c3b926700
+Serialized key bytes: 5c4b050f010201783076301006072a8648ce3d020106052b81040022036200040874a2e0b8ff448f0e54321e27f4f1e64d064cdeb7d26f458c32e930120f4e57dc85c2693f977eed4a8ecc8db981b4d91f69446df4f4c6f5de19003f45f891d0ebcd2fffdb5c81c040e8d6994c43c7feedb98a4a31edfb35e89a30013c3b9267
 PASS: Cloned key exported data should be [3076301006072a8648ce3d020106052b81040022036200040874a2e0b8ff448f0e54321e27f4f1e64d064cdeb7d26f458c32e930120f4e57dc85c2693f977eed4a8ecc8db981b4d91f69446df4f4c6f5de19003f45f891d0ebcd2fffdb5c81c040e8d6994c43c7feedb98a4a31edfb35e89a30013c3b9267] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -71,7 +71,7 @@
 PASS clonedKey.algorithm.name is "ECDH"
 PASS clonedKey.algorithm.namedCurve is "P-384"
 PASS clonedKey.usages.join(',') is ""
-Serialized key bytes: 4b050f010200783076301006072a8648ce3d020106052b81040022036200040874a2e0b8ff448f0e54321e27f4f1e64d064cdeb7d26f458c32e930120f4e57dc85c2693f977eed4a8ecc8db981b4d91f69446df4f4c6f5de19003f45f891d0ebcd2fffdb5c81c040e8d6994c43c7feedb98a4a31edfb35e89a30013c3b926700
+Serialized key bytes: 5c4b050f010200783076301006072a8648ce3d020106052b81040022036200040874a2e0b8ff448f0e54321e27f4f1e64d064cdeb7d26f458c32e930120f4e57dc85c2693f977eed4a8ecc8db981b4d91f69446df4f4c6f5de19003f45f891d0ebcd2fffdb5c81c040e8d6994c43c7feedb98a4a31edfb35e89a30013c3b9267
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "public"
@@ -88,7 +88,7 @@
 PASS clonedKey.algorithm.name is "ECDH"
 PASS clonedKey.algorithm.namedCurve is "P-521"
 PASS clonedKey.usages.join(',') is ""
-Serialized key bytes: 4b050f0103019e0130819b301006072a8648ce3d020106052b81040023038186000400f50a08703250c15f043c8c46e99783435245cf98f4f2694b0e2f8d029a514dd6f0b086d4ed892000cd5590107aae69c4c0a7a95f7cf74e5770a07d5db55bce4ab400f2c770bab8b9be4cdb6ecd3dc26c698da0d2599cebf3d904f7f9ca3a55e64731810d73cd317264e50baba4bc2860857e16d6cbb79501bc9e3a32bd172ea8a71dee
+Serialized key bytes: 5c4b050f0103019e0130819b301006072a8648ce3d020106052b81040023038186000400f50a08703250c15f043c8c46e99783435245cf98f4f2694b0e2f8d029a514dd6f0b086d4ed892000cd5590107aae69c4c0a7a95f7cf74e5770a07d5db55bce4ab400f2c770bab8b9be4cdb6ecd3dc26c698da0d2599cebf3d904f7f9ca3a55e64731810d73cd317264e50baba4bc2860857e16d6cbb79501bc9e3a32bd172ea8a71dee00
 PASS: Cloned key exported data should be [30819b301006072a8648ce3d020106052b81040023038186000400f50a08703250c15f043c8c46e99783435245cf98f4f2694b0e2f8d029a514dd6f0b086d4ed892000cd5590107aae69c4c0a7a95f7cf74e5770a07d5db55bce4ab400f2c770bab8b9be4cdb6ecd3dc26c698da0d2599cebf3d904f7f9ca3a55e64731810d73cd317264e50baba4bc2860857e16d6cbb79501bc9e3a32bd172ea8a71dee] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -106,7 +106,7 @@
 PASS clonedKey.algorithm.name is "ECDH"
 PASS clonedKey.algorithm.namedCurve is "P-521"
 PASS clonedKey.usages.join(',') is ""
-Serialized key bytes: 4b050f0103009e0130819b301006072a8648ce3d020106052b81040023038186000400f50a08703250c15f043c8c46e99783435245cf98f4f2694b0e2f8d029a514dd6f0b086d4ed892000cd5590107aae69c4c0a7a95f7cf74e5770a07d5db55bce4ab400f2c770bab8b9be4cdb6ecd3dc26c698da0d2599cebf3d904f7f9ca3a55e64731810d73cd317264e50baba4bc2860857e16d6cbb79501bc9e3a32bd172ea8a71dee
+Serialized key bytes: 5c4b050f0103009e0130819b301006072a8648ce3d020106052b81040023038186000400f50a08703250c15f043c8c46e99783435245cf98f4f2694b0e2f8d029a514dd6f0b086d4ed892000cd5590107aae69c4c0a7a95f7cf74e5770a07d5db55bce4ab400f2c770bab8b9be4cdb6ecd3dc26c698da0d2599cebf3d904f7f9ca3a55e64731810d73cd317264e50baba4bc2860857e16d6cbb79501bc9e3a32bd172ea8a71dee00
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "private"
@@ -123,7 +123,7 @@
 PASS clonedKey.algorithm.name is "ECDH"
 PASS clonedKey.algorithm.namedCurve is "P-256"
 PASS clonedKey.usages.join(',') is "deriveBits"
-Serialized key bytes: 4b050f020181028a01308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b02010104201fe33950c5f461124ae992c2bdfdf1c73b1615f571bd567e60d19aa1f48cdf42a144034200047c110c66dcfda807f6e69e45ddb3c74f69a1484d203e8dc5ada8e9a9dd7cb3c70df448986e51bde5d1576f99901f9c2c6a806a47fd907643a72b835597efc8c600
+Serialized key bytes: 5c4b050f020181028a01308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b02010104201fe33950c5f461124ae992c2bdfdf1c73b1615f571bd567e60d19aa1f48cdf42a144034200047c110c66dcfda807f6e69e45ddb3c74f69a1484d203e8dc5ada8e9a9dd7cb3c70df448986e51bde5d1576f99901f9c2c6a806a47fd907643a72b835597efc8c6
 PASS: Cloned key exported data should be [308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b02010104201fe33950c5f461124ae992c2bdfdf1c73b1615f571bd567e60d19aa1f48cdf42a144034200047c110c66dcfda807f6e69e45ddb3c74f69a1484d203e8dc5ada8e9a9dd7cb3c70df448986e51bde5d1576f99901f9c2c6a806a47fd907643a72b835597efc8c6] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -141,7 +141,7 @@
 PASS clonedKey.algorithm.name is "ECDH"
 PASS clonedKey.algorithm.namedCurve is "P-256"
 PASS clonedKey.usages.join(',') is "deriveBits"
-Serialized key bytes: 4b050f020180028a01308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b02010104201fe33950c5f461124ae992c2bdfdf1c73b1615f571bd567e60d19aa1f48cdf42a144034200047c110c66dcfda807f6e69e45ddb3c74f69a1484d203e8dc5ada8e9a9dd7cb3c70df448986e51bde5d1576f99901f9c2c6a806a47fd907643a72b835597efc8c600
+Serialized key bytes: 5c4b050f020180028a01308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b02010104201fe33950c5f461124ae992c2bdfdf1c73b1615f571bd567e60d19aa1f48cdf42a144034200047c110c66dcfda807f6e69e45ddb3c74f69a1484d203e8dc5ada8e9a9dd7cb3c70df448986e51bde5d1576f99901f9c2c6a806a47fd907643a72b835597efc8c6
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "private"
@@ -158,7 +158,7 @@
 PASS clonedKey.algorithm.name is "ECDH"
 PASS clonedKey.algorithm.namedCurve is "P-384"
 PASS clonedKey.usages.join(',') is "deriveBits"
-Serialized key bytes: 4b050f02028102b9013081b6020100301006072a8648ce3d020106052b8104002204819e30819b0201010430a492ce8fa90084c227e1a32f7974d39e9ff67a7e8705ec3419b35fb607582bebd461e0b1520ac76ec2dd4e9b63ebae71a16403620004e55fee6c49d8d523f5ce7bf9c0425ce4ff650708b7de5cfb095901523979a7f042602db30854735369813b5c3f5ef86828f59cc5dc509892a988d38a8e2519de3d0c4fd0fbdb0993e38f18506c17606c5e24249246f1ce94983a5361c5be983e
+Serialized key bytes: 5c4b050f02028102b9013081b6020100301006072a8648ce3d020106052b8104002204819e30819b0201010430a492ce8fa90084c227e1a32f7974d39e9ff67a7e8705ec3419b35fb607582bebd461e0b1520ac76ec2dd4e9b63ebae71a16403620004e55fee6c49d8d523f5ce7bf9c0425ce4ff650708b7de5cfb095901523979a7f042602db30854735369813b5c3f5ef86828f59cc5dc509892a988d38a8e2519de3d0c4fd0fbdb0993e38f18506c17606c5e24249246f1ce94983a5361c5be983e00
 PASS: Cloned key exported data should be [3081b6020100301006072a8648ce3d020106052b8104002204819e30819b0201010430a492ce8fa90084c227e1a32f7974d39e9ff67a7e8705ec3419b35fb607582bebd461e0b1520ac76ec2dd4e9b63ebae71a16403620004e55fee6c49d8d523f5ce7bf9c0425ce4ff650708b7de5cfb095901523979a7f042602db30854735369813b5c3f5ef86828f59cc5dc509892a988d38a8e2519de3d0c4fd0fbdb0993e38f18506c17606c5e24249246f1ce94983a5361c5be983e] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -176,7 +176,7 @@
 PASS clonedKey.algorithm.name is "ECDH"
 PASS clonedKey.algorithm.namedCurve is "P-384"
 PASS clonedKey.usages.join(',') is "deriveBits"
-Serialized key bytes: 4b050f02028002b9013081b6020100301006072a8648ce3d020106052b8104002204819e30819b0201010430a492ce8fa90084c227e1a32f7974d39e9ff67a7e8705ec3419b35fb607582bebd461e0b1520ac76ec2dd4e9b63ebae71a16403620004e55fee6c49d8d523f5ce7bf9c0425ce4ff650708b7de5cfb095901523979a7f042602db30854735369813b5c3f5ef86828f59cc5dc509892a988d38a8e2519de3d0c4fd0fbdb0993e38f18506c17606c5e24249246f1ce94983a5361c5be983e
+Serialized key bytes: 5c4b050f02028002b9013081b6020100301006072a8648ce3d020106052b8104002204819e30819b0201010430a492ce8fa90084c227e1a32f7974d39e9ff67a7e8705ec3419b35fb607582bebd461e0b1520ac76ec2dd4e9b63ebae71a16403620004e55fee6c49d8d523f5ce7bf9c0425ce4ff650708b7de5cfb095901523979a7f042602db30854735369813b5c3f5ef86828f59cc5dc509892a988d38a8e2519de3d0c4fd0fbdb0993e38f18506c17606c5e24249246f1ce94983a5361c5be983e00
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "private"
@@ -193,7 +193,7 @@
 PASS clonedKey.algorithm.name is "ECDH"
 PASS clonedKey.algorithm.namedCurve is "P-521"
 PASS clonedKey.usages.join(',') is "deriveBits"
-Serialized key bytes: 4b050f02038102f1013081ee020100301006072a8648ce3d020106052b810400230481d63081d3020101044201bd56bd106118eda246155bd43b42b8e13f0a6e25dd3bb376026fab4dc92b6157bc6dfec2d15dd3d0cf2a39aa68494042af48ba9601118da82c6f2108a3a203ad74a181890381860004012fbcaeffa6a51f3ee4d3d2b51c5dec6d7c726ca353fc014ea2bf7cfbb9b910d32cbfa6a00fe39b6cdb8946f22775398b2e233c0cf144d78c8a7742b5c7a3bb5d23009cdef823dd7bf9a79e8cceacd2e4527c231d0ae5967af0958e931d7ddccf2805a3e618dc3039fec9febbd33052fe4c0fee98f033106064982d88f4e03549d4a64d
+Serialized key bytes: 5c4b050f02038102f1013081ee020100301006072a8648ce3d020106052b810400230481d63081d3020101044201bd56bd106118eda246155bd43b42b8e13f0a6e25dd3bb376026fab4dc92b6157bc6dfec2d15dd3d0cf2a39aa68494042af48ba9601118da82c6f2108a3a203ad74a181890381860004012fbcaeffa6a51f3ee4d3d2b51c5dec6d7c726ca353fc014ea2bf7cfbb9b910d32cbfa6a00fe39b6cdb8946f22775398b2e233c0cf144d78c8a7742b5c7a3bb5d23009cdef823dd7bf9a79e8cceacd2e4527c231d0ae5967af0958e931d7ddccf2805a3e618dc3039fec9febbd33052fe4c0fee98f033106064982d88f4e03549d4a64d00
 PASS: Cloned key exported data should be [3081ee020100301006072a8648ce3d020106052b810400230481d63081d3020101044201bd56bd106118eda246155bd43b42b8e13f0a6e25dd3bb376026fab4dc92b6157bc6dfec2d15dd3d0cf2a39aa68494042af48ba9601118da82c6f2108a3a203ad74a181890381860004012fbcaeffa6a51f3ee4d3d2b51c5dec6d7c726ca353fc014ea2bf7cfbb9b910d32cbfa6a00fe39b6cdb8946f22775398b2e233c0cf144d78c8a7742b5c7a3bb5d23009cdef823dd7bf9a79e8cceacd2e4527c231d0ae5967af0958e931d7ddccf2805a3e618dc3039fec9febbd33052fe4c0fee98f033106064982d88f4e03549d4a64d] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -211,7 +211,7 @@
 PASS clonedKey.algorithm.name is "ECDH"
 PASS clonedKey.algorithm.namedCurve is "P-521"
 PASS clonedKey.usages.join(',') is "deriveBits"
-Serialized key bytes: 4b050f02038002f1013081ee020100301006072a8648ce3d020106052b810400230481d63081d3020101044201bd56bd106118eda246155bd43b42b8e13f0a6e25dd3bb376026fab4dc92b6157bc6dfec2d15dd3d0cf2a39aa68494042af48ba9601118da82c6f2108a3a203ad74a181890381860004012fbcaeffa6a51f3ee4d3d2b51c5dec6d7c726ca353fc014ea2bf7cfbb9b910d32cbfa6a00fe39b6cdb8946f22775398b2e233c0cf144d78c8a7742b5c7a3bb5d23009cdef823dd7bf9a79e8cceacd2e4527c231d0ae5967af0958e931d7ddccf2805a3e618dc3039fec9febbd33052fe4c0fee98f033106064982d88f4e03549d4a64d
+Serialized key bytes: 5c4b050f02038002f1013081ee020100301006072a8648ce3d020106052b810400230481d63081d3020101044201bd56bd106118eda246155bd43b42b8e13f0a6e25dd3bb376026fab4dc92b6157bc6dfec2d15dd3d0cf2a39aa68494042af48ba9601118da82c6f2108a3a203ad74a181890381860004012fbcaeffa6a51f3ee4d3d2b51c5dec6d7c726ca353fc014ea2bf7cfbb9b910d32cbfa6a00fe39b6cdb8946f22775398b2e233c0cf144d78c8a7742b5c7a3bb5d23009cdef823dd7bf9a79e8cceacd2e4527c231d0ae5967af0958e931d7ddccf2805a3e618dc3039fec9febbd33052fe4c0fee98f033106064982d88f4e03549d4a64d00
 
 PASS successfullyParsed is true
 
diff --git a/third_party/WebKit/LayoutTests/crypto/subtle/ecdsa/cloneKey-expected.txt b/third_party/WebKit/LayoutTests/crypto/subtle/ecdsa/cloneKey-expected.txt
index 3cc9b97..9335d3b 100644
--- a/third_party/WebKit/LayoutTests/crypto/subtle/ecdsa/cloneKey-expected.txt
+++ b/third_party/WebKit/LayoutTests/crypto/subtle/ecdsa/cloneKey-expected.txt
@@ -18,7 +18,7 @@
 PASS clonedKey.algorithm.name is "ECDSA"
 PASS clonedKey.algorithm.namedCurve is "P-256"
 PASS clonedKey.usages.join(',') is ""
-Serialized key bytes: 4b050e0101015b3059301306072a8648ce3d020106082a8648ce3d030107034200049cb0cf69303dafc761d4e4687b4ecf039e6d34ab964af80810d8d558a4a8d6f72d51233a1788920a86ee08a1962c79efa317fb7879e297dad2146db995fa1c78
+Serialized key bytes: 5c4b050e0101015b3059301306072a8648ce3d020106082a8648ce3d030107034200049cb0cf69303dafc761d4e4687b4ecf039e6d34ab964af80810d8d558a4a8d6f72d51233a1788920a86ee08a1962c79efa317fb7879e297dad2146db995fa1c7800
 PASS: Cloned key exported data should be [3059301306072a8648ce3d020106082a8648ce3d030107034200049cb0cf69303dafc761d4e4687b4ecf039e6d34ab964af80810d8d558a4a8d6f72d51233a1788920a86ee08a1962c79efa317fb7879e297dad2146db995fa1c78] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -36,7 +36,7 @@
 PASS clonedKey.algorithm.name is "ECDSA"
 PASS clonedKey.algorithm.namedCurve is "P-256"
 PASS clonedKey.usages.join(',') is "verify"
-Serialized key bytes: 4b050e0101115b3059301306072a8648ce3d020106082a8648ce3d030107034200049cb0cf69303dafc761d4e4687b4ecf039e6d34ab964af80810d8d558a4a8d6f72d51233a1788920a86ee08a1962c79efa317fb7879e297dad2146db995fa1c78
+Serialized key bytes: 5c4b050e0101115b3059301306072a8648ce3d020106082a8648ce3d030107034200049cb0cf69303dafc761d4e4687b4ecf039e6d34ab964af80810d8d558a4a8d6f72d51233a1788920a86ee08a1962c79efa317fb7879e297dad2146db995fa1c7800
 PASS: Cloned key exported data should be [3059301306072a8648ce3d020106082a8648ce3d030107034200049cb0cf69303dafc761d4e4687b4ecf039e6d34ab964af80810d8d558a4a8d6f72d51233a1788920a86ee08a1962c79efa317fb7879e297dad2146db995fa1c78] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -54,7 +54,7 @@
 PASS clonedKey.algorithm.name is "ECDSA"
 PASS clonedKey.algorithm.namedCurve is "P-256"
 PASS clonedKey.usages.join(',') is ""
-Serialized key bytes: 4b050e0101005b3059301306072a8648ce3d020106082a8648ce3d030107034200049cb0cf69303dafc761d4e4687b4ecf039e6d34ab964af80810d8d558a4a8d6f72d51233a1788920a86ee08a1962c79efa317fb7879e297dad2146db995fa1c78
+Serialized key bytes: 5c4b050e0101005b3059301306072a8648ce3d020106082a8648ce3d030107034200049cb0cf69303dafc761d4e4687b4ecf039e6d34ab964af80810d8d558a4a8d6f72d51233a1788920a86ee08a1962c79efa317fb7879e297dad2146db995fa1c7800
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "public"
@@ -71,7 +71,7 @@
 PASS clonedKey.algorithm.name is "ECDSA"
 PASS clonedKey.algorithm.namedCurve is "P-256"
 PASS clonedKey.usages.join(',') is "verify"
-Serialized key bytes: 4b050e0101105b3059301306072a8648ce3d020106082a8648ce3d030107034200049cb0cf69303dafc761d4e4687b4ecf039e6d34ab964af80810d8d558a4a8d6f72d51233a1788920a86ee08a1962c79efa317fb7879e297dad2146db995fa1c78
+Serialized key bytes: 5c4b050e0101105b3059301306072a8648ce3d020106082a8648ce3d030107034200049cb0cf69303dafc761d4e4687b4ecf039e6d34ab964af80810d8d558a4a8d6f72d51233a1788920a86ee08a1962c79efa317fb7879e297dad2146db995fa1c7800
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "public"
@@ -88,7 +88,7 @@
 PASS clonedKey.algorithm.name is "ECDSA"
 PASS clonedKey.algorithm.namedCurve is "P-384"
 PASS clonedKey.usages.join(',') is ""
-Serialized key bytes: 4b050e010201783076301006072a8648ce3d020106052b81040022036200040874a2e0b8ff448f0e54321e27f4f1e64d064cdeb7d26f458c32e930120f4e57dc85c2693f977eed4a8ecc8db981b4d91f69446df4f4c6f5de19003f45f891d0ebcd2fffdb5c81c040e8d6994c43c7feedb98a4a31edfb35e89a30013c3b926700
+Serialized key bytes: 5c4b050e010201783076301006072a8648ce3d020106052b81040022036200040874a2e0b8ff448f0e54321e27f4f1e64d064cdeb7d26f458c32e930120f4e57dc85c2693f977eed4a8ecc8db981b4d91f69446df4f4c6f5de19003f45f891d0ebcd2fffdb5c81c040e8d6994c43c7feedb98a4a31edfb35e89a30013c3b9267
 PASS: Cloned key exported data should be [3076301006072a8648ce3d020106052b81040022036200040874a2e0b8ff448f0e54321e27f4f1e64d064cdeb7d26f458c32e930120f4e57dc85c2693f977eed4a8ecc8db981b4d91f69446df4f4c6f5de19003f45f891d0ebcd2fffdb5c81c040e8d6994c43c7feedb98a4a31edfb35e89a30013c3b9267] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -106,7 +106,7 @@
 PASS clonedKey.algorithm.name is "ECDSA"
 PASS clonedKey.algorithm.namedCurve is "P-384"
 PASS clonedKey.usages.join(',') is "verify"
-Serialized key bytes: 4b050e010211783076301006072a8648ce3d020106052b81040022036200040874a2e0b8ff448f0e54321e27f4f1e64d064cdeb7d26f458c32e930120f4e57dc85c2693f977eed4a8ecc8db981b4d91f69446df4f4c6f5de19003f45f891d0ebcd2fffdb5c81c040e8d6994c43c7feedb98a4a31edfb35e89a30013c3b926700
+Serialized key bytes: 5c4b050e010211783076301006072a8648ce3d020106052b81040022036200040874a2e0b8ff448f0e54321e27f4f1e64d064cdeb7d26f458c32e930120f4e57dc85c2693f977eed4a8ecc8db981b4d91f69446df4f4c6f5de19003f45f891d0ebcd2fffdb5c81c040e8d6994c43c7feedb98a4a31edfb35e89a30013c3b9267
 PASS: Cloned key exported data should be [3076301006072a8648ce3d020106052b81040022036200040874a2e0b8ff448f0e54321e27f4f1e64d064cdeb7d26f458c32e930120f4e57dc85c2693f977eed4a8ecc8db981b4d91f69446df4f4c6f5de19003f45f891d0ebcd2fffdb5c81c040e8d6994c43c7feedb98a4a31edfb35e89a30013c3b9267] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -124,7 +124,7 @@
 PASS clonedKey.algorithm.name is "ECDSA"
 PASS clonedKey.algorithm.namedCurve is "P-384"
 PASS clonedKey.usages.join(',') is ""
-Serialized key bytes: 4b050e010200783076301006072a8648ce3d020106052b81040022036200040874a2e0b8ff448f0e54321e27f4f1e64d064cdeb7d26f458c32e930120f4e57dc85c2693f977eed4a8ecc8db981b4d91f69446df4f4c6f5de19003f45f891d0ebcd2fffdb5c81c040e8d6994c43c7feedb98a4a31edfb35e89a30013c3b926700
+Serialized key bytes: 5c4b050e010200783076301006072a8648ce3d020106052b81040022036200040874a2e0b8ff448f0e54321e27f4f1e64d064cdeb7d26f458c32e930120f4e57dc85c2693f977eed4a8ecc8db981b4d91f69446df4f4c6f5de19003f45f891d0ebcd2fffdb5c81c040e8d6994c43c7feedb98a4a31edfb35e89a30013c3b9267
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "public"
@@ -141,7 +141,7 @@
 PASS clonedKey.algorithm.name is "ECDSA"
 PASS clonedKey.algorithm.namedCurve is "P-384"
 PASS clonedKey.usages.join(',') is "verify"
-Serialized key bytes: 4b050e010210783076301006072a8648ce3d020106052b81040022036200040874a2e0b8ff448f0e54321e27f4f1e64d064cdeb7d26f458c32e930120f4e57dc85c2693f977eed4a8ecc8db981b4d91f69446df4f4c6f5de19003f45f891d0ebcd2fffdb5c81c040e8d6994c43c7feedb98a4a31edfb35e89a30013c3b926700
+Serialized key bytes: 5c4b050e010210783076301006072a8648ce3d020106052b81040022036200040874a2e0b8ff448f0e54321e27f4f1e64d064cdeb7d26f458c32e930120f4e57dc85c2693f977eed4a8ecc8db981b4d91f69446df4f4c6f5de19003f45f891d0ebcd2fffdb5c81c040e8d6994c43c7feedb98a4a31edfb35e89a30013c3b9267
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "public"
@@ -158,7 +158,7 @@
 PASS clonedKey.algorithm.name is "ECDSA"
 PASS clonedKey.algorithm.namedCurve is "P-521"
 PASS clonedKey.usages.join(',') is ""
-Serialized key bytes: 4b050e0103019e0130819b301006072a8648ce3d020106052b81040023038186000400f50a08703250c15f043c8c46e99783435245cf98f4f2694b0e2f8d029a514dd6f0b086d4ed892000cd5590107aae69c4c0a7a95f7cf74e5770a07d5db55bce4ab400f2c770bab8b9be4cdb6ecd3dc26c698da0d2599cebf3d904f7f9ca3a55e64731810d73cd317264e50baba4bc2860857e16d6cbb79501bc9e3a32bd172ea8a71dee
+Serialized key bytes: 5c4b050e0103019e0130819b301006072a8648ce3d020106052b81040023038186000400f50a08703250c15f043c8c46e99783435245cf98f4f2694b0e2f8d029a514dd6f0b086d4ed892000cd5590107aae69c4c0a7a95f7cf74e5770a07d5db55bce4ab400f2c770bab8b9be4cdb6ecd3dc26c698da0d2599cebf3d904f7f9ca3a55e64731810d73cd317264e50baba4bc2860857e16d6cbb79501bc9e3a32bd172ea8a71dee00
 PASS: Cloned key exported data should be [30819b301006072a8648ce3d020106052b81040023038186000400f50a08703250c15f043c8c46e99783435245cf98f4f2694b0e2f8d029a514dd6f0b086d4ed892000cd5590107aae69c4c0a7a95f7cf74e5770a07d5db55bce4ab400f2c770bab8b9be4cdb6ecd3dc26c698da0d2599cebf3d904f7f9ca3a55e64731810d73cd317264e50baba4bc2860857e16d6cbb79501bc9e3a32bd172ea8a71dee] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -176,7 +176,7 @@
 PASS clonedKey.algorithm.name is "ECDSA"
 PASS clonedKey.algorithm.namedCurve is "P-521"
 PASS clonedKey.usages.join(',') is "verify"
-Serialized key bytes: 4b050e0103119e0130819b301006072a8648ce3d020106052b81040023038186000400f50a08703250c15f043c8c46e99783435245cf98f4f2694b0e2f8d029a514dd6f0b086d4ed892000cd5590107aae69c4c0a7a95f7cf74e5770a07d5db55bce4ab400f2c770bab8b9be4cdb6ecd3dc26c698da0d2599cebf3d904f7f9ca3a55e64731810d73cd317264e50baba4bc2860857e16d6cbb79501bc9e3a32bd172ea8a71dee
+Serialized key bytes: 5c4b050e0103119e0130819b301006072a8648ce3d020106052b81040023038186000400f50a08703250c15f043c8c46e99783435245cf98f4f2694b0e2f8d029a514dd6f0b086d4ed892000cd5590107aae69c4c0a7a95f7cf74e5770a07d5db55bce4ab400f2c770bab8b9be4cdb6ecd3dc26c698da0d2599cebf3d904f7f9ca3a55e64731810d73cd317264e50baba4bc2860857e16d6cbb79501bc9e3a32bd172ea8a71dee00
 PASS: Cloned key exported data should be [30819b301006072a8648ce3d020106052b81040023038186000400f50a08703250c15f043c8c46e99783435245cf98f4f2694b0e2f8d029a514dd6f0b086d4ed892000cd5590107aae69c4c0a7a95f7cf74e5770a07d5db55bce4ab400f2c770bab8b9be4cdb6ecd3dc26c698da0d2599cebf3d904f7f9ca3a55e64731810d73cd317264e50baba4bc2860857e16d6cbb79501bc9e3a32bd172ea8a71dee] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -194,7 +194,7 @@
 PASS clonedKey.algorithm.name is "ECDSA"
 PASS clonedKey.algorithm.namedCurve is "P-521"
 PASS clonedKey.usages.join(',') is ""
-Serialized key bytes: 4b050e0103009e0130819b301006072a8648ce3d020106052b81040023038186000400f50a08703250c15f043c8c46e99783435245cf98f4f2694b0e2f8d029a514dd6f0b086d4ed892000cd5590107aae69c4c0a7a95f7cf74e5770a07d5db55bce4ab400f2c770bab8b9be4cdb6ecd3dc26c698da0d2599cebf3d904f7f9ca3a55e64731810d73cd317264e50baba4bc2860857e16d6cbb79501bc9e3a32bd172ea8a71dee
+Serialized key bytes: 5c4b050e0103009e0130819b301006072a8648ce3d020106052b81040023038186000400f50a08703250c15f043c8c46e99783435245cf98f4f2694b0e2f8d029a514dd6f0b086d4ed892000cd5590107aae69c4c0a7a95f7cf74e5770a07d5db55bce4ab400f2c770bab8b9be4cdb6ecd3dc26c698da0d2599cebf3d904f7f9ca3a55e64731810d73cd317264e50baba4bc2860857e16d6cbb79501bc9e3a32bd172ea8a71dee00
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "public"
@@ -211,7 +211,7 @@
 PASS clonedKey.algorithm.name is "ECDSA"
 PASS clonedKey.algorithm.namedCurve is "P-521"
 PASS clonedKey.usages.join(',') is "verify"
-Serialized key bytes: 4b050e0103109e0130819b301006072a8648ce3d020106052b81040023038186000400f50a08703250c15f043c8c46e99783435245cf98f4f2694b0e2f8d029a514dd6f0b086d4ed892000cd5590107aae69c4c0a7a95f7cf74e5770a07d5db55bce4ab400f2c770bab8b9be4cdb6ecd3dc26c698da0d2599cebf3d904f7f9ca3a55e64731810d73cd317264e50baba4bc2860857e16d6cbb79501bc9e3a32bd172ea8a71dee
+Serialized key bytes: 5c4b050e0103109e0130819b301006072a8648ce3d020106052b81040023038186000400f50a08703250c15f043c8c46e99783435245cf98f4f2694b0e2f8d029a514dd6f0b086d4ed892000cd5590107aae69c4c0a7a95f7cf74e5770a07d5db55bce4ab400f2c770bab8b9be4cdb6ecd3dc26c698da0d2599cebf3d904f7f9ca3a55e64731810d73cd317264e50baba4bc2860857e16d6cbb79501bc9e3a32bd172ea8a71dee00
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "private"
@@ -228,7 +228,7 @@
 PASS clonedKey.algorithm.name is "ECDSA"
 PASS clonedKey.algorithm.namedCurve is "P-256"
 PASS clonedKey.usages.join(',') is "sign"
-Serialized key bytes: 4b050e0201098a01308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b02010104201fe33950c5f461124ae992c2bdfdf1c73b1615f571bd567e60d19aa1f48cdf42a144034200047c110c66dcfda807f6e69e45ddb3c74f69a1484d203e8dc5ada8e9a9dd7cb3c70df448986e51bde5d1576f99901f9c2c6a806a47fd907643a72b835597efc8c6
+Serialized key bytes: 5c4b050e0201098a01308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b02010104201fe33950c5f461124ae992c2bdfdf1c73b1615f571bd567e60d19aa1f48cdf42a144034200047c110c66dcfda807f6e69e45ddb3c74f69a1484d203e8dc5ada8e9a9dd7cb3c70df448986e51bde5d1576f99901f9c2c6a806a47fd907643a72b835597efc8c600
 PASS: Cloned key exported data should be [308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b02010104201fe33950c5f461124ae992c2bdfdf1c73b1615f571bd567e60d19aa1f48cdf42a144034200047c110c66dcfda807f6e69e45ddb3c74f69a1484d203e8dc5ada8e9a9dd7cb3c70df448986e51bde5d1576f99901f9c2c6a806a47fd907643a72b835597efc8c6] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -246,7 +246,7 @@
 PASS clonedKey.algorithm.name is "ECDSA"
 PASS clonedKey.algorithm.namedCurve is "P-256"
 PASS clonedKey.usages.join(',') is "sign"
-Serialized key bytes: 4b050e0201088a01308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b02010104201fe33950c5f461124ae992c2bdfdf1c73b1615f571bd567e60d19aa1f48cdf42a144034200047c110c66dcfda807f6e69e45ddb3c74f69a1484d203e8dc5ada8e9a9dd7cb3c70df448986e51bde5d1576f99901f9c2c6a806a47fd907643a72b835597efc8c6
+Serialized key bytes: 5c4b050e0201088a01308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b02010104201fe33950c5f461124ae992c2bdfdf1c73b1615f571bd567e60d19aa1f48cdf42a144034200047c110c66dcfda807f6e69e45ddb3c74f69a1484d203e8dc5ada8e9a9dd7cb3c70df448986e51bde5d1576f99901f9c2c6a806a47fd907643a72b835597efc8c600
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "private"
@@ -263,7 +263,7 @@
 PASS clonedKey.algorithm.name is "ECDSA"
 PASS clonedKey.algorithm.namedCurve is "P-384"
 PASS clonedKey.usages.join(',') is "sign"
-Serialized key bytes: 4b050e020209b9013081b6020100301006072a8648ce3d020106052b8104002204819e30819b0201010430a492ce8fa90084c227e1a32f7974d39e9ff67a7e8705ec3419b35fb607582bebd461e0b1520ac76ec2dd4e9b63ebae71a16403620004e55fee6c49d8d523f5ce7bf9c0425ce4ff650708b7de5cfb095901523979a7f042602db30854735369813b5c3f5ef86828f59cc5dc509892a988d38a8e2519de3d0c4fd0fbdb0993e38f18506c17606c5e24249246f1ce94983a5361c5be983e00
+Serialized key bytes: 5c4b050e020209b9013081b6020100301006072a8648ce3d020106052b8104002204819e30819b0201010430a492ce8fa90084c227e1a32f7974d39e9ff67a7e8705ec3419b35fb607582bebd461e0b1520ac76ec2dd4e9b63ebae71a16403620004e55fee6c49d8d523f5ce7bf9c0425ce4ff650708b7de5cfb095901523979a7f042602db30854735369813b5c3f5ef86828f59cc5dc509892a988d38a8e2519de3d0c4fd0fbdb0993e38f18506c17606c5e24249246f1ce94983a5361c5be983e
 PASS: Cloned key exported data should be [3081b6020100301006072a8648ce3d020106052b8104002204819e30819b0201010430a492ce8fa90084c227e1a32f7974d39e9ff67a7e8705ec3419b35fb607582bebd461e0b1520ac76ec2dd4e9b63ebae71a16403620004e55fee6c49d8d523f5ce7bf9c0425ce4ff650708b7de5cfb095901523979a7f042602db30854735369813b5c3f5ef86828f59cc5dc509892a988d38a8e2519de3d0c4fd0fbdb0993e38f18506c17606c5e24249246f1ce94983a5361c5be983e] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -281,7 +281,7 @@
 PASS clonedKey.algorithm.name is "ECDSA"
 PASS clonedKey.algorithm.namedCurve is "P-384"
 PASS clonedKey.usages.join(',') is "sign"
-Serialized key bytes: 4b050e020208b9013081b6020100301006072a8648ce3d020106052b8104002204819e30819b0201010430a492ce8fa90084c227e1a32f7974d39e9ff67a7e8705ec3419b35fb607582bebd461e0b1520ac76ec2dd4e9b63ebae71a16403620004e55fee6c49d8d523f5ce7bf9c0425ce4ff650708b7de5cfb095901523979a7f042602db30854735369813b5c3f5ef86828f59cc5dc509892a988d38a8e2519de3d0c4fd0fbdb0993e38f18506c17606c5e24249246f1ce94983a5361c5be983e00
+Serialized key bytes: 5c4b050e020208b9013081b6020100301006072a8648ce3d020106052b8104002204819e30819b0201010430a492ce8fa90084c227e1a32f7974d39e9ff67a7e8705ec3419b35fb607582bebd461e0b1520ac76ec2dd4e9b63ebae71a16403620004e55fee6c49d8d523f5ce7bf9c0425ce4ff650708b7de5cfb095901523979a7f042602db30854735369813b5c3f5ef86828f59cc5dc509892a988d38a8e2519de3d0c4fd0fbdb0993e38f18506c17606c5e24249246f1ce94983a5361c5be983e
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "private"
@@ -298,7 +298,7 @@
 PASS clonedKey.algorithm.name is "ECDSA"
 PASS clonedKey.algorithm.namedCurve is "P-521"
 PASS clonedKey.usages.join(',') is "sign"
-Serialized key bytes: 4b050e020309f1013081ee020100301006072a8648ce3d020106052b810400230481d63081d3020101044201bd56bd106118eda246155bd43b42b8e13f0a6e25dd3bb376026fab4dc92b6157bc6dfec2d15dd3d0cf2a39aa68494042af48ba9601118da82c6f2108a3a203ad74a181890381860004012fbcaeffa6a51f3ee4d3d2b51c5dec6d7c726ca353fc014ea2bf7cfbb9b910d32cbfa6a00fe39b6cdb8946f22775398b2e233c0cf144d78c8a7742b5c7a3bb5d23009cdef823dd7bf9a79e8cceacd2e4527c231d0ae5967af0958e931d7ddccf2805a3e618dc3039fec9febbd33052fe4c0fee98f033106064982d88f4e03549d4a64d00
+Serialized key bytes: 5c4b050e020309f1013081ee020100301006072a8648ce3d020106052b810400230481d63081d3020101044201bd56bd106118eda246155bd43b42b8e13f0a6e25dd3bb376026fab4dc92b6157bc6dfec2d15dd3d0cf2a39aa68494042af48ba9601118da82c6f2108a3a203ad74a181890381860004012fbcaeffa6a51f3ee4d3d2b51c5dec6d7c726ca353fc014ea2bf7cfbb9b910d32cbfa6a00fe39b6cdb8946f22775398b2e233c0cf144d78c8a7742b5c7a3bb5d23009cdef823dd7bf9a79e8cceacd2e4527c231d0ae5967af0958e931d7ddccf2805a3e618dc3039fec9febbd33052fe4c0fee98f033106064982d88f4e03549d4a64d
 PASS: Cloned key exported data should be [3081ee020100301006072a8648ce3d020106052b810400230481d63081d3020101044201bd56bd106118eda246155bd43b42b8e13f0a6e25dd3bb376026fab4dc92b6157bc6dfec2d15dd3d0cf2a39aa68494042af48ba9601118da82c6f2108a3a203ad74a181890381860004012fbcaeffa6a51f3ee4d3d2b51c5dec6d7c726ca353fc014ea2bf7cfbb9b910d32cbfa6a00fe39b6cdb8946f22775398b2e233c0cf144d78c8a7742b5c7a3bb5d23009cdef823dd7bf9a79e8cceacd2e4527c231d0ae5967af0958e931d7ddccf2805a3e618dc3039fec9febbd33052fe4c0fee98f033106064982d88f4e03549d4a64d] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -316,7 +316,7 @@
 PASS clonedKey.algorithm.name is "ECDSA"
 PASS clonedKey.algorithm.namedCurve is "P-521"
 PASS clonedKey.usages.join(',') is "sign"
-Serialized key bytes: 4b050e020308f1013081ee020100301006072a8648ce3d020106052b810400230481d63081d3020101044201bd56bd106118eda246155bd43b42b8e13f0a6e25dd3bb376026fab4dc92b6157bc6dfec2d15dd3d0cf2a39aa68494042af48ba9601118da82c6f2108a3a203ad74a181890381860004012fbcaeffa6a51f3ee4d3d2b51c5dec6d7c726ca353fc014ea2bf7cfbb9b910d32cbfa6a00fe39b6cdb8946f22775398b2e233c0cf144d78c8a7742b5c7a3bb5d23009cdef823dd7bf9a79e8cceacd2e4527c231d0ae5967af0958e931d7ddccf2805a3e618dc3039fec9febbd33052fe4c0fee98f033106064982d88f4e03549d4a64d00
+Serialized key bytes: 5c4b050e020308f1013081ee020100301006072a8648ce3d020106052b810400230481d63081d3020101044201bd56bd106118eda246155bd43b42b8e13f0a6e25dd3bb376026fab4dc92b6157bc6dfec2d15dd3d0cf2a39aa68494042af48ba9601118da82c6f2108a3a203ad74a181890381860004012fbcaeffa6a51f3ee4d3d2b51c5dec6d7c726ca353fc014ea2bf7cfbb9b910d32cbfa6a00fe39b6cdb8946f22775398b2e233c0cf144d78c8a7742b5c7a3bb5d23009cdef823dd7bf9a79e8cceacd2e4527c231d0ae5967af0958e931d7ddccf2805a3e618dc3039fec9febbd33052fe4c0fee98f033106064982d88f4e03549d4a64d
 
 PASS successfullyParsed is true
 
diff --git a/third_party/WebKit/LayoutTests/crypto/subtle/hkdf/cloneKey-expected.txt b/third_party/WebKit/LayoutTests/crypto/subtle/hkdf/cloneKey-expected.txt
index 3f3c40c..ec493bd 100644
--- a/third_party/WebKit/LayoutTests/crypto/subtle/hkdf/cloneKey-expected.txt
+++ b/third_party/WebKit/LayoutTests/crypto/subtle/hkdf/cloneKey-expected.txt
@@ -16,7 +16,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "HKDF"
 PASS clonedKey.usages.join(',') is "deriveBits"
-Serialized key bytes: 4b0610800200
+Serialized key bytes: 5c4b061080020000
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -31,7 +31,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "HKDF"
 PASS clonedKey.usages.join(',') is "deriveBits"
-Serialized key bytes: 4b06108002013000
+Serialized key bytes: 5c4b061080020130
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -46,7 +46,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "HKDF"
 PASS clonedKey.usages.join(',') is "deriveBits"
-Serialized key bytes: 4b06108002080011223344554677
+Serialized key bytes: 5c4b0610800208001122334455467700
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -61,7 +61,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "HKDF"
 PASS clonedKey.usages.join(',') is "deriveBits"
-Serialized key bytes: 4b061080020b00112233445546778899aa00
+Serialized key bytes: 5c4b061080020b00112233445546778899aa
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -76,7 +76,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "HKDF"
 PASS clonedKey.usages.join(',') is "deriveBits"
-Serialized key bytes: 4b061080021030112233445566778899aabbccddeeff
+Serialized key bytes: 5c4b061080021030112233445566778899aabbccddeeff00
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -91,7 +91,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "HKDF"
 PASS clonedKey.usages.join(',') is "deriveKey"
-Serialized key bytes: 4b0610200000
+Serialized key bytes: 5c4b06102000
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -106,7 +106,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "HKDF"
 PASS clonedKey.usages.join(',') is "deriveKey"
-Serialized key bytes: 4b0610200130
+Serialized key bytes: 5c4b061020013000
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -121,7 +121,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "HKDF"
 PASS clonedKey.usages.join(',') is "deriveKey"
-Serialized key bytes: 4b06102008001122334455467700
+Serialized key bytes: 5c4b061020080011223344554677
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -136,7 +136,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "HKDF"
 PASS clonedKey.usages.join(',') is "deriveKey"
-Serialized key bytes: 4b0610200b00112233445546778899aa
+Serialized key bytes: 5c4b0610200b00112233445546778899aa00
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -151,7 +151,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "HKDF"
 PASS clonedKey.usages.join(',') is "deriveKey"
-Serialized key bytes: 4b0610201030112233445566778899aabbccddeeff00
+Serialized key bytes: 5c4b0610201030112233445566778899aabbccddeeff
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -166,7 +166,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "HKDF"
 PASS clonedKey.usages.join(',') is "deriveKey,deriveBits"
-Serialized key bytes: 4b0610a00200
+Serialized key bytes: 5c4b0610a0020000
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -181,7 +181,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "HKDF"
 PASS clonedKey.usages.join(',') is "deriveKey,deriveBits"
-Serialized key bytes: 4b0610a002013000
+Serialized key bytes: 5c4b0610a0020130
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -196,7 +196,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "HKDF"
 PASS clonedKey.usages.join(',') is "deriveKey,deriveBits"
-Serialized key bytes: 4b0610a002080011223344554677
+Serialized key bytes: 5c4b0610a00208001122334455467700
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -211,7 +211,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "HKDF"
 PASS clonedKey.usages.join(',') is "deriveKey,deriveBits"
-Serialized key bytes: 4b0610a0020b00112233445546778899aa00
+Serialized key bytes: 5c4b0610a0020b00112233445546778899aa
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -226,7 +226,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "HKDF"
 PASS clonedKey.usages.join(',') is "deriveKey,deriveBits"
-Serialized key bytes: 4b0610a0021030112233445566778899aabbccddeeff
+Serialized key bytes: 5c4b0610a0021030112233445566778899aabbccddeeff00
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -241,7 +241,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "HKDF"
 PASS clonedKey.usages.join(',') is "deriveBits"
-Serialized key bytes: 4b0610800200
+Serialized key bytes: 5c4b061080020000
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -256,7 +256,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "HKDF"
 PASS clonedKey.usages.join(',') is "deriveBits"
-Serialized key bytes: 4b06108002013000
+Serialized key bytes: 5c4b061080020130
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -271,7 +271,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "HKDF"
 PASS clonedKey.usages.join(',') is "deriveBits"
-Serialized key bytes: 4b06108002080011223344554677
+Serialized key bytes: 5c4b0610800208001122334455467700
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -286,7 +286,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "HKDF"
 PASS clonedKey.usages.join(',') is "deriveBits"
-Serialized key bytes: 4b061080020b00112233445546778899aa00
+Serialized key bytes: 5c4b061080020b00112233445546778899aa
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -301,7 +301,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "HKDF"
 PASS clonedKey.usages.join(',') is "deriveBits"
-Serialized key bytes: 4b061080021030112233445566778899aabbccddeeff
+Serialized key bytes: 5c4b061080021030112233445566778899aabbccddeeff00
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -316,7 +316,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "HKDF"
 PASS clonedKey.usages.join(',') is "deriveKey"
-Serialized key bytes: 4b0610200000
+Serialized key bytes: 5c4b06102000
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -331,7 +331,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "HKDF"
 PASS clonedKey.usages.join(',') is "deriveKey"
-Serialized key bytes: 4b0610200130
+Serialized key bytes: 5c4b061020013000
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -346,7 +346,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "HKDF"
 PASS clonedKey.usages.join(',') is "deriveKey"
-Serialized key bytes: 4b06102008001122334455467700
+Serialized key bytes: 5c4b061020080011223344554677
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -361,7 +361,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "HKDF"
 PASS clonedKey.usages.join(',') is "deriveKey"
-Serialized key bytes: 4b0610200b00112233445546778899aa
+Serialized key bytes: 5c4b0610200b00112233445546778899aa00
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -376,7 +376,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "HKDF"
 PASS clonedKey.usages.join(',') is "deriveKey"
-Serialized key bytes: 4b0610201030112233445566778899aabbccddeeff00
+Serialized key bytes: 5c4b0610201030112233445566778899aabbccddeeff
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -391,7 +391,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "HKDF"
 PASS clonedKey.usages.join(',') is "deriveKey,deriveBits"
-Serialized key bytes: 4b0610a00200
+Serialized key bytes: 5c4b0610a0020000
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -406,7 +406,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "HKDF"
 PASS clonedKey.usages.join(',') is "deriveKey,deriveBits"
-Serialized key bytes: 4b0610a002013000
+Serialized key bytes: 5c4b0610a0020130
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -421,7 +421,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "HKDF"
 PASS clonedKey.usages.join(',') is "deriveKey,deriveBits"
-Serialized key bytes: 4b0610a002080011223344554677
+Serialized key bytes: 5c4b0610a00208001122334455467700
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -436,7 +436,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "HKDF"
 PASS clonedKey.usages.join(',') is "deriveKey,deriveBits"
-Serialized key bytes: 4b0610a0020b00112233445546778899aa00
+Serialized key bytes: 5c4b0610a0020b00112233445546778899aa
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -451,7 +451,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "HKDF"
 PASS clonedKey.usages.join(',') is "deriveKey,deriveBits"
-Serialized key bytes: 4b0610a0021030112233445566778899aabbccddeeff
+Serialized key bytes: 5c4b0610a0021030112233445566778899aabbccddeeff00
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -466,7 +466,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "HKDF"
 PASS clonedKey.usages.join(',') is "deriveBits"
-Serialized key bytes: 4b0610800200
+Serialized key bytes: 5c4b061080020000
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -481,7 +481,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "HKDF"
 PASS clonedKey.usages.join(',') is "deriveBits"
-Serialized key bytes: 4b06108002013000
+Serialized key bytes: 5c4b061080020130
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -496,7 +496,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "HKDF"
 PASS clonedKey.usages.join(',') is "deriveBits"
-Serialized key bytes: 4b06108002080011223344554677
+Serialized key bytes: 5c4b0610800208001122334455467700
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -511,7 +511,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "HKDF"
 PASS clonedKey.usages.join(',') is "deriveBits"
-Serialized key bytes: 4b061080020b00112233445546778899aa00
+Serialized key bytes: 5c4b061080020b00112233445546778899aa
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -526,7 +526,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "HKDF"
 PASS clonedKey.usages.join(',') is "deriveBits"
-Serialized key bytes: 4b061080021030112233445566778899aabbccddeeff
+Serialized key bytes: 5c4b061080021030112233445566778899aabbccddeeff00
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -541,7 +541,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "HKDF"
 PASS clonedKey.usages.join(',') is "deriveKey"
-Serialized key bytes: 4b0610200000
+Serialized key bytes: 5c4b06102000
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -556,7 +556,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "HKDF"
 PASS clonedKey.usages.join(',') is "deriveKey"
-Serialized key bytes: 4b0610200130
+Serialized key bytes: 5c4b061020013000
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -571,7 +571,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "HKDF"
 PASS clonedKey.usages.join(',') is "deriveKey"
-Serialized key bytes: 4b06102008001122334455467700
+Serialized key bytes: 5c4b061020080011223344554677
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -586,7 +586,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "HKDF"
 PASS clonedKey.usages.join(',') is "deriveKey"
-Serialized key bytes: 4b0610200b00112233445546778899aa
+Serialized key bytes: 5c4b0610200b00112233445546778899aa00
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -601,7 +601,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "HKDF"
 PASS clonedKey.usages.join(',') is "deriveKey"
-Serialized key bytes: 4b0610201030112233445566778899aabbccddeeff00
+Serialized key bytes: 5c4b0610201030112233445566778899aabbccddeeff
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -616,7 +616,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "HKDF"
 PASS clonedKey.usages.join(',') is "deriveKey,deriveBits"
-Serialized key bytes: 4b0610a00200
+Serialized key bytes: 5c4b0610a0020000
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -631,7 +631,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "HKDF"
 PASS clonedKey.usages.join(',') is "deriveKey,deriveBits"
-Serialized key bytes: 4b0610a002013000
+Serialized key bytes: 5c4b0610a0020130
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -646,7 +646,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "HKDF"
 PASS clonedKey.usages.join(',') is "deriveKey,deriveBits"
-Serialized key bytes: 4b0610a002080011223344554677
+Serialized key bytes: 5c4b0610a00208001122334455467700
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -661,7 +661,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "HKDF"
 PASS clonedKey.usages.join(',') is "deriveKey,deriveBits"
-Serialized key bytes: 4b0610a0020b00112233445546778899aa00
+Serialized key bytes: 5c4b0610a0020b00112233445546778899aa
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -676,7 +676,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "HKDF"
 PASS clonedKey.usages.join(',') is "deriveKey,deriveBits"
-Serialized key bytes: 4b0610a0021030112233445566778899aabbccddeeff
+Serialized key bytes: 5c4b0610a0021030112233445566778899aabbccddeeff00
 
 PASS successfullyParsed is true
 
diff --git a/third_party/WebKit/LayoutTests/crypto/subtle/hmac/cloneKey-expected.txt b/third_party/WebKit/LayoutTests/crypto/subtle/hmac/cloneKey-expected.txt
index 5f57e09..0c3233e 100644
--- a/third_party/WebKit/LayoutTests/crypto/subtle/hmac/cloneKey-expected.txt
+++ b/third_party/WebKit/LayoutTests/crypto/subtle/hmac/cloneKey-expected.txt
@@ -20,7 +20,7 @@
 PASS clonedKey.algorithm.length is 8
 PASS clonedKey.algorithm.hash.name is "SHA-1"
 PASS clonedKey.usages.join(',') is "sign"
-Serialized key bytes: 4b02010509013000
+Serialized key bytes: 5c4b020105090130
 PASS: Cloned key exported data should be [30] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -40,7 +40,7 @@
 PASS clonedKey.algorithm.length is 64
 PASS clonedKey.algorithm.hash.name is "SHA-1"
 PASS clonedKey.usages.join(',') is "sign"
-Serialized key bytes: 4b02080509080011223344554677
+Serialized key bytes: 5c4b0208050908001122334455467700
 PASS: Cloned key exported data should be [0011223344554677] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -60,7 +60,7 @@
 PASS clonedKey.algorithm.length is 88
 PASS clonedKey.algorithm.hash.name is "SHA-1"
 PASS clonedKey.usages.join(',') is "sign"
-Serialized key bytes: 4b020b05090b00112233445546778899aa00
+Serialized key bytes: 5c4b020b05090b00112233445546778899aa
 PASS: Cloned key exported data should be [00112233445546778899aa] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -80,7 +80,7 @@
 PASS clonedKey.algorithm.length is 128
 PASS clonedKey.algorithm.hash.name is "SHA-1"
 PASS clonedKey.usages.join(',') is "sign"
-Serialized key bytes: 4b021005091030112233445566778899aabbccddeeff
+Serialized key bytes: 5c4b021005091030112233445566778899aabbccddeeff00
 PASS: Cloned key exported data should be [30112233445566778899aabbccddeeff] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -100,7 +100,7 @@
 PASS clonedKey.algorithm.length is 8
 PASS clonedKey.algorithm.hash.name is "SHA-1"
 PASS clonedKey.usages.join(',') is "verify"
-Serialized key bytes: 4b02010511013000
+Serialized key bytes: 5c4b020105110130
 PASS: Cloned key exported data should be [30] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -120,7 +120,7 @@
 PASS clonedKey.algorithm.length is 64
 PASS clonedKey.algorithm.hash.name is "SHA-1"
 PASS clonedKey.usages.join(',') is "verify"
-Serialized key bytes: 4b02080511080011223344554677
+Serialized key bytes: 5c4b0208051108001122334455467700
 PASS: Cloned key exported data should be [0011223344554677] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -140,7 +140,7 @@
 PASS clonedKey.algorithm.length is 88
 PASS clonedKey.algorithm.hash.name is "SHA-1"
 PASS clonedKey.usages.join(',') is "verify"
-Serialized key bytes: 4b020b05110b00112233445546778899aa00
+Serialized key bytes: 5c4b020b05110b00112233445546778899aa
 PASS: Cloned key exported data should be [00112233445546778899aa] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -160,7 +160,7 @@
 PASS clonedKey.algorithm.length is 128
 PASS clonedKey.algorithm.hash.name is "SHA-1"
 PASS clonedKey.usages.join(',') is "verify"
-Serialized key bytes: 4b021005111030112233445566778899aabbccddeeff
+Serialized key bytes: 5c4b021005111030112233445566778899aabbccddeeff00
 PASS: Cloned key exported data should be [30112233445566778899aabbccddeeff] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -180,7 +180,7 @@
 PASS clonedKey.algorithm.length is 8
 PASS clonedKey.algorithm.hash.name is "SHA-1"
 PASS clonedKey.usages.join(',') is "sign,verify"
-Serialized key bytes: 4b02010519013000
+Serialized key bytes: 5c4b020105190130
 PASS: Cloned key exported data should be [30] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -200,7 +200,7 @@
 PASS clonedKey.algorithm.length is 64
 PASS clonedKey.algorithm.hash.name is "SHA-1"
 PASS clonedKey.usages.join(',') is "sign,verify"
-Serialized key bytes: 4b02080519080011223344554677
+Serialized key bytes: 5c4b0208051908001122334455467700
 PASS: Cloned key exported data should be [0011223344554677] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -220,7 +220,7 @@
 PASS clonedKey.algorithm.length is 88
 PASS clonedKey.algorithm.hash.name is "SHA-1"
 PASS clonedKey.usages.join(',') is "sign,verify"
-Serialized key bytes: 4b020b05190b00112233445546778899aa00
+Serialized key bytes: 5c4b020b05190b00112233445546778899aa
 PASS: Cloned key exported data should be [00112233445546778899aa] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -240,7 +240,7 @@
 PASS clonedKey.algorithm.length is 128
 PASS clonedKey.algorithm.hash.name is "SHA-1"
 PASS clonedKey.usages.join(',') is "sign,verify"
-Serialized key bytes: 4b021005191030112233445566778899aabbccddeeff
+Serialized key bytes: 5c4b021005191030112233445566778899aabbccddeeff00
 PASS: Cloned key exported data should be [30112233445566778899aabbccddeeff] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -260,7 +260,7 @@
 PASS clonedKey.algorithm.length is 8
 PASS clonedKey.algorithm.hash.name is "SHA-1"
 PASS clonedKey.usages.join(',') is "sign"
-Serialized key bytes: 4b02010508013000
+Serialized key bytes: 5c4b020105080130
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -279,7 +279,7 @@
 PASS clonedKey.algorithm.length is 64
 PASS clonedKey.algorithm.hash.name is "SHA-1"
 PASS clonedKey.usages.join(',') is "sign"
-Serialized key bytes: 4b02080508080011223344554677
+Serialized key bytes: 5c4b0208050808001122334455467700
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -298,7 +298,7 @@
 PASS clonedKey.algorithm.length is 88
 PASS clonedKey.algorithm.hash.name is "SHA-1"
 PASS clonedKey.usages.join(',') is "sign"
-Serialized key bytes: 4b020b05080b00112233445546778899aa00
+Serialized key bytes: 5c4b020b05080b00112233445546778899aa
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -317,7 +317,7 @@
 PASS clonedKey.algorithm.length is 128
 PASS clonedKey.algorithm.hash.name is "SHA-1"
 PASS clonedKey.usages.join(',') is "sign"
-Serialized key bytes: 4b021005081030112233445566778899aabbccddeeff
+Serialized key bytes: 5c4b021005081030112233445566778899aabbccddeeff00
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -336,7 +336,7 @@
 PASS clonedKey.algorithm.length is 8
 PASS clonedKey.algorithm.hash.name is "SHA-1"
 PASS clonedKey.usages.join(',') is "verify"
-Serialized key bytes: 4b02010510013000
+Serialized key bytes: 5c4b020105100130
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -355,7 +355,7 @@
 PASS clonedKey.algorithm.length is 64
 PASS clonedKey.algorithm.hash.name is "SHA-1"
 PASS clonedKey.usages.join(',') is "verify"
-Serialized key bytes: 4b02080510080011223344554677
+Serialized key bytes: 5c4b0208051008001122334455467700
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -374,7 +374,7 @@
 PASS clonedKey.algorithm.length is 88
 PASS clonedKey.algorithm.hash.name is "SHA-1"
 PASS clonedKey.usages.join(',') is "verify"
-Serialized key bytes: 4b020b05100b00112233445546778899aa00
+Serialized key bytes: 5c4b020b05100b00112233445546778899aa
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -393,7 +393,7 @@
 PASS clonedKey.algorithm.length is 128
 PASS clonedKey.algorithm.hash.name is "SHA-1"
 PASS clonedKey.usages.join(',') is "verify"
-Serialized key bytes: 4b021005101030112233445566778899aabbccddeeff
+Serialized key bytes: 5c4b021005101030112233445566778899aabbccddeeff00
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -412,7 +412,7 @@
 PASS clonedKey.algorithm.length is 8
 PASS clonedKey.algorithm.hash.name is "SHA-1"
 PASS clonedKey.usages.join(',') is "sign,verify"
-Serialized key bytes: 4b02010518013000
+Serialized key bytes: 5c4b020105180130
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -431,7 +431,7 @@
 PASS clonedKey.algorithm.length is 64
 PASS clonedKey.algorithm.hash.name is "SHA-1"
 PASS clonedKey.usages.join(',') is "sign,verify"
-Serialized key bytes: 4b02080518080011223344554677
+Serialized key bytes: 5c4b0208051808001122334455467700
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -450,7 +450,7 @@
 PASS clonedKey.algorithm.length is 88
 PASS clonedKey.algorithm.hash.name is "SHA-1"
 PASS clonedKey.usages.join(',') is "sign,verify"
-Serialized key bytes: 4b020b05180b00112233445546778899aa00
+Serialized key bytes: 5c4b020b05180b00112233445546778899aa
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -469,7 +469,7 @@
 PASS clonedKey.algorithm.length is 128
 PASS clonedKey.algorithm.hash.name is "SHA-1"
 PASS clonedKey.usages.join(',') is "sign,verify"
-Serialized key bytes: 4b021005181030112233445566778899aabbccddeeff
+Serialized key bytes: 5c4b021005181030112233445566778899aabbccddeeff00
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -488,7 +488,7 @@
 PASS clonedKey.algorithm.length is 8
 PASS clonedKey.algorithm.hash.name is "SHA-256"
 PASS clonedKey.usages.join(',') is "sign"
-Serialized key bytes: 4b02010609013000
+Serialized key bytes: 5c4b020106090130
 PASS: Cloned key exported data should be [30] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -508,7 +508,7 @@
 PASS clonedKey.algorithm.length is 64
 PASS clonedKey.algorithm.hash.name is "SHA-256"
 PASS clonedKey.usages.join(',') is "sign"
-Serialized key bytes: 4b02080609080011223344554677
+Serialized key bytes: 5c4b0208060908001122334455467700
 PASS: Cloned key exported data should be [0011223344554677] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -528,7 +528,7 @@
 PASS clonedKey.algorithm.length is 88
 PASS clonedKey.algorithm.hash.name is "SHA-256"
 PASS clonedKey.usages.join(',') is "sign"
-Serialized key bytes: 4b020b06090b00112233445546778899aa00
+Serialized key bytes: 5c4b020b06090b00112233445546778899aa
 PASS: Cloned key exported data should be [00112233445546778899aa] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -548,7 +548,7 @@
 PASS clonedKey.algorithm.length is 128
 PASS clonedKey.algorithm.hash.name is "SHA-256"
 PASS clonedKey.usages.join(',') is "sign"
-Serialized key bytes: 4b021006091030112233445566778899aabbccddeeff
+Serialized key bytes: 5c4b021006091030112233445566778899aabbccddeeff00
 PASS: Cloned key exported data should be [30112233445566778899aabbccddeeff] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -568,7 +568,7 @@
 PASS clonedKey.algorithm.length is 8
 PASS clonedKey.algorithm.hash.name is "SHA-256"
 PASS clonedKey.usages.join(',') is "verify"
-Serialized key bytes: 4b02010611013000
+Serialized key bytes: 5c4b020106110130
 PASS: Cloned key exported data should be [30] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -588,7 +588,7 @@
 PASS clonedKey.algorithm.length is 64
 PASS clonedKey.algorithm.hash.name is "SHA-256"
 PASS clonedKey.usages.join(',') is "verify"
-Serialized key bytes: 4b02080611080011223344554677
+Serialized key bytes: 5c4b0208061108001122334455467700
 PASS: Cloned key exported data should be [0011223344554677] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -608,7 +608,7 @@
 PASS clonedKey.algorithm.length is 88
 PASS clonedKey.algorithm.hash.name is "SHA-256"
 PASS clonedKey.usages.join(',') is "verify"
-Serialized key bytes: 4b020b06110b00112233445546778899aa00
+Serialized key bytes: 5c4b020b06110b00112233445546778899aa
 PASS: Cloned key exported data should be [00112233445546778899aa] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -628,7 +628,7 @@
 PASS clonedKey.algorithm.length is 128
 PASS clonedKey.algorithm.hash.name is "SHA-256"
 PASS clonedKey.usages.join(',') is "verify"
-Serialized key bytes: 4b021006111030112233445566778899aabbccddeeff
+Serialized key bytes: 5c4b021006111030112233445566778899aabbccddeeff00
 PASS: Cloned key exported data should be [30112233445566778899aabbccddeeff] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -648,7 +648,7 @@
 PASS clonedKey.algorithm.length is 8
 PASS clonedKey.algorithm.hash.name is "SHA-256"
 PASS clonedKey.usages.join(',') is "sign,verify"
-Serialized key bytes: 4b02010619013000
+Serialized key bytes: 5c4b020106190130
 PASS: Cloned key exported data should be [30] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -668,7 +668,7 @@
 PASS clonedKey.algorithm.length is 64
 PASS clonedKey.algorithm.hash.name is "SHA-256"
 PASS clonedKey.usages.join(',') is "sign,verify"
-Serialized key bytes: 4b02080619080011223344554677
+Serialized key bytes: 5c4b0208061908001122334455467700
 PASS: Cloned key exported data should be [0011223344554677] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -688,7 +688,7 @@
 PASS clonedKey.algorithm.length is 88
 PASS clonedKey.algorithm.hash.name is "SHA-256"
 PASS clonedKey.usages.join(',') is "sign,verify"
-Serialized key bytes: 4b020b06190b00112233445546778899aa00
+Serialized key bytes: 5c4b020b06190b00112233445546778899aa
 PASS: Cloned key exported data should be [00112233445546778899aa] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -708,7 +708,7 @@
 PASS clonedKey.algorithm.length is 128
 PASS clonedKey.algorithm.hash.name is "SHA-256"
 PASS clonedKey.usages.join(',') is "sign,verify"
-Serialized key bytes: 4b021006191030112233445566778899aabbccddeeff
+Serialized key bytes: 5c4b021006191030112233445566778899aabbccddeeff00
 PASS: Cloned key exported data should be [30112233445566778899aabbccddeeff] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -728,7 +728,7 @@
 PASS clonedKey.algorithm.length is 8
 PASS clonedKey.algorithm.hash.name is "SHA-256"
 PASS clonedKey.usages.join(',') is "sign"
-Serialized key bytes: 4b02010608013000
+Serialized key bytes: 5c4b020106080130
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -747,7 +747,7 @@
 PASS clonedKey.algorithm.length is 64
 PASS clonedKey.algorithm.hash.name is "SHA-256"
 PASS clonedKey.usages.join(',') is "sign"
-Serialized key bytes: 4b02080608080011223344554677
+Serialized key bytes: 5c4b0208060808001122334455467700
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -766,7 +766,7 @@
 PASS clonedKey.algorithm.length is 88
 PASS clonedKey.algorithm.hash.name is "SHA-256"
 PASS clonedKey.usages.join(',') is "sign"
-Serialized key bytes: 4b020b06080b00112233445546778899aa00
+Serialized key bytes: 5c4b020b06080b00112233445546778899aa
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -785,7 +785,7 @@
 PASS clonedKey.algorithm.length is 128
 PASS clonedKey.algorithm.hash.name is "SHA-256"
 PASS clonedKey.usages.join(',') is "sign"
-Serialized key bytes: 4b021006081030112233445566778899aabbccddeeff
+Serialized key bytes: 5c4b021006081030112233445566778899aabbccddeeff00
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -804,7 +804,7 @@
 PASS clonedKey.algorithm.length is 8
 PASS clonedKey.algorithm.hash.name is "SHA-256"
 PASS clonedKey.usages.join(',') is "verify"
-Serialized key bytes: 4b02010610013000
+Serialized key bytes: 5c4b020106100130
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -823,7 +823,7 @@
 PASS clonedKey.algorithm.length is 64
 PASS clonedKey.algorithm.hash.name is "SHA-256"
 PASS clonedKey.usages.join(',') is "verify"
-Serialized key bytes: 4b02080610080011223344554677
+Serialized key bytes: 5c4b0208061008001122334455467700
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -842,7 +842,7 @@
 PASS clonedKey.algorithm.length is 88
 PASS clonedKey.algorithm.hash.name is "SHA-256"
 PASS clonedKey.usages.join(',') is "verify"
-Serialized key bytes: 4b020b06100b00112233445546778899aa00
+Serialized key bytes: 5c4b020b06100b00112233445546778899aa
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -861,7 +861,7 @@
 PASS clonedKey.algorithm.length is 128
 PASS clonedKey.algorithm.hash.name is "SHA-256"
 PASS clonedKey.usages.join(',') is "verify"
-Serialized key bytes: 4b021006101030112233445566778899aabbccddeeff
+Serialized key bytes: 5c4b021006101030112233445566778899aabbccddeeff00
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -880,7 +880,7 @@
 PASS clonedKey.algorithm.length is 8
 PASS clonedKey.algorithm.hash.name is "SHA-256"
 PASS clonedKey.usages.join(',') is "sign,verify"
-Serialized key bytes: 4b02010618013000
+Serialized key bytes: 5c4b020106180130
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -899,7 +899,7 @@
 PASS clonedKey.algorithm.length is 64
 PASS clonedKey.algorithm.hash.name is "SHA-256"
 PASS clonedKey.usages.join(',') is "sign,verify"
-Serialized key bytes: 4b02080618080011223344554677
+Serialized key bytes: 5c4b0208061808001122334455467700
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -918,7 +918,7 @@
 PASS clonedKey.algorithm.length is 88
 PASS clonedKey.algorithm.hash.name is "SHA-256"
 PASS clonedKey.usages.join(',') is "sign,verify"
-Serialized key bytes: 4b020b06180b00112233445546778899aa00
+Serialized key bytes: 5c4b020b06180b00112233445546778899aa
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -937,7 +937,7 @@
 PASS clonedKey.algorithm.length is 128
 PASS clonedKey.algorithm.hash.name is "SHA-256"
 PASS clonedKey.usages.join(',') is "sign,verify"
-Serialized key bytes: 4b021006181030112233445566778899aabbccddeeff
+Serialized key bytes: 5c4b021006181030112233445566778899aabbccddeeff00
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -956,7 +956,7 @@
 PASS clonedKey.algorithm.length is 8
 PASS clonedKey.algorithm.hash.name is "SHA-512"
 PASS clonedKey.usages.join(',') is "sign"
-Serialized key bytes: 4b02010809013000
+Serialized key bytes: 5c4b020108090130
 PASS: Cloned key exported data should be [30] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -976,7 +976,7 @@
 PASS clonedKey.algorithm.length is 64
 PASS clonedKey.algorithm.hash.name is "SHA-512"
 PASS clonedKey.usages.join(',') is "sign"
-Serialized key bytes: 4b02080809080011223344554677
+Serialized key bytes: 5c4b0208080908001122334455467700
 PASS: Cloned key exported data should be [0011223344554677] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -996,7 +996,7 @@
 PASS clonedKey.algorithm.length is 88
 PASS clonedKey.algorithm.hash.name is "SHA-512"
 PASS clonedKey.usages.join(',') is "sign"
-Serialized key bytes: 4b020b08090b00112233445546778899aa00
+Serialized key bytes: 5c4b020b08090b00112233445546778899aa
 PASS: Cloned key exported data should be [00112233445546778899aa] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -1016,7 +1016,7 @@
 PASS clonedKey.algorithm.length is 128
 PASS clonedKey.algorithm.hash.name is "SHA-512"
 PASS clonedKey.usages.join(',') is "sign"
-Serialized key bytes: 4b021008091030112233445566778899aabbccddeeff
+Serialized key bytes: 5c4b021008091030112233445566778899aabbccddeeff00
 PASS: Cloned key exported data should be [30112233445566778899aabbccddeeff] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -1036,7 +1036,7 @@
 PASS clonedKey.algorithm.length is 8
 PASS clonedKey.algorithm.hash.name is "SHA-512"
 PASS clonedKey.usages.join(',') is "verify"
-Serialized key bytes: 4b02010811013000
+Serialized key bytes: 5c4b020108110130
 PASS: Cloned key exported data should be [30] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -1056,7 +1056,7 @@
 PASS clonedKey.algorithm.length is 64
 PASS clonedKey.algorithm.hash.name is "SHA-512"
 PASS clonedKey.usages.join(',') is "verify"
-Serialized key bytes: 4b02080811080011223344554677
+Serialized key bytes: 5c4b0208081108001122334455467700
 PASS: Cloned key exported data should be [0011223344554677] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -1076,7 +1076,7 @@
 PASS clonedKey.algorithm.length is 88
 PASS clonedKey.algorithm.hash.name is "SHA-512"
 PASS clonedKey.usages.join(',') is "verify"
-Serialized key bytes: 4b020b08110b00112233445546778899aa00
+Serialized key bytes: 5c4b020b08110b00112233445546778899aa
 PASS: Cloned key exported data should be [00112233445546778899aa] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -1096,7 +1096,7 @@
 PASS clonedKey.algorithm.length is 128
 PASS clonedKey.algorithm.hash.name is "SHA-512"
 PASS clonedKey.usages.join(',') is "verify"
-Serialized key bytes: 4b021008111030112233445566778899aabbccddeeff
+Serialized key bytes: 5c4b021008111030112233445566778899aabbccddeeff00
 PASS: Cloned key exported data should be [30112233445566778899aabbccddeeff] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -1116,7 +1116,7 @@
 PASS clonedKey.algorithm.length is 8
 PASS clonedKey.algorithm.hash.name is "SHA-512"
 PASS clonedKey.usages.join(',') is "sign,verify"
-Serialized key bytes: 4b02010819013000
+Serialized key bytes: 5c4b020108190130
 PASS: Cloned key exported data should be [30] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -1136,7 +1136,7 @@
 PASS clonedKey.algorithm.length is 64
 PASS clonedKey.algorithm.hash.name is "SHA-512"
 PASS clonedKey.usages.join(',') is "sign,verify"
-Serialized key bytes: 4b02080819080011223344554677
+Serialized key bytes: 5c4b0208081908001122334455467700
 PASS: Cloned key exported data should be [0011223344554677] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -1156,7 +1156,7 @@
 PASS clonedKey.algorithm.length is 88
 PASS clonedKey.algorithm.hash.name is "SHA-512"
 PASS clonedKey.usages.join(',') is "sign,verify"
-Serialized key bytes: 4b020b08190b00112233445546778899aa00
+Serialized key bytes: 5c4b020b08190b00112233445546778899aa
 PASS: Cloned key exported data should be [00112233445546778899aa] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -1176,7 +1176,7 @@
 PASS clonedKey.algorithm.length is 128
 PASS clonedKey.algorithm.hash.name is "SHA-512"
 PASS clonedKey.usages.join(',') is "sign,verify"
-Serialized key bytes: 4b021008191030112233445566778899aabbccddeeff
+Serialized key bytes: 5c4b021008191030112233445566778899aabbccddeeff00
 PASS: Cloned key exported data should be [30112233445566778899aabbccddeeff] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -1196,7 +1196,7 @@
 PASS clonedKey.algorithm.length is 8
 PASS clonedKey.algorithm.hash.name is "SHA-512"
 PASS clonedKey.usages.join(',') is "sign"
-Serialized key bytes: 4b02010808013000
+Serialized key bytes: 5c4b020108080130
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -1215,7 +1215,7 @@
 PASS clonedKey.algorithm.length is 64
 PASS clonedKey.algorithm.hash.name is "SHA-512"
 PASS clonedKey.usages.join(',') is "sign"
-Serialized key bytes: 4b02080808080011223344554677
+Serialized key bytes: 5c4b0208080808001122334455467700
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -1234,7 +1234,7 @@
 PASS clonedKey.algorithm.length is 88
 PASS clonedKey.algorithm.hash.name is "SHA-512"
 PASS clonedKey.usages.join(',') is "sign"
-Serialized key bytes: 4b020b08080b00112233445546778899aa00
+Serialized key bytes: 5c4b020b08080b00112233445546778899aa
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -1253,7 +1253,7 @@
 PASS clonedKey.algorithm.length is 128
 PASS clonedKey.algorithm.hash.name is "SHA-512"
 PASS clonedKey.usages.join(',') is "sign"
-Serialized key bytes: 4b021008081030112233445566778899aabbccddeeff
+Serialized key bytes: 5c4b021008081030112233445566778899aabbccddeeff00
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -1272,7 +1272,7 @@
 PASS clonedKey.algorithm.length is 8
 PASS clonedKey.algorithm.hash.name is "SHA-512"
 PASS clonedKey.usages.join(',') is "verify"
-Serialized key bytes: 4b02010810013000
+Serialized key bytes: 5c4b020108100130
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -1291,7 +1291,7 @@
 PASS clonedKey.algorithm.length is 64
 PASS clonedKey.algorithm.hash.name is "SHA-512"
 PASS clonedKey.usages.join(',') is "verify"
-Serialized key bytes: 4b02080810080011223344554677
+Serialized key bytes: 5c4b0208081008001122334455467700
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -1310,7 +1310,7 @@
 PASS clonedKey.algorithm.length is 88
 PASS clonedKey.algorithm.hash.name is "SHA-512"
 PASS clonedKey.usages.join(',') is "verify"
-Serialized key bytes: 4b020b08100b00112233445546778899aa00
+Serialized key bytes: 5c4b020b08100b00112233445546778899aa
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -1329,7 +1329,7 @@
 PASS clonedKey.algorithm.length is 128
 PASS clonedKey.algorithm.hash.name is "SHA-512"
 PASS clonedKey.usages.join(',') is "verify"
-Serialized key bytes: 4b021008101030112233445566778899aabbccddeeff
+Serialized key bytes: 5c4b021008101030112233445566778899aabbccddeeff00
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -1348,7 +1348,7 @@
 PASS clonedKey.algorithm.length is 8
 PASS clonedKey.algorithm.hash.name is "SHA-512"
 PASS clonedKey.usages.join(',') is "sign,verify"
-Serialized key bytes: 4b02010818013000
+Serialized key bytes: 5c4b020108180130
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -1367,7 +1367,7 @@
 PASS clonedKey.algorithm.length is 64
 PASS clonedKey.algorithm.hash.name is "SHA-512"
 PASS clonedKey.usages.join(',') is "sign,verify"
-Serialized key bytes: 4b02080818080011223344554677
+Serialized key bytes: 5c4b0208081808001122334455467700
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -1386,7 +1386,7 @@
 PASS clonedKey.algorithm.length is 88
 PASS clonedKey.algorithm.hash.name is "SHA-512"
 PASS clonedKey.usages.join(',') is "sign,verify"
-Serialized key bytes: 4b020b08180b00112233445546778899aa00
+Serialized key bytes: 5c4b020b08180b00112233445546778899aa
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -1405,7 +1405,7 @@
 PASS clonedKey.algorithm.length is 128
 PASS clonedKey.algorithm.hash.name is "SHA-512"
 PASS clonedKey.usages.join(',') is "sign,verify"
-Serialized key bytes: 4b021008181030112233445566778899aabbccddeeff
+Serialized key bytes: 5c4b021008181030112233445566778899aabbccddeeff00
 
 PASS successfullyParsed is true
 
diff --git a/third_party/WebKit/LayoutTests/crypto/subtle/pbkdf2/cloneKey-expected.txt b/third_party/WebKit/LayoutTests/crypto/subtle/pbkdf2/cloneKey-expected.txt
index 986e63f..c15ec53 100644
--- a/third_party/WebKit/LayoutTests/crypto/subtle/pbkdf2/cloneKey-expected.txt
+++ b/third_party/WebKit/LayoutTests/crypto/subtle/pbkdf2/cloneKey-expected.txt
@@ -16,7 +16,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "PBKDF2"
 PASS clonedKey.usages.join(',') is "deriveBits"
-Serialized key bytes: 4b0611800200
+Serialized key bytes: 5c4b061180020000
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -31,7 +31,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "PBKDF2"
 PASS clonedKey.usages.join(',') is "deriveBits"
-Serialized key bytes: 4b06118002013000
+Serialized key bytes: 5c4b061180020130
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -46,7 +46,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "PBKDF2"
 PASS clonedKey.usages.join(',') is "deriveBits"
-Serialized key bytes: 4b06118002080011223344554677
+Serialized key bytes: 5c4b0611800208001122334455467700
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -61,7 +61,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "PBKDF2"
 PASS clonedKey.usages.join(',') is "deriveBits"
-Serialized key bytes: 4b061180020b00112233445546778899aa00
+Serialized key bytes: 5c4b061180020b00112233445546778899aa
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -76,7 +76,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "PBKDF2"
 PASS clonedKey.usages.join(',') is "deriveBits"
-Serialized key bytes: 4b061180021030112233445566778899aabbccddeeff
+Serialized key bytes: 5c4b061180021030112233445566778899aabbccddeeff00
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -91,7 +91,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "PBKDF2"
 PASS clonedKey.usages.join(',') is "deriveKey"
-Serialized key bytes: 4b0611200000
+Serialized key bytes: 5c4b06112000
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -106,7 +106,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "PBKDF2"
 PASS clonedKey.usages.join(',') is "deriveKey"
-Serialized key bytes: 4b0611200130
+Serialized key bytes: 5c4b061120013000
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -121,7 +121,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "PBKDF2"
 PASS clonedKey.usages.join(',') is "deriveKey"
-Serialized key bytes: 4b06112008001122334455467700
+Serialized key bytes: 5c4b061120080011223344554677
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -136,7 +136,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "PBKDF2"
 PASS clonedKey.usages.join(',') is "deriveKey"
-Serialized key bytes: 4b0611200b00112233445546778899aa
+Serialized key bytes: 5c4b0611200b00112233445546778899aa00
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -151,7 +151,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "PBKDF2"
 PASS clonedKey.usages.join(',') is "deriveKey"
-Serialized key bytes: 4b0611201030112233445566778899aabbccddeeff00
+Serialized key bytes: 5c4b0611201030112233445566778899aabbccddeeff
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -166,7 +166,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "PBKDF2"
 PASS clonedKey.usages.join(',') is "deriveKey,deriveBits"
-Serialized key bytes: 4b0611a00200
+Serialized key bytes: 5c4b0611a0020000
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -181,7 +181,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "PBKDF2"
 PASS clonedKey.usages.join(',') is "deriveKey,deriveBits"
-Serialized key bytes: 4b0611a002013000
+Serialized key bytes: 5c4b0611a0020130
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -196,7 +196,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "PBKDF2"
 PASS clonedKey.usages.join(',') is "deriveKey,deriveBits"
-Serialized key bytes: 4b0611a002080011223344554677
+Serialized key bytes: 5c4b0611a00208001122334455467700
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -211,7 +211,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "PBKDF2"
 PASS clonedKey.usages.join(',') is "deriveKey,deriveBits"
-Serialized key bytes: 4b0611a0020b00112233445546778899aa00
+Serialized key bytes: 5c4b0611a0020b00112233445546778899aa
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -226,7 +226,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "PBKDF2"
 PASS clonedKey.usages.join(',') is "deriveKey,deriveBits"
-Serialized key bytes: 4b0611a0021030112233445566778899aabbccddeeff
+Serialized key bytes: 5c4b0611a0021030112233445566778899aabbccddeeff00
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -241,7 +241,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "PBKDF2"
 PASS clonedKey.usages.join(',') is "deriveBits"
-Serialized key bytes: 4b0611800200
+Serialized key bytes: 5c4b061180020000
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -256,7 +256,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "PBKDF2"
 PASS clonedKey.usages.join(',') is "deriveBits"
-Serialized key bytes: 4b06118002013000
+Serialized key bytes: 5c4b061180020130
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -271,7 +271,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "PBKDF2"
 PASS clonedKey.usages.join(',') is "deriveBits"
-Serialized key bytes: 4b06118002080011223344554677
+Serialized key bytes: 5c4b0611800208001122334455467700
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -286,7 +286,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "PBKDF2"
 PASS clonedKey.usages.join(',') is "deriveBits"
-Serialized key bytes: 4b061180020b00112233445546778899aa00
+Serialized key bytes: 5c4b061180020b00112233445546778899aa
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -301,7 +301,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "PBKDF2"
 PASS clonedKey.usages.join(',') is "deriveBits"
-Serialized key bytes: 4b061180021030112233445566778899aabbccddeeff
+Serialized key bytes: 5c4b061180021030112233445566778899aabbccddeeff00
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -316,7 +316,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "PBKDF2"
 PASS clonedKey.usages.join(',') is "deriveKey"
-Serialized key bytes: 4b0611200000
+Serialized key bytes: 5c4b06112000
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -331,7 +331,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "PBKDF2"
 PASS clonedKey.usages.join(',') is "deriveKey"
-Serialized key bytes: 4b0611200130
+Serialized key bytes: 5c4b061120013000
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -346,7 +346,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "PBKDF2"
 PASS clonedKey.usages.join(',') is "deriveKey"
-Serialized key bytes: 4b06112008001122334455467700
+Serialized key bytes: 5c4b061120080011223344554677
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -361,7 +361,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "PBKDF2"
 PASS clonedKey.usages.join(',') is "deriveKey"
-Serialized key bytes: 4b0611200b00112233445546778899aa
+Serialized key bytes: 5c4b0611200b00112233445546778899aa00
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -376,7 +376,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "PBKDF2"
 PASS clonedKey.usages.join(',') is "deriveKey"
-Serialized key bytes: 4b0611201030112233445566778899aabbccddeeff00
+Serialized key bytes: 5c4b0611201030112233445566778899aabbccddeeff
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -391,7 +391,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "PBKDF2"
 PASS clonedKey.usages.join(',') is "deriveKey,deriveBits"
-Serialized key bytes: 4b0611a00200
+Serialized key bytes: 5c4b0611a0020000
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -406,7 +406,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "PBKDF2"
 PASS clonedKey.usages.join(',') is "deriveKey,deriveBits"
-Serialized key bytes: 4b0611a002013000
+Serialized key bytes: 5c4b0611a0020130
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -421,7 +421,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "PBKDF2"
 PASS clonedKey.usages.join(',') is "deriveKey,deriveBits"
-Serialized key bytes: 4b0611a002080011223344554677
+Serialized key bytes: 5c4b0611a00208001122334455467700
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -436,7 +436,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "PBKDF2"
 PASS clonedKey.usages.join(',') is "deriveKey,deriveBits"
-Serialized key bytes: 4b0611a0020b00112233445546778899aa00
+Serialized key bytes: 5c4b0611a0020b00112233445546778899aa
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -451,7 +451,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "PBKDF2"
 PASS clonedKey.usages.join(',') is "deriveKey,deriveBits"
-Serialized key bytes: 4b0611a0021030112233445566778899aabbccddeeff
+Serialized key bytes: 5c4b0611a0021030112233445566778899aabbccddeeff00
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -466,7 +466,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "PBKDF2"
 PASS clonedKey.usages.join(',') is "deriveBits"
-Serialized key bytes: 4b0611800200
+Serialized key bytes: 5c4b061180020000
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -481,7 +481,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "PBKDF2"
 PASS clonedKey.usages.join(',') is "deriveBits"
-Serialized key bytes: 4b06118002013000
+Serialized key bytes: 5c4b061180020130
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -496,7 +496,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "PBKDF2"
 PASS clonedKey.usages.join(',') is "deriveBits"
-Serialized key bytes: 4b06118002080011223344554677
+Serialized key bytes: 5c4b0611800208001122334455467700
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -511,7 +511,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "PBKDF2"
 PASS clonedKey.usages.join(',') is "deriveBits"
-Serialized key bytes: 4b061180020b00112233445546778899aa00
+Serialized key bytes: 5c4b061180020b00112233445546778899aa
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -526,7 +526,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "PBKDF2"
 PASS clonedKey.usages.join(',') is "deriveBits"
-Serialized key bytes: 4b061180021030112233445566778899aabbccddeeff
+Serialized key bytes: 5c4b061180021030112233445566778899aabbccddeeff00
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -541,7 +541,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "PBKDF2"
 PASS clonedKey.usages.join(',') is "deriveKey"
-Serialized key bytes: 4b0611200000
+Serialized key bytes: 5c4b06112000
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -556,7 +556,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "PBKDF2"
 PASS clonedKey.usages.join(',') is "deriveKey"
-Serialized key bytes: 4b0611200130
+Serialized key bytes: 5c4b061120013000
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -571,7 +571,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "PBKDF2"
 PASS clonedKey.usages.join(',') is "deriveKey"
-Serialized key bytes: 4b06112008001122334455467700
+Serialized key bytes: 5c4b061120080011223344554677
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -586,7 +586,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "PBKDF2"
 PASS clonedKey.usages.join(',') is "deriveKey"
-Serialized key bytes: 4b0611200b00112233445546778899aa
+Serialized key bytes: 5c4b0611200b00112233445546778899aa00
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -601,7 +601,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "PBKDF2"
 PASS clonedKey.usages.join(',') is "deriveKey"
-Serialized key bytes: 4b0611201030112233445566778899aabbccddeeff00
+Serialized key bytes: 5c4b0611201030112233445566778899aabbccddeeff
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -616,7 +616,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "PBKDF2"
 PASS clonedKey.usages.join(',') is "deriveKey,deriveBits"
-Serialized key bytes: 4b0611a00200
+Serialized key bytes: 5c4b0611a0020000
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -631,7 +631,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "PBKDF2"
 PASS clonedKey.usages.join(',') is "deriveKey,deriveBits"
-Serialized key bytes: 4b0611a002013000
+Serialized key bytes: 5c4b0611a0020130
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -646,7 +646,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "PBKDF2"
 PASS clonedKey.usages.join(',') is "deriveKey,deriveBits"
-Serialized key bytes: 4b0611a002080011223344554677
+Serialized key bytes: 5c4b0611a00208001122334455467700
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -661,7 +661,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "PBKDF2"
 PASS clonedKey.usages.join(',') is "deriveKey,deriveBits"
-Serialized key bytes: 4b0611a0020b00112233445546778899aa00
+Serialized key bytes: 5c4b0611a0020b00112233445546778899aa
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "secret"
@@ -676,7 +676,7 @@
 PASS clonedKey.extractable is false
 PASS clonedKey.algorithm.name is "PBKDF2"
 PASS clonedKey.usages.join(',') is "deriveKey,deriveBits"
-Serialized key bytes: 4b0611a0021030112233445566778899aabbccddeeff
+Serialized key bytes: 5c4b0611a0021030112233445566778899aabbccddeeff00
 
 PASS successfullyParsed is true
 
diff --git a/third_party/WebKit/LayoutTests/crypto/subtle/rsassa-pkcs1-v1_5/cloneKey-expected.txt b/third_party/WebKit/LayoutTests/crypto/subtle/rsassa-pkcs1-v1_5/cloneKey-expected.txt
index f91eb56a..3208500 100644
--- a/third_party/WebKit/LayoutTests/crypto/subtle/rsassa-pkcs1-v1_5/cloneKey-expected.txt
+++ b/third_party/WebKit/LayoutTests/crypto/subtle/rsassa-pkcs1-v1_5/cloneKey-expected.txt
@@ -22,7 +22,7 @@
 PASS: clonedKey.algorithm.publicExponent should be [010001] and was
 PASS clonedKey.algorithm.hash.name is "SHA-1"
 PASS clonedKey.usages.join(',') is ""
-Serialized key bytes: 4b0403018008030100010501a20130819f300d06092a864886f70d010101050003818d0030818902818100b289c62ecc3ddf64154817203439eaa0dc07a65954429a7b6098a77235673d96df1f06bd3c1ae73990867199e678bf95b3728fcd4686136e6ee9dd4c09eb490eb7cb953c388668b759263f61d6a7dfcabf27b5c9d6972455b12b66d483843286d6b871f35f912a773c97c1932255fcee05ce7b8af213879f017de4232a306a410203010001
+Serialized key bytes: 5c4b0403018008030100010501a20130819f300d06092a864886f70d010101050003818d0030818902818100b289c62ecc3ddf64154817203439eaa0dc07a65954429a7b6098a77235673d96df1f06bd3c1ae73990867199e678bf95b3728fcd4686136e6ee9dd4c09eb490eb7cb953c388668b759263f61d6a7dfcabf27b5c9d6972455b12b66d483843286d6b871f35f912a773c97c1932255fcee05ce7b8af213879f017de4232a306a41020301000100
 PASS: Cloned key exported data should be [30819f300d06092a864886f70d010101050003818d0030818902818100b289c62ecc3ddf64154817203439eaa0dc07a65954429a7b6098a77235673d96df1f06bd3c1ae73990867199e678bf95b3728fcd4686136e6ee9dd4c09eb490eb7cb953c388668b759263f61d6a7dfcabf27b5c9d6972455b12b66d483843286d6b871f35f912a773c97c1932255fcee05ce7b8af213879f017de4232a306a410203010001] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -44,7 +44,7 @@
 PASS: clonedKey.algorithm.publicExponent should be [010001] and was
 PASS clonedKey.algorithm.hash.name is "SHA-1"
 PASS clonedKey.usages.join(',') is ""
-Serialized key bytes: 4b0403018010030100010501a60230820122300d06092a864886f70d01010105000382010f003082010a0282010100b4c8b631194aef0154b1479ab7a534b60ca878981108680f0ae6b7c88cb6010f6dbf9f665646208410575cb923b26bf874a24b4cd801c9bba967062ae506cdcf307add4380d0d93077a4c1f0fc06d498dc729f811335c530b90fe9bf9f3979ccec050a48e8923045b19368e1e89ea4157538e8059e53320f47c155f1741310a93ed153a7f3af2d46c388b95d82518527a02b7bd9ab7edc4bcb737677f679c5c6de5e1ebed3a29d6b99b8eace2d59ceb533e001cf39c5671495d51d3ee34406ea4fdb0c626dee68da256b8a12f9f65059ccc85a2190ce1385152d62785e00cae702e77c4c597b86a6268adbf043dda68881c790f1517671fb7d198fca5ba97bef0203010001
+Serialized key bytes: 5c4b0403018010030100010501a60230820122300d06092a864886f70d01010105000382010f003082010a0282010100b4c8b631194aef0154b1479ab7a534b60ca878981108680f0ae6b7c88cb6010f6dbf9f665646208410575cb923b26bf874a24b4cd801c9bba967062ae506cdcf307add4380d0d93077a4c1f0fc06d498dc729f811335c530b90fe9bf9f3979ccec050a48e8923045b19368e1e89ea4157538e8059e53320f47c155f1741310a93ed153a7f3af2d46c388b95d82518527a02b7bd9ab7edc4bcb737677f679c5c6de5e1ebed3a29d6b99b8eace2d59ceb533e001cf39c5671495d51d3ee34406ea4fdb0c626dee68da256b8a12f9f65059ccc85a2190ce1385152d62785e00cae702e77c4c597b86a6268adbf043dda68881c790f1517671fb7d198fca5ba97bef020301000100
 PASS: Cloned key exported data should be [30820122300d06092a864886f70d01010105000382010f003082010a0282010100b4c8b631194aef0154b1479ab7a534b60ca878981108680f0ae6b7c88cb6010f6dbf9f665646208410575cb923b26bf874a24b4cd801c9bba967062ae506cdcf307add4380d0d93077a4c1f0fc06d498dc729f811335c530b90fe9bf9f3979ccec050a48e8923045b19368e1e89ea4157538e8059e53320f47c155f1741310a93ed153a7f3af2d46c388b95d82518527a02b7bd9ab7edc4bcb737677f679c5c6de5e1ebed3a29d6b99b8eace2d59ceb533e001cf39c5671495d51d3ee34406ea4fdb0c626dee68da256b8a12f9f65059ccc85a2190ce1385152d62785e00cae702e77c4c597b86a6268adbf043dda68881c790f1517671fb7d198fca5ba97bef0203010001] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -66,7 +66,7 @@
 PASS: clonedKey.algorithm.publicExponent should be [010001] and was
 PASS clonedKey.algorithm.hash.name is "SHA-1"
 PASS clonedKey.usages.join(',') is "verify"
-Serialized key bytes: 4b0403018008030100010511a20130819f300d06092a864886f70d010101050003818d0030818902818100b289c62ecc3ddf64154817203439eaa0dc07a65954429a7b6098a77235673d96df1f06bd3c1ae73990867199e678bf95b3728fcd4686136e6ee9dd4c09eb490eb7cb953c388668b759263f61d6a7dfcabf27b5c9d6972455b12b66d483843286d6b871f35f912a773c97c1932255fcee05ce7b8af213879f017de4232a306a410203010001
+Serialized key bytes: 5c4b0403018008030100010511a20130819f300d06092a864886f70d010101050003818d0030818902818100b289c62ecc3ddf64154817203439eaa0dc07a65954429a7b6098a77235673d96df1f06bd3c1ae73990867199e678bf95b3728fcd4686136e6ee9dd4c09eb490eb7cb953c388668b759263f61d6a7dfcabf27b5c9d6972455b12b66d483843286d6b871f35f912a773c97c1932255fcee05ce7b8af213879f017de4232a306a41020301000100
 PASS: Cloned key exported data should be [30819f300d06092a864886f70d010101050003818d0030818902818100b289c62ecc3ddf64154817203439eaa0dc07a65954429a7b6098a77235673d96df1f06bd3c1ae73990867199e678bf95b3728fcd4686136e6ee9dd4c09eb490eb7cb953c388668b759263f61d6a7dfcabf27b5c9d6972455b12b66d483843286d6b871f35f912a773c97c1932255fcee05ce7b8af213879f017de4232a306a410203010001] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -88,7 +88,7 @@
 PASS: clonedKey.algorithm.publicExponent should be [010001] and was
 PASS clonedKey.algorithm.hash.name is "SHA-1"
 PASS clonedKey.usages.join(',') is "verify"
-Serialized key bytes: 4b0403018010030100010511a60230820122300d06092a864886f70d01010105000382010f003082010a0282010100b4c8b631194aef0154b1479ab7a534b60ca878981108680f0ae6b7c88cb6010f6dbf9f665646208410575cb923b26bf874a24b4cd801c9bba967062ae506cdcf307add4380d0d93077a4c1f0fc06d498dc729f811335c530b90fe9bf9f3979ccec050a48e8923045b19368e1e89ea4157538e8059e53320f47c155f1741310a93ed153a7f3af2d46c388b95d82518527a02b7bd9ab7edc4bcb737677f679c5c6de5e1ebed3a29d6b99b8eace2d59ceb533e001cf39c5671495d51d3ee34406ea4fdb0c626dee68da256b8a12f9f65059ccc85a2190ce1385152d62785e00cae702e77c4c597b86a6268adbf043dda68881c790f1517671fb7d198fca5ba97bef0203010001
+Serialized key bytes: 5c4b0403018010030100010511a60230820122300d06092a864886f70d01010105000382010f003082010a0282010100b4c8b631194aef0154b1479ab7a534b60ca878981108680f0ae6b7c88cb6010f6dbf9f665646208410575cb923b26bf874a24b4cd801c9bba967062ae506cdcf307add4380d0d93077a4c1f0fc06d498dc729f811335c530b90fe9bf9f3979ccec050a48e8923045b19368e1e89ea4157538e8059e53320f47c155f1741310a93ed153a7f3af2d46c388b95d82518527a02b7bd9ab7edc4bcb737677f679c5c6de5e1ebed3a29d6b99b8eace2d59ceb533e001cf39c5671495d51d3ee34406ea4fdb0c626dee68da256b8a12f9f65059ccc85a2190ce1385152d62785e00cae702e77c4c597b86a6268adbf043dda68881c790f1517671fb7d198fca5ba97bef020301000100
 PASS: Cloned key exported data should be [30820122300d06092a864886f70d01010105000382010f003082010a0282010100b4c8b631194aef0154b1479ab7a534b60ca878981108680f0ae6b7c88cb6010f6dbf9f665646208410575cb923b26bf874a24b4cd801c9bba967062ae506cdcf307add4380d0d93077a4c1f0fc06d498dc729f811335c530b90fe9bf9f3979ccec050a48e8923045b19368e1e89ea4157538e8059e53320f47c155f1741310a93ed153a7f3af2d46c388b95d82518527a02b7bd9ab7edc4bcb737677f679c5c6de5e1ebed3a29d6b99b8eace2d59ceb533e001cf39c5671495d51d3ee34406ea4fdb0c626dee68da256b8a12f9f65059ccc85a2190ce1385152d62785e00cae702e77c4c597b86a6268adbf043dda68881c790f1517671fb7d198fca5ba97bef0203010001] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -110,7 +110,7 @@
 PASS: clonedKey.algorithm.publicExponent should be [010001] and was
 PASS clonedKey.algorithm.hash.name is "SHA-1"
 PASS clonedKey.usages.join(',') is ""
-Serialized key bytes: 4b0403018008030100010500a20130819f300d06092a864886f70d010101050003818d0030818902818100b289c62ecc3ddf64154817203439eaa0dc07a65954429a7b6098a77235673d96df1f06bd3c1ae73990867199e678bf95b3728fcd4686136e6ee9dd4c09eb490eb7cb953c388668b759263f61d6a7dfcabf27b5c9d6972455b12b66d483843286d6b871f35f912a773c97c1932255fcee05ce7b8af213879f017de4232a306a410203010001
+Serialized key bytes: 5c4b0403018008030100010500a20130819f300d06092a864886f70d010101050003818d0030818902818100b289c62ecc3ddf64154817203439eaa0dc07a65954429a7b6098a77235673d96df1f06bd3c1ae73990867199e678bf95b3728fcd4686136e6ee9dd4c09eb490eb7cb953c388668b759263f61d6a7dfcabf27b5c9d6972455b12b66d483843286d6b871f35f912a773c97c1932255fcee05ce7b8af213879f017de4232a306a41020301000100
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "public"
@@ -131,7 +131,7 @@
 PASS: clonedKey.algorithm.publicExponent should be [010001] and was
 PASS clonedKey.algorithm.hash.name is "SHA-1"
 PASS clonedKey.usages.join(',') is ""
-Serialized key bytes: 4b0403018010030100010500a60230820122300d06092a864886f70d01010105000382010f003082010a0282010100b4c8b631194aef0154b1479ab7a534b60ca878981108680f0ae6b7c88cb6010f6dbf9f665646208410575cb923b26bf874a24b4cd801c9bba967062ae506cdcf307add4380d0d93077a4c1f0fc06d498dc729f811335c530b90fe9bf9f3979ccec050a48e8923045b19368e1e89ea4157538e8059e53320f47c155f1741310a93ed153a7f3af2d46c388b95d82518527a02b7bd9ab7edc4bcb737677f679c5c6de5e1ebed3a29d6b99b8eace2d59ceb533e001cf39c5671495d51d3ee34406ea4fdb0c626dee68da256b8a12f9f65059ccc85a2190ce1385152d62785e00cae702e77c4c597b86a6268adbf043dda68881c790f1517671fb7d198fca5ba97bef0203010001
+Serialized key bytes: 5c4b0403018010030100010500a60230820122300d06092a864886f70d01010105000382010f003082010a0282010100b4c8b631194aef0154b1479ab7a534b60ca878981108680f0ae6b7c88cb6010f6dbf9f665646208410575cb923b26bf874a24b4cd801c9bba967062ae506cdcf307add4380d0d93077a4c1f0fc06d498dc729f811335c530b90fe9bf9f3979ccec050a48e8923045b19368e1e89ea4157538e8059e53320f47c155f1741310a93ed153a7f3af2d46c388b95d82518527a02b7bd9ab7edc4bcb737677f679c5c6de5e1ebed3a29d6b99b8eace2d59ceb533e001cf39c5671495d51d3ee34406ea4fdb0c626dee68da256b8a12f9f65059ccc85a2190ce1385152d62785e00cae702e77c4c597b86a6268adbf043dda68881c790f1517671fb7d198fca5ba97bef020301000100
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "public"
@@ -152,7 +152,7 @@
 PASS: clonedKey.algorithm.publicExponent should be [010001] and was
 PASS clonedKey.algorithm.hash.name is "SHA-1"
 PASS clonedKey.usages.join(',') is "verify"
-Serialized key bytes: 4b0403018008030100010510a20130819f300d06092a864886f70d010101050003818d0030818902818100b289c62ecc3ddf64154817203439eaa0dc07a65954429a7b6098a77235673d96df1f06bd3c1ae73990867199e678bf95b3728fcd4686136e6ee9dd4c09eb490eb7cb953c388668b759263f61d6a7dfcabf27b5c9d6972455b12b66d483843286d6b871f35f912a773c97c1932255fcee05ce7b8af213879f017de4232a306a410203010001
+Serialized key bytes: 5c4b0403018008030100010510a20130819f300d06092a864886f70d010101050003818d0030818902818100b289c62ecc3ddf64154817203439eaa0dc07a65954429a7b6098a77235673d96df1f06bd3c1ae73990867199e678bf95b3728fcd4686136e6ee9dd4c09eb490eb7cb953c388668b759263f61d6a7dfcabf27b5c9d6972455b12b66d483843286d6b871f35f912a773c97c1932255fcee05ce7b8af213879f017de4232a306a41020301000100
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "public"
@@ -173,7 +173,7 @@
 PASS: clonedKey.algorithm.publicExponent should be [010001] and was
 PASS clonedKey.algorithm.hash.name is "SHA-1"
 PASS clonedKey.usages.join(',') is "verify"
-Serialized key bytes: 4b0403018010030100010510a60230820122300d06092a864886f70d01010105000382010f003082010a0282010100b4c8b631194aef0154b1479ab7a534b60ca878981108680f0ae6b7c88cb6010f6dbf9f665646208410575cb923b26bf874a24b4cd801c9bba967062ae506cdcf307add4380d0d93077a4c1f0fc06d498dc729f811335c530b90fe9bf9f3979ccec050a48e8923045b19368e1e89ea4157538e8059e53320f47c155f1741310a93ed153a7f3af2d46c388b95d82518527a02b7bd9ab7edc4bcb737677f679c5c6de5e1ebed3a29d6b99b8eace2d59ceb533e001cf39c5671495d51d3ee34406ea4fdb0c626dee68da256b8a12f9f65059ccc85a2190ce1385152d62785e00cae702e77c4c597b86a6268adbf043dda68881c790f1517671fb7d198fca5ba97bef0203010001
+Serialized key bytes: 5c4b0403018010030100010510a60230820122300d06092a864886f70d01010105000382010f003082010a0282010100b4c8b631194aef0154b1479ab7a534b60ca878981108680f0ae6b7c88cb6010f6dbf9f665646208410575cb923b26bf874a24b4cd801c9bba967062ae506cdcf307add4380d0d93077a4c1f0fc06d498dc729f811335c530b90fe9bf9f3979ccec050a48e8923045b19368e1e89ea4157538e8059e53320f47c155f1741310a93ed153a7f3af2d46c388b95d82518527a02b7bd9ab7edc4bcb737677f679c5c6de5e1ebed3a29d6b99b8eace2d59ceb533e001cf39c5671495d51d3ee34406ea4fdb0c626dee68da256b8a12f9f65059ccc85a2190ce1385152d62785e00cae702e77c4c597b86a6268adbf043dda68881c790f1517671fb7d198fca5ba97bef020301000100
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "public"
@@ -194,7 +194,7 @@
 PASS: clonedKey.algorithm.publicExponent should be [010001] and was
 PASS clonedKey.algorithm.hash.name is "SHA-256"
 PASS clonedKey.usages.join(',') is ""
-Serialized key bytes: 4b0403018008030100010601a20130819f300d06092a864886f70d010101050003818d0030818902818100b289c62ecc3ddf64154817203439eaa0dc07a65954429a7b6098a77235673d96df1f06bd3c1ae73990867199e678bf95b3728fcd4686136e6ee9dd4c09eb490eb7cb953c388668b759263f61d6a7dfcabf27b5c9d6972455b12b66d483843286d6b871f35f912a773c97c1932255fcee05ce7b8af213879f017de4232a306a410203010001
+Serialized key bytes: 5c4b0403018008030100010601a20130819f300d06092a864886f70d010101050003818d0030818902818100b289c62ecc3ddf64154817203439eaa0dc07a65954429a7b6098a77235673d96df1f06bd3c1ae73990867199e678bf95b3728fcd4686136e6ee9dd4c09eb490eb7cb953c388668b759263f61d6a7dfcabf27b5c9d6972455b12b66d483843286d6b871f35f912a773c97c1932255fcee05ce7b8af213879f017de4232a306a41020301000100
 PASS: Cloned key exported data should be [30819f300d06092a864886f70d010101050003818d0030818902818100b289c62ecc3ddf64154817203439eaa0dc07a65954429a7b6098a77235673d96df1f06bd3c1ae73990867199e678bf95b3728fcd4686136e6ee9dd4c09eb490eb7cb953c388668b759263f61d6a7dfcabf27b5c9d6972455b12b66d483843286d6b871f35f912a773c97c1932255fcee05ce7b8af213879f017de4232a306a410203010001] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -216,7 +216,7 @@
 PASS: clonedKey.algorithm.publicExponent should be [010001] and was
 PASS clonedKey.algorithm.hash.name is "SHA-256"
 PASS clonedKey.usages.join(',') is ""
-Serialized key bytes: 4b0403018010030100010601a60230820122300d06092a864886f70d01010105000382010f003082010a0282010100b4c8b631194aef0154b1479ab7a534b60ca878981108680f0ae6b7c88cb6010f6dbf9f665646208410575cb923b26bf874a24b4cd801c9bba967062ae506cdcf307add4380d0d93077a4c1f0fc06d498dc729f811335c530b90fe9bf9f3979ccec050a48e8923045b19368e1e89ea4157538e8059e53320f47c155f1741310a93ed153a7f3af2d46c388b95d82518527a02b7bd9ab7edc4bcb737677f679c5c6de5e1ebed3a29d6b99b8eace2d59ceb533e001cf39c5671495d51d3ee34406ea4fdb0c626dee68da256b8a12f9f65059ccc85a2190ce1385152d62785e00cae702e77c4c597b86a6268adbf043dda68881c790f1517671fb7d198fca5ba97bef0203010001
+Serialized key bytes: 5c4b0403018010030100010601a60230820122300d06092a864886f70d01010105000382010f003082010a0282010100b4c8b631194aef0154b1479ab7a534b60ca878981108680f0ae6b7c88cb6010f6dbf9f665646208410575cb923b26bf874a24b4cd801c9bba967062ae506cdcf307add4380d0d93077a4c1f0fc06d498dc729f811335c530b90fe9bf9f3979ccec050a48e8923045b19368e1e89ea4157538e8059e53320f47c155f1741310a93ed153a7f3af2d46c388b95d82518527a02b7bd9ab7edc4bcb737677f679c5c6de5e1ebed3a29d6b99b8eace2d59ceb533e001cf39c5671495d51d3ee34406ea4fdb0c626dee68da256b8a12f9f65059ccc85a2190ce1385152d62785e00cae702e77c4c597b86a6268adbf043dda68881c790f1517671fb7d198fca5ba97bef020301000100
 PASS: Cloned key exported data should be [30820122300d06092a864886f70d01010105000382010f003082010a0282010100b4c8b631194aef0154b1479ab7a534b60ca878981108680f0ae6b7c88cb6010f6dbf9f665646208410575cb923b26bf874a24b4cd801c9bba967062ae506cdcf307add4380d0d93077a4c1f0fc06d498dc729f811335c530b90fe9bf9f3979ccec050a48e8923045b19368e1e89ea4157538e8059e53320f47c155f1741310a93ed153a7f3af2d46c388b95d82518527a02b7bd9ab7edc4bcb737677f679c5c6de5e1ebed3a29d6b99b8eace2d59ceb533e001cf39c5671495d51d3ee34406ea4fdb0c626dee68da256b8a12f9f65059ccc85a2190ce1385152d62785e00cae702e77c4c597b86a6268adbf043dda68881c790f1517671fb7d198fca5ba97bef0203010001] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -238,7 +238,7 @@
 PASS: clonedKey.algorithm.publicExponent should be [010001] and was
 PASS clonedKey.algorithm.hash.name is "SHA-256"
 PASS clonedKey.usages.join(',') is "verify"
-Serialized key bytes: 4b0403018008030100010611a20130819f300d06092a864886f70d010101050003818d0030818902818100b289c62ecc3ddf64154817203439eaa0dc07a65954429a7b6098a77235673d96df1f06bd3c1ae73990867199e678bf95b3728fcd4686136e6ee9dd4c09eb490eb7cb953c388668b759263f61d6a7dfcabf27b5c9d6972455b12b66d483843286d6b871f35f912a773c97c1932255fcee05ce7b8af213879f017de4232a306a410203010001
+Serialized key bytes: 5c4b0403018008030100010611a20130819f300d06092a864886f70d010101050003818d0030818902818100b289c62ecc3ddf64154817203439eaa0dc07a65954429a7b6098a77235673d96df1f06bd3c1ae73990867199e678bf95b3728fcd4686136e6ee9dd4c09eb490eb7cb953c388668b759263f61d6a7dfcabf27b5c9d6972455b12b66d483843286d6b871f35f912a773c97c1932255fcee05ce7b8af213879f017de4232a306a41020301000100
 PASS: Cloned key exported data should be [30819f300d06092a864886f70d010101050003818d0030818902818100b289c62ecc3ddf64154817203439eaa0dc07a65954429a7b6098a77235673d96df1f06bd3c1ae73990867199e678bf95b3728fcd4686136e6ee9dd4c09eb490eb7cb953c388668b759263f61d6a7dfcabf27b5c9d6972455b12b66d483843286d6b871f35f912a773c97c1932255fcee05ce7b8af213879f017de4232a306a410203010001] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -260,7 +260,7 @@
 PASS: clonedKey.algorithm.publicExponent should be [010001] and was
 PASS clonedKey.algorithm.hash.name is "SHA-256"
 PASS clonedKey.usages.join(',') is "verify"
-Serialized key bytes: 4b0403018010030100010611a60230820122300d06092a864886f70d01010105000382010f003082010a0282010100b4c8b631194aef0154b1479ab7a534b60ca878981108680f0ae6b7c88cb6010f6dbf9f665646208410575cb923b26bf874a24b4cd801c9bba967062ae506cdcf307add4380d0d93077a4c1f0fc06d498dc729f811335c530b90fe9bf9f3979ccec050a48e8923045b19368e1e89ea4157538e8059e53320f47c155f1741310a93ed153a7f3af2d46c388b95d82518527a02b7bd9ab7edc4bcb737677f679c5c6de5e1ebed3a29d6b99b8eace2d59ceb533e001cf39c5671495d51d3ee34406ea4fdb0c626dee68da256b8a12f9f65059ccc85a2190ce1385152d62785e00cae702e77c4c597b86a6268adbf043dda68881c790f1517671fb7d198fca5ba97bef0203010001
+Serialized key bytes: 5c4b0403018010030100010611a60230820122300d06092a864886f70d01010105000382010f003082010a0282010100b4c8b631194aef0154b1479ab7a534b60ca878981108680f0ae6b7c88cb6010f6dbf9f665646208410575cb923b26bf874a24b4cd801c9bba967062ae506cdcf307add4380d0d93077a4c1f0fc06d498dc729f811335c530b90fe9bf9f3979ccec050a48e8923045b19368e1e89ea4157538e8059e53320f47c155f1741310a93ed153a7f3af2d46c388b95d82518527a02b7bd9ab7edc4bcb737677f679c5c6de5e1ebed3a29d6b99b8eace2d59ceb533e001cf39c5671495d51d3ee34406ea4fdb0c626dee68da256b8a12f9f65059ccc85a2190ce1385152d62785e00cae702e77c4c597b86a6268adbf043dda68881c790f1517671fb7d198fca5ba97bef020301000100
 PASS: Cloned key exported data should be [30820122300d06092a864886f70d01010105000382010f003082010a0282010100b4c8b631194aef0154b1479ab7a534b60ca878981108680f0ae6b7c88cb6010f6dbf9f665646208410575cb923b26bf874a24b4cd801c9bba967062ae506cdcf307add4380d0d93077a4c1f0fc06d498dc729f811335c530b90fe9bf9f3979ccec050a48e8923045b19368e1e89ea4157538e8059e53320f47c155f1741310a93ed153a7f3af2d46c388b95d82518527a02b7bd9ab7edc4bcb737677f679c5c6de5e1ebed3a29d6b99b8eace2d59ceb533e001cf39c5671495d51d3ee34406ea4fdb0c626dee68da256b8a12f9f65059ccc85a2190ce1385152d62785e00cae702e77c4c597b86a6268adbf043dda68881c790f1517671fb7d198fca5ba97bef0203010001] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -282,7 +282,7 @@
 PASS: clonedKey.algorithm.publicExponent should be [010001] and was
 PASS clonedKey.algorithm.hash.name is "SHA-256"
 PASS clonedKey.usages.join(',') is ""
-Serialized key bytes: 4b0403018008030100010600a20130819f300d06092a864886f70d010101050003818d0030818902818100b289c62ecc3ddf64154817203439eaa0dc07a65954429a7b6098a77235673d96df1f06bd3c1ae73990867199e678bf95b3728fcd4686136e6ee9dd4c09eb490eb7cb953c388668b759263f61d6a7dfcabf27b5c9d6972455b12b66d483843286d6b871f35f912a773c97c1932255fcee05ce7b8af213879f017de4232a306a410203010001
+Serialized key bytes: 5c4b0403018008030100010600a20130819f300d06092a864886f70d010101050003818d0030818902818100b289c62ecc3ddf64154817203439eaa0dc07a65954429a7b6098a77235673d96df1f06bd3c1ae73990867199e678bf95b3728fcd4686136e6ee9dd4c09eb490eb7cb953c388668b759263f61d6a7dfcabf27b5c9d6972455b12b66d483843286d6b871f35f912a773c97c1932255fcee05ce7b8af213879f017de4232a306a41020301000100
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "public"
@@ -303,7 +303,7 @@
 PASS: clonedKey.algorithm.publicExponent should be [010001] and was
 PASS clonedKey.algorithm.hash.name is "SHA-256"
 PASS clonedKey.usages.join(',') is ""
-Serialized key bytes: 4b0403018010030100010600a60230820122300d06092a864886f70d01010105000382010f003082010a0282010100b4c8b631194aef0154b1479ab7a534b60ca878981108680f0ae6b7c88cb6010f6dbf9f665646208410575cb923b26bf874a24b4cd801c9bba967062ae506cdcf307add4380d0d93077a4c1f0fc06d498dc729f811335c530b90fe9bf9f3979ccec050a48e8923045b19368e1e89ea4157538e8059e53320f47c155f1741310a93ed153a7f3af2d46c388b95d82518527a02b7bd9ab7edc4bcb737677f679c5c6de5e1ebed3a29d6b99b8eace2d59ceb533e001cf39c5671495d51d3ee34406ea4fdb0c626dee68da256b8a12f9f65059ccc85a2190ce1385152d62785e00cae702e77c4c597b86a6268adbf043dda68881c790f1517671fb7d198fca5ba97bef0203010001
+Serialized key bytes: 5c4b0403018010030100010600a60230820122300d06092a864886f70d01010105000382010f003082010a0282010100b4c8b631194aef0154b1479ab7a534b60ca878981108680f0ae6b7c88cb6010f6dbf9f665646208410575cb923b26bf874a24b4cd801c9bba967062ae506cdcf307add4380d0d93077a4c1f0fc06d498dc729f811335c530b90fe9bf9f3979ccec050a48e8923045b19368e1e89ea4157538e8059e53320f47c155f1741310a93ed153a7f3af2d46c388b95d82518527a02b7bd9ab7edc4bcb737677f679c5c6de5e1ebed3a29d6b99b8eace2d59ceb533e001cf39c5671495d51d3ee34406ea4fdb0c626dee68da256b8a12f9f65059ccc85a2190ce1385152d62785e00cae702e77c4c597b86a6268adbf043dda68881c790f1517671fb7d198fca5ba97bef020301000100
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "public"
@@ -324,7 +324,7 @@
 PASS: clonedKey.algorithm.publicExponent should be [010001] and was
 PASS clonedKey.algorithm.hash.name is "SHA-256"
 PASS clonedKey.usages.join(',') is "verify"
-Serialized key bytes: 4b0403018008030100010610a20130819f300d06092a864886f70d010101050003818d0030818902818100b289c62ecc3ddf64154817203439eaa0dc07a65954429a7b6098a77235673d96df1f06bd3c1ae73990867199e678bf95b3728fcd4686136e6ee9dd4c09eb490eb7cb953c388668b759263f61d6a7dfcabf27b5c9d6972455b12b66d483843286d6b871f35f912a773c97c1932255fcee05ce7b8af213879f017de4232a306a410203010001
+Serialized key bytes: 5c4b0403018008030100010610a20130819f300d06092a864886f70d010101050003818d0030818902818100b289c62ecc3ddf64154817203439eaa0dc07a65954429a7b6098a77235673d96df1f06bd3c1ae73990867199e678bf95b3728fcd4686136e6ee9dd4c09eb490eb7cb953c388668b759263f61d6a7dfcabf27b5c9d6972455b12b66d483843286d6b871f35f912a773c97c1932255fcee05ce7b8af213879f017de4232a306a41020301000100
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "public"
@@ -345,7 +345,7 @@
 PASS: clonedKey.algorithm.publicExponent should be [010001] and was
 PASS clonedKey.algorithm.hash.name is "SHA-256"
 PASS clonedKey.usages.join(',') is "verify"
-Serialized key bytes: 4b0403018010030100010610a60230820122300d06092a864886f70d01010105000382010f003082010a0282010100b4c8b631194aef0154b1479ab7a534b60ca878981108680f0ae6b7c88cb6010f6dbf9f665646208410575cb923b26bf874a24b4cd801c9bba967062ae506cdcf307add4380d0d93077a4c1f0fc06d498dc729f811335c530b90fe9bf9f3979ccec050a48e8923045b19368e1e89ea4157538e8059e53320f47c155f1741310a93ed153a7f3af2d46c388b95d82518527a02b7bd9ab7edc4bcb737677f679c5c6de5e1ebed3a29d6b99b8eace2d59ceb533e001cf39c5671495d51d3ee34406ea4fdb0c626dee68da256b8a12f9f65059ccc85a2190ce1385152d62785e00cae702e77c4c597b86a6268adbf043dda68881c790f1517671fb7d198fca5ba97bef0203010001
+Serialized key bytes: 5c4b0403018010030100010610a60230820122300d06092a864886f70d01010105000382010f003082010a0282010100b4c8b631194aef0154b1479ab7a534b60ca878981108680f0ae6b7c88cb6010f6dbf9f665646208410575cb923b26bf874a24b4cd801c9bba967062ae506cdcf307add4380d0d93077a4c1f0fc06d498dc729f811335c530b90fe9bf9f3979ccec050a48e8923045b19368e1e89ea4157538e8059e53320f47c155f1741310a93ed153a7f3af2d46c388b95d82518527a02b7bd9ab7edc4bcb737677f679c5c6de5e1ebed3a29d6b99b8eace2d59ceb533e001cf39c5671495d51d3ee34406ea4fdb0c626dee68da256b8a12f9f65059ccc85a2190ce1385152d62785e00cae702e77c4c597b86a6268adbf043dda68881c790f1517671fb7d198fca5ba97bef020301000100
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "public"
@@ -366,7 +366,7 @@
 PASS: clonedKey.algorithm.publicExponent should be [010001] and was
 PASS clonedKey.algorithm.hash.name is "SHA-512"
 PASS clonedKey.usages.join(',') is ""
-Serialized key bytes: 4b0403018008030100010801a20130819f300d06092a864886f70d010101050003818d0030818902818100b289c62ecc3ddf64154817203439eaa0dc07a65954429a7b6098a77235673d96df1f06bd3c1ae73990867199e678bf95b3728fcd4686136e6ee9dd4c09eb490eb7cb953c388668b759263f61d6a7dfcabf27b5c9d6972455b12b66d483843286d6b871f35f912a773c97c1932255fcee05ce7b8af213879f017de4232a306a410203010001
+Serialized key bytes: 5c4b0403018008030100010801a20130819f300d06092a864886f70d010101050003818d0030818902818100b289c62ecc3ddf64154817203439eaa0dc07a65954429a7b6098a77235673d96df1f06bd3c1ae73990867199e678bf95b3728fcd4686136e6ee9dd4c09eb490eb7cb953c388668b759263f61d6a7dfcabf27b5c9d6972455b12b66d483843286d6b871f35f912a773c97c1932255fcee05ce7b8af213879f017de4232a306a41020301000100
 PASS: Cloned key exported data should be [30819f300d06092a864886f70d010101050003818d0030818902818100b289c62ecc3ddf64154817203439eaa0dc07a65954429a7b6098a77235673d96df1f06bd3c1ae73990867199e678bf95b3728fcd4686136e6ee9dd4c09eb490eb7cb953c388668b759263f61d6a7dfcabf27b5c9d6972455b12b66d483843286d6b871f35f912a773c97c1932255fcee05ce7b8af213879f017de4232a306a410203010001] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -388,7 +388,7 @@
 PASS: clonedKey.algorithm.publicExponent should be [010001] and was
 PASS clonedKey.algorithm.hash.name is "SHA-512"
 PASS clonedKey.usages.join(',') is ""
-Serialized key bytes: 4b0403018010030100010801a60230820122300d06092a864886f70d01010105000382010f003082010a0282010100b4c8b631194aef0154b1479ab7a534b60ca878981108680f0ae6b7c88cb6010f6dbf9f665646208410575cb923b26bf874a24b4cd801c9bba967062ae506cdcf307add4380d0d93077a4c1f0fc06d498dc729f811335c530b90fe9bf9f3979ccec050a48e8923045b19368e1e89ea4157538e8059e53320f47c155f1741310a93ed153a7f3af2d46c388b95d82518527a02b7bd9ab7edc4bcb737677f679c5c6de5e1ebed3a29d6b99b8eace2d59ceb533e001cf39c5671495d51d3ee34406ea4fdb0c626dee68da256b8a12f9f65059ccc85a2190ce1385152d62785e00cae702e77c4c597b86a6268adbf043dda68881c790f1517671fb7d198fca5ba97bef0203010001
+Serialized key bytes: 5c4b0403018010030100010801a60230820122300d06092a864886f70d01010105000382010f003082010a0282010100b4c8b631194aef0154b1479ab7a534b60ca878981108680f0ae6b7c88cb6010f6dbf9f665646208410575cb923b26bf874a24b4cd801c9bba967062ae506cdcf307add4380d0d93077a4c1f0fc06d498dc729f811335c530b90fe9bf9f3979ccec050a48e8923045b19368e1e89ea4157538e8059e53320f47c155f1741310a93ed153a7f3af2d46c388b95d82518527a02b7bd9ab7edc4bcb737677f679c5c6de5e1ebed3a29d6b99b8eace2d59ceb533e001cf39c5671495d51d3ee34406ea4fdb0c626dee68da256b8a12f9f65059ccc85a2190ce1385152d62785e00cae702e77c4c597b86a6268adbf043dda68881c790f1517671fb7d198fca5ba97bef020301000100
 PASS: Cloned key exported data should be [30820122300d06092a864886f70d01010105000382010f003082010a0282010100b4c8b631194aef0154b1479ab7a534b60ca878981108680f0ae6b7c88cb6010f6dbf9f665646208410575cb923b26bf874a24b4cd801c9bba967062ae506cdcf307add4380d0d93077a4c1f0fc06d498dc729f811335c530b90fe9bf9f3979ccec050a48e8923045b19368e1e89ea4157538e8059e53320f47c155f1741310a93ed153a7f3af2d46c388b95d82518527a02b7bd9ab7edc4bcb737677f679c5c6de5e1ebed3a29d6b99b8eace2d59ceb533e001cf39c5671495d51d3ee34406ea4fdb0c626dee68da256b8a12f9f65059ccc85a2190ce1385152d62785e00cae702e77c4c597b86a6268adbf043dda68881c790f1517671fb7d198fca5ba97bef0203010001] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -410,7 +410,7 @@
 PASS: clonedKey.algorithm.publicExponent should be [010001] and was
 PASS clonedKey.algorithm.hash.name is "SHA-512"
 PASS clonedKey.usages.join(',') is "verify"
-Serialized key bytes: 4b0403018008030100010811a20130819f300d06092a864886f70d010101050003818d0030818902818100b289c62ecc3ddf64154817203439eaa0dc07a65954429a7b6098a77235673d96df1f06bd3c1ae73990867199e678bf95b3728fcd4686136e6ee9dd4c09eb490eb7cb953c388668b759263f61d6a7dfcabf27b5c9d6972455b12b66d483843286d6b871f35f912a773c97c1932255fcee05ce7b8af213879f017de4232a306a410203010001
+Serialized key bytes: 5c4b0403018008030100010811a20130819f300d06092a864886f70d010101050003818d0030818902818100b289c62ecc3ddf64154817203439eaa0dc07a65954429a7b6098a77235673d96df1f06bd3c1ae73990867199e678bf95b3728fcd4686136e6ee9dd4c09eb490eb7cb953c388668b759263f61d6a7dfcabf27b5c9d6972455b12b66d483843286d6b871f35f912a773c97c1932255fcee05ce7b8af213879f017de4232a306a41020301000100
 PASS: Cloned key exported data should be [30819f300d06092a864886f70d010101050003818d0030818902818100b289c62ecc3ddf64154817203439eaa0dc07a65954429a7b6098a77235673d96df1f06bd3c1ae73990867199e678bf95b3728fcd4686136e6ee9dd4c09eb490eb7cb953c388668b759263f61d6a7dfcabf27b5c9d6972455b12b66d483843286d6b871f35f912a773c97c1932255fcee05ce7b8af213879f017de4232a306a410203010001] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -432,7 +432,7 @@
 PASS: clonedKey.algorithm.publicExponent should be [010001] and was
 PASS clonedKey.algorithm.hash.name is "SHA-512"
 PASS clonedKey.usages.join(',') is "verify"
-Serialized key bytes: 4b0403018010030100010811a60230820122300d06092a864886f70d01010105000382010f003082010a0282010100b4c8b631194aef0154b1479ab7a534b60ca878981108680f0ae6b7c88cb6010f6dbf9f665646208410575cb923b26bf874a24b4cd801c9bba967062ae506cdcf307add4380d0d93077a4c1f0fc06d498dc729f811335c530b90fe9bf9f3979ccec050a48e8923045b19368e1e89ea4157538e8059e53320f47c155f1741310a93ed153a7f3af2d46c388b95d82518527a02b7bd9ab7edc4bcb737677f679c5c6de5e1ebed3a29d6b99b8eace2d59ceb533e001cf39c5671495d51d3ee34406ea4fdb0c626dee68da256b8a12f9f65059ccc85a2190ce1385152d62785e00cae702e77c4c597b86a6268adbf043dda68881c790f1517671fb7d198fca5ba97bef0203010001
+Serialized key bytes: 5c4b0403018010030100010811a60230820122300d06092a864886f70d01010105000382010f003082010a0282010100b4c8b631194aef0154b1479ab7a534b60ca878981108680f0ae6b7c88cb6010f6dbf9f665646208410575cb923b26bf874a24b4cd801c9bba967062ae506cdcf307add4380d0d93077a4c1f0fc06d498dc729f811335c530b90fe9bf9f3979ccec050a48e8923045b19368e1e89ea4157538e8059e53320f47c155f1741310a93ed153a7f3af2d46c388b95d82518527a02b7bd9ab7edc4bcb737677f679c5c6de5e1ebed3a29d6b99b8eace2d59ceb533e001cf39c5671495d51d3ee34406ea4fdb0c626dee68da256b8a12f9f65059ccc85a2190ce1385152d62785e00cae702e77c4c597b86a6268adbf043dda68881c790f1517671fb7d198fca5ba97bef020301000100
 PASS: Cloned key exported data should be [30820122300d06092a864886f70d01010105000382010f003082010a0282010100b4c8b631194aef0154b1479ab7a534b60ca878981108680f0ae6b7c88cb6010f6dbf9f665646208410575cb923b26bf874a24b4cd801c9bba967062ae506cdcf307add4380d0d93077a4c1f0fc06d498dc729f811335c530b90fe9bf9f3979ccec050a48e8923045b19368e1e89ea4157538e8059e53320f47c155f1741310a93ed153a7f3af2d46c388b95d82518527a02b7bd9ab7edc4bcb737677f679c5c6de5e1ebed3a29d6b99b8eace2d59ceb533e001cf39c5671495d51d3ee34406ea4fdb0c626dee68da256b8a12f9f65059ccc85a2190ce1385152d62785e00cae702e77c4c597b86a6268adbf043dda68881c790f1517671fb7d198fca5ba97bef0203010001] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -454,7 +454,7 @@
 PASS: clonedKey.algorithm.publicExponent should be [010001] and was
 PASS clonedKey.algorithm.hash.name is "SHA-512"
 PASS clonedKey.usages.join(',') is ""
-Serialized key bytes: 4b0403018008030100010800a20130819f300d06092a864886f70d010101050003818d0030818902818100b289c62ecc3ddf64154817203439eaa0dc07a65954429a7b6098a77235673d96df1f06bd3c1ae73990867199e678bf95b3728fcd4686136e6ee9dd4c09eb490eb7cb953c388668b759263f61d6a7dfcabf27b5c9d6972455b12b66d483843286d6b871f35f912a773c97c1932255fcee05ce7b8af213879f017de4232a306a410203010001
+Serialized key bytes: 5c4b0403018008030100010800a20130819f300d06092a864886f70d010101050003818d0030818902818100b289c62ecc3ddf64154817203439eaa0dc07a65954429a7b6098a77235673d96df1f06bd3c1ae73990867199e678bf95b3728fcd4686136e6ee9dd4c09eb490eb7cb953c388668b759263f61d6a7dfcabf27b5c9d6972455b12b66d483843286d6b871f35f912a773c97c1932255fcee05ce7b8af213879f017de4232a306a41020301000100
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "public"
@@ -475,7 +475,7 @@
 PASS: clonedKey.algorithm.publicExponent should be [010001] and was
 PASS clonedKey.algorithm.hash.name is "SHA-512"
 PASS clonedKey.usages.join(',') is ""
-Serialized key bytes: 4b0403018010030100010800a60230820122300d06092a864886f70d01010105000382010f003082010a0282010100b4c8b631194aef0154b1479ab7a534b60ca878981108680f0ae6b7c88cb6010f6dbf9f665646208410575cb923b26bf874a24b4cd801c9bba967062ae506cdcf307add4380d0d93077a4c1f0fc06d498dc729f811335c530b90fe9bf9f3979ccec050a48e8923045b19368e1e89ea4157538e8059e53320f47c155f1741310a93ed153a7f3af2d46c388b95d82518527a02b7bd9ab7edc4bcb737677f679c5c6de5e1ebed3a29d6b99b8eace2d59ceb533e001cf39c5671495d51d3ee34406ea4fdb0c626dee68da256b8a12f9f65059ccc85a2190ce1385152d62785e00cae702e77c4c597b86a6268adbf043dda68881c790f1517671fb7d198fca5ba97bef0203010001
+Serialized key bytes: 5c4b0403018010030100010800a60230820122300d06092a864886f70d01010105000382010f003082010a0282010100b4c8b631194aef0154b1479ab7a534b60ca878981108680f0ae6b7c88cb6010f6dbf9f665646208410575cb923b26bf874a24b4cd801c9bba967062ae506cdcf307add4380d0d93077a4c1f0fc06d498dc729f811335c530b90fe9bf9f3979ccec050a48e8923045b19368e1e89ea4157538e8059e53320f47c155f1741310a93ed153a7f3af2d46c388b95d82518527a02b7bd9ab7edc4bcb737677f679c5c6de5e1ebed3a29d6b99b8eace2d59ceb533e001cf39c5671495d51d3ee34406ea4fdb0c626dee68da256b8a12f9f65059ccc85a2190ce1385152d62785e00cae702e77c4c597b86a6268adbf043dda68881c790f1517671fb7d198fca5ba97bef020301000100
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "public"
@@ -496,7 +496,7 @@
 PASS: clonedKey.algorithm.publicExponent should be [010001] and was
 PASS clonedKey.algorithm.hash.name is "SHA-512"
 PASS clonedKey.usages.join(',') is "verify"
-Serialized key bytes: 4b0403018008030100010810a20130819f300d06092a864886f70d010101050003818d0030818902818100b289c62ecc3ddf64154817203439eaa0dc07a65954429a7b6098a77235673d96df1f06bd3c1ae73990867199e678bf95b3728fcd4686136e6ee9dd4c09eb490eb7cb953c388668b759263f61d6a7dfcabf27b5c9d6972455b12b66d483843286d6b871f35f912a773c97c1932255fcee05ce7b8af213879f017de4232a306a410203010001
+Serialized key bytes: 5c4b0403018008030100010810a20130819f300d06092a864886f70d010101050003818d0030818902818100b289c62ecc3ddf64154817203439eaa0dc07a65954429a7b6098a77235673d96df1f06bd3c1ae73990867199e678bf95b3728fcd4686136e6ee9dd4c09eb490eb7cb953c388668b759263f61d6a7dfcabf27b5c9d6972455b12b66d483843286d6b871f35f912a773c97c1932255fcee05ce7b8af213879f017de4232a306a41020301000100
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "public"
@@ -517,7 +517,7 @@
 PASS: clonedKey.algorithm.publicExponent should be [010001] and was
 PASS clonedKey.algorithm.hash.name is "SHA-512"
 PASS clonedKey.usages.join(',') is "verify"
-Serialized key bytes: 4b0403018010030100010810a60230820122300d06092a864886f70d01010105000382010f003082010a0282010100b4c8b631194aef0154b1479ab7a534b60ca878981108680f0ae6b7c88cb6010f6dbf9f665646208410575cb923b26bf874a24b4cd801c9bba967062ae506cdcf307add4380d0d93077a4c1f0fc06d498dc729f811335c530b90fe9bf9f3979ccec050a48e8923045b19368e1e89ea4157538e8059e53320f47c155f1741310a93ed153a7f3af2d46c388b95d82518527a02b7bd9ab7edc4bcb737677f679c5c6de5e1ebed3a29d6b99b8eace2d59ceb533e001cf39c5671495d51d3ee34406ea4fdb0c626dee68da256b8a12f9f65059ccc85a2190ce1385152d62785e00cae702e77c4c597b86a6268adbf043dda68881c790f1517671fb7d198fca5ba97bef0203010001
+Serialized key bytes: 5c4b0403018010030100010810a60230820122300d06092a864886f70d01010105000382010f003082010a0282010100b4c8b631194aef0154b1479ab7a534b60ca878981108680f0ae6b7c88cb6010f6dbf9f665646208410575cb923b26bf874a24b4cd801c9bba967062ae506cdcf307add4380d0d93077a4c1f0fc06d498dc729f811335c530b90fe9bf9f3979ccec050a48e8923045b19368e1e89ea4157538e8059e53320f47c155f1741310a93ed153a7f3af2d46c388b95d82518527a02b7bd9ab7edc4bcb737677f679c5c6de5e1ebed3a29d6b99b8eace2d59ceb533e001cf39c5671495d51d3ee34406ea4fdb0c626dee68da256b8a12f9f65059ccc85a2190ce1385152d62785e00cae702e77c4c597b86a6268adbf043dda68881c790f1517671fb7d198fca5ba97bef020301000100
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "private"
@@ -538,7 +538,7 @@
 PASS: clonedKey.algorithm.publicExponent should be [010001] and was
 PASS clonedKey.algorithm.hash.name is "SHA-1"
 PASS clonedKey.usages.join(',') is "sign"
-Serialized key bytes: 4b0403028008030100010509f90430820275020100300d06092a864886f70d01010105000482025f3082025b02010002818100a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137020301000102818033a5042a90b27d4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e894a724ac3c568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9ae55fee896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c31b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b325024100e7e8942720a877517273a356053ea2a1bc0c94aa72d55c6e86296b2dfc967948c0a72cbccca7eacb35706e09a1df55a1535bd9b3cc34160b3b6dcd3eda8e6443024100b69dca1cf7d4d7ec81e75b90fcca874abcde123fd2700180aa90479b6e48de8d67ed24f9f19d85ba275874f542cd20dc723e6963364a1f9425452b269a6799fd024028fa13938655be1f8a159cbaca5a72ea190c30089e19cd274a556f36c4f6e19f554b34c077790427bbdd8dd3ede2448328f385d81b30e8e43b2fffa02786197902401a8b38f398fa712049898d7fb79ee0a77668791299cdfa09efc0e507acb21ed74301ef5bfd48be455eaeb6e1678255827580a8e4e8e14151d1510a82a3f2e729024027156aba4126d24a81f3a528cbfb27f56886f840a9f6e86e17a44b94fe9319584b8e22fdde1e5a2e3bd8aa5ba8d8584194eb2190acf832b847f13a3d24a79f4d00
+Serialized key bytes: 5c4b0403028008030100010509f90430820275020100300d06092a864886f70d01010105000482025f3082025b02010002818100a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137020301000102818033a5042a90b27d4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e894a724ac3c568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9ae55fee896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c31b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b325024100e7e8942720a877517273a356053ea2a1bc0c94aa72d55c6e86296b2dfc967948c0a72cbccca7eacb35706e09a1df55a1535bd9b3cc34160b3b6dcd3eda8e6443024100b69dca1cf7d4d7ec81e75b90fcca874abcde123fd2700180aa90479b6e48de8d67ed24f9f19d85ba275874f542cd20dc723e6963364a1f9425452b269a6799fd024028fa13938655be1f8a159cbaca5a72ea190c30089e19cd274a556f36c4f6e19f554b34c077790427bbdd8dd3ede2448328f385d81b30e8e43b2fffa02786197902401a8b38f398fa712049898d7fb79ee0a77668791299cdfa09efc0e507acb21ed74301ef5bfd48be455eaeb6e1678255827580a8e4e8e14151d1510a82a3f2e729024027156aba4126d24a81f3a528cbfb27f56886f840a9f6e86e17a44b94fe9319584b8e22fdde1e5a2e3bd8aa5ba8d8584194eb2190acf832b847f13a3d24a79f4d
 PASS: Cloned key exported data should be [30820275020100300d06092a864886f70d01010105000482025f3082025b02010002818100a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137020301000102818033a5042a90b27d4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e894a724ac3c568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9ae55fee896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c31b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b325024100e7e8942720a877517273a356053ea2a1bc0c94aa72d55c6e86296b2dfc967948c0a72cbccca7eacb35706e09a1df55a1535bd9b3cc34160b3b6dcd3eda8e6443024100b69dca1cf7d4d7ec81e75b90fcca874abcde123fd2700180aa90479b6e48de8d67ed24f9f19d85ba275874f542cd20dc723e6963364a1f9425452b269a6799fd024028fa13938655be1f8a159cbaca5a72ea190c30089e19cd274a556f36c4f6e19f554b34c077790427bbdd8dd3ede2448328f385d81b30e8e43b2fffa02786197902401a8b38f398fa712049898d7fb79ee0a77668791299cdfa09efc0e507acb21ed74301ef5bfd48be455eaeb6e1678255827580a8e4e8e14151d1510a82a3f2e729024027156aba4126d24a81f3a528cbfb27f56886f840a9f6e86e17a44b94fe9319584b8e22fdde1e5a2e3bd8aa5ba8d8584194eb2190acf832b847f13a3d24a79f4d] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -560,7 +560,7 @@
 PASS: clonedKey.algorithm.publicExponent should be [010001] and was
 PASS clonedKey.algorithm.hash.name is "SHA-1"
 PASS clonedKey.usages.join(',') is "sign"
-Serialized key bytes: 4b0403028010030100010509c109308204bd020100300d06092a864886f70d0101010500048204a7308204a30201000282010100e085e33c42d3f3d63434e0bf1b812c444e790ff6c0becf2cc9de895afa601457bd0fafa81e2b977ab818d086d018491d7ff45be40e916c4c81b3d055ac1803b514e1010b983ff072b77fa228dd47024e65a3c72ab4e2ed02901ba43351dcd87beef92036983c42495d9efec5b4ea1113848b53287099cff1ba58a7829af733f19269101da8c10aa1d5d6b34d381dbb0704e58904c3504a1922f6956e95596780a5db08fe944ff3056ec070eafa66f8c1c5d7dcde4ce2c2694f240aec528eb699089e29f669fb3405c47d6309a609936e8b64e003b5f40743be6b7c2d5673e305cc4e2d154b2a046fba889b60913271b00d5321fd15f82cc41b2894ffc2e54d0b0203010001028201007ae930b59b8bf66f6c130a79f42fa9b117187521caf069f005eeda58c0b9fa48f1c9f58a5e41d4e22c880117dc317f4d33efeca2134b8ef2ef0a25e1d09d30e25fb4b162cc8d2c2f50bf0161c78908fd2bed15aa0e6e2ffb78327998529748b7c7e1ffbd8367718e423f390fb8736eb7b596a4067e65e58d5a4b1020927f03a293d5d3b32931d2a06542e9bbeab7e90085afc9fe145d1c28f44a97f8d9eb8c41913ed9f40261ac5f86806254e26aa8502b92779794a7b08ea299865cbdfeab4dd16307169902b46dbe132b035f7e2742f779f5b39a0b40099434a8af14c78f705abaa7474633a7c6306b2673a97aae35b6a3bf6a5fdd9a6b8d17bd6bbfa1872902818100f2bdbf99a43a4064ac5c85ccff42cccf14fa35250a8d77db6746478d0aea456377dc304688a55b1d2b14c46189ff4f92b078902ff66d144116038667cbbf5bfe80a775aa6eb9885686193debf030eaba00a8cbf26a4fdce1cb433a3a0ccd9696d64448141b0c5d9dfb32bdc29a271594d8e2bc0639daeec705b2cc12419876b702818100ecc964d844657b98dc6b3c6df58a4b5adff0cf5ac1a68679de2baccb4cda1b767f879e441769e5cc0065d8e573f9d728bbd4e25553ee8a2ba779eb219ad0a108daea34e7054d1767e644bdb63880234ac8143a9dda28d3f9196508088e2722ab86a3aa10e599b3caf226e69bee90a1ae7f289b945a34a4fed5e34f9d216b284d028180150ba27afda4174523347a5d459c5309793620396feac8037bb6ba295e52e565345520d25cb2896dc3f86ef64df296c18f0f44e103aa7d610f398b03a0c49c833a404a91563c3bb7d4b4878bd72d468c8dd614a895d30ac180cff952631dc7fa97e51fa2ae9da9d83299399e8fa2e7da19dbbe95839a99ad23af56c6166dd38d02818005da6497c3f90e391519c180a65528cfb2416d9ebcb2b5184619a647d03a83fb45e3c051c692638fcb62b91dd2e4162177a327851c720510572f7854785337e7d4217df547f843dfd99d516333ba5724fe1521edccfabd62a6f20c64c9bec5e89f876428cec421e19e62bfc892f918460bf6a101e5c8ef5b2d46552d792a00f102818100b7d0e59415405a3ce9503e95078078518d381f4273106d67863cfee642d2b82186d9932b7cd921bf1867257473ccd2058d9c88a223701701aa8370b90878df96a6950e3b3ed52326a5cabbf376c97aa644c50fafe38f7496fb9e69efdd138b3525d8b7ac162bd75fe84cb4ce7066d6b786e80c42d5e63059ae939c7bcfa497ed00
+Serialized key bytes: 5c4b0403028010030100010509c109308204bd020100300d06092a864886f70d0101010500048204a7308204a30201000282010100e085e33c42d3f3d63434e0bf1b812c444e790ff6c0becf2cc9de895afa601457bd0fafa81e2b977ab818d086d018491d7ff45be40e916c4c81b3d055ac1803b514e1010b983ff072b77fa228dd47024e65a3c72ab4e2ed02901ba43351dcd87beef92036983c42495d9efec5b4ea1113848b53287099cff1ba58a7829af733f19269101da8c10aa1d5d6b34d381dbb0704e58904c3504a1922f6956e95596780a5db08fe944ff3056ec070eafa66f8c1c5d7dcde4ce2c2694f240aec528eb699089e29f669fb3405c47d6309a609936e8b64e003b5f40743be6b7c2d5673e305cc4e2d154b2a046fba889b60913271b00d5321fd15f82cc41b2894ffc2e54d0b0203010001028201007ae930b59b8bf66f6c130a79f42fa9b117187521caf069f005eeda58c0b9fa48f1c9f58a5e41d4e22c880117dc317f4d33efeca2134b8ef2ef0a25e1d09d30e25fb4b162cc8d2c2f50bf0161c78908fd2bed15aa0e6e2ffb78327998529748b7c7e1ffbd8367718e423f390fb8736eb7b596a4067e65e58d5a4b1020927f03a293d5d3b32931d2a06542e9bbeab7e90085afc9fe145d1c28f44a97f8d9eb8c41913ed9f40261ac5f86806254e26aa8502b92779794a7b08ea299865cbdfeab4dd16307169902b46dbe132b035f7e2742f779f5b39a0b40099434a8af14c78f705abaa7474633a7c6306b2673a97aae35b6a3bf6a5fdd9a6b8d17bd6bbfa1872902818100f2bdbf99a43a4064ac5c85ccff42cccf14fa35250a8d77db6746478d0aea456377dc304688a55b1d2b14c46189ff4f92b078902ff66d144116038667cbbf5bfe80a775aa6eb9885686193debf030eaba00a8cbf26a4fdce1cb433a3a0ccd9696d64448141b0c5d9dfb32bdc29a271594d8e2bc0639daeec705b2cc12419876b702818100ecc964d844657b98dc6b3c6df58a4b5adff0cf5ac1a68679de2baccb4cda1b767f879e441769e5cc0065d8e573f9d728bbd4e25553ee8a2ba779eb219ad0a108daea34e7054d1767e644bdb63880234ac8143a9dda28d3f9196508088e2722ab86a3aa10e599b3caf226e69bee90a1ae7f289b945a34a4fed5e34f9d216b284d028180150ba27afda4174523347a5d459c5309793620396feac8037bb6ba295e52e565345520d25cb2896dc3f86ef64df296c18f0f44e103aa7d610f398b03a0c49c833a404a91563c3bb7d4b4878bd72d468c8dd614a895d30ac180cff952631dc7fa97e51fa2ae9da9d83299399e8fa2e7da19dbbe95839a99ad23af56c6166dd38d02818005da6497c3f90e391519c180a65528cfb2416d9ebcb2b5184619a647d03a83fb45e3c051c692638fcb62b91dd2e4162177a327851c720510572f7854785337e7d4217df547f843dfd99d516333ba5724fe1521edccfabd62a6f20c64c9bec5e89f876428cec421e19e62bfc892f918460bf6a101e5c8ef5b2d46552d792a00f102818100b7d0e59415405a3ce9503e95078078518d381f4273106d67863cfee642d2b82186d9932b7cd921bf1867257473ccd2058d9c88a223701701aa8370b90878df96a6950e3b3ed52326a5cabbf376c97aa644c50fafe38f7496fb9e69efdd138b3525d8b7ac162bd75fe84cb4ce7066d6b786e80c42d5e63059ae939c7bcfa497ed
 PASS: Cloned key exported data should be [308204bd020100300d06092a864886f70d0101010500048204a7308204a30201000282010100e085e33c42d3f3d63434e0bf1b812c444e790ff6c0becf2cc9de895afa601457bd0fafa81e2b977ab818d086d018491d7ff45be40e916c4c81b3d055ac1803b514e1010b983ff072b77fa228dd47024e65a3c72ab4e2ed02901ba43351dcd87beef92036983c42495d9efec5b4ea1113848b53287099cff1ba58a7829af733f19269101da8c10aa1d5d6b34d381dbb0704e58904c3504a1922f6956e95596780a5db08fe944ff3056ec070eafa66f8c1c5d7dcde4ce2c2694f240aec528eb699089e29f669fb3405c47d6309a609936e8b64e003b5f40743be6b7c2d5673e305cc4e2d154b2a046fba889b60913271b00d5321fd15f82cc41b2894ffc2e54d0b0203010001028201007ae930b59b8bf66f6c130a79f42fa9b117187521caf069f005eeda58c0b9fa48f1c9f58a5e41d4e22c880117dc317f4d33efeca2134b8ef2ef0a25e1d09d30e25fb4b162cc8d2c2f50bf0161c78908fd2bed15aa0e6e2ffb78327998529748b7c7e1ffbd8367718e423f390fb8736eb7b596a4067e65e58d5a4b1020927f03a293d5d3b32931d2a06542e9bbeab7e90085afc9fe145d1c28f44a97f8d9eb8c41913ed9f40261ac5f86806254e26aa8502b92779794a7b08ea299865cbdfeab4dd16307169902b46dbe132b035f7e2742f779f5b39a0b40099434a8af14c78f705abaa7474633a7c6306b2673a97aae35b6a3bf6a5fdd9a6b8d17bd6bbfa1872902818100f2bdbf99a43a4064ac5c85ccff42cccf14fa35250a8d77db6746478d0aea456377dc304688a55b1d2b14c46189ff4f92b078902ff66d144116038667cbbf5bfe80a775aa6eb9885686193debf030eaba00a8cbf26a4fdce1cb433a3a0ccd9696d64448141b0c5d9dfb32bdc29a271594d8e2bc0639daeec705b2cc12419876b702818100ecc964d844657b98dc6b3c6df58a4b5adff0cf5ac1a68679de2baccb4cda1b767f879e441769e5cc0065d8e573f9d728bbd4e25553ee8a2ba779eb219ad0a108daea34e7054d1767e644bdb63880234ac8143a9dda28d3f9196508088e2722ab86a3aa10e599b3caf226e69bee90a1ae7f289b945a34a4fed5e34f9d216b284d028180150ba27afda4174523347a5d459c5309793620396feac8037bb6ba295e52e565345520d25cb2896dc3f86ef64df296c18f0f44e103aa7d610f398b03a0c49c833a404a91563c3bb7d4b4878bd72d468c8dd614a895d30ac180cff952631dc7fa97e51fa2ae9da9d83299399e8fa2e7da19dbbe95839a99ad23af56c6166dd38d02818005da6497c3f90e391519c180a65528cfb2416d9ebcb2b5184619a647d03a83fb45e3c051c692638fcb62b91dd2e4162177a327851c720510572f7854785337e7d4217df547f843dfd99d516333ba5724fe1521edccfabd62a6f20c64c9bec5e89f876428cec421e19e62bfc892f918460bf6a101e5c8ef5b2d46552d792a00f102818100b7d0e59415405a3ce9503e95078078518d381f4273106d67863cfee642d2b82186d9932b7cd921bf1867257473ccd2058d9c88a223701701aa8370b90878df96a6950e3b3ed52326a5cabbf376c97aa644c50fafe38f7496fb9e69efdd138b3525d8b7ac162bd75fe84cb4ce7066d6b786e80c42d5e63059ae939c7bcfa497ed] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -582,7 +582,7 @@
 PASS: clonedKey.algorithm.publicExponent should be [010001] and was
 PASS clonedKey.algorithm.hash.name is "SHA-1"
 PASS clonedKey.usages.join(',') is "sign"
-Serialized key bytes: 4b0403028008030100010508f90430820275020100300d06092a864886f70d01010105000482025f3082025b02010002818100a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137020301000102818033a5042a90b27d4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e894a724ac3c568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9ae55fee896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c31b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b325024100e7e8942720a877517273a356053ea2a1bc0c94aa72d55c6e86296b2dfc967948c0a72cbccca7eacb35706e09a1df55a1535bd9b3cc34160b3b6dcd3eda8e6443024100b69dca1cf7d4d7ec81e75b90fcca874abcde123fd2700180aa90479b6e48de8d67ed24f9f19d85ba275874f542cd20dc723e6963364a1f9425452b269a6799fd024028fa13938655be1f8a159cbaca5a72ea190c30089e19cd274a556f36c4f6e19f554b34c077790427bbdd8dd3ede2448328f385d81b30e8e43b2fffa02786197902401a8b38f398fa712049898d7fb79ee0a77668791299cdfa09efc0e507acb21ed74301ef5bfd48be455eaeb6e1678255827580a8e4e8e14151d1510a82a3f2e729024027156aba4126d24a81f3a528cbfb27f56886f840a9f6e86e17a44b94fe9319584b8e22fdde1e5a2e3bd8aa5ba8d8584194eb2190acf832b847f13a3d24a79f4d00
+Serialized key bytes: 5c4b0403028008030100010508f90430820275020100300d06092a864886f70d01010105000482025f3082025b02010002818100a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137020301000102818033a5042a90b27d4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e894a724ac3c568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9ae55fee896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c31b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b325024100e7e8942720a877517273a356053ea2a1bc0c94aa72d55c6e86296b2dfc967948c0a72cbccca7eacb35706e09a1df55a1535bd9b3cc34160b3b6dcd3eda8e6443024100b69dca1cf7d4d7ec81e75b90fcca874abcde123fd2700180aa90479b6e48de8d67ed24f9f19d85ba275874f542cd20dc723e6963364a1f9425452b269a6799fd024028fa13938655be1f8a159cbaca5a72ea190c30089e19cd274a556f36c4f6e19f554b34c077790427bbdd8dd3ede2448328f385d81b30e8e43b2fffa02786197902401a8b38f398fa712049898d7fb79ee0a77668791299cdfa09efc0e507acb21ed74301ef5bfd48be455eaeb6e1678255827580a8e4e8e14151d1510a82a3f2e729024027156aba4126d24a81f3a528cbfb27f56886f840a9f6e86e17a44b94fe9319584b8e22fdde1e5a2e3bd8aa5ba8d8584194eb2190acf832b847f13a3d24a79f4d
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "private"
@@ -603,7 +603,7 @@
 PASS: clonedKey.algorithm.publicExponent should be [010001] and was
 PASS clonedKey.algorithm.hash.name is "SHA-1"
 PASS clonedKey.usages.join(',') is "sign"
-Serialized key bytes: 4b0403028010030100010508c109308204bd020100300d06092a864886f70d0101010500048204a7308204a30201000282010100e085e33c42d3f3d63434e0bf1b812c444e790ff6c0becf2cc9de895afa601457bd0fafa81e2b977ab818d086d018491d7ff45be40e916c4c81b3d055ac1803b514e1010b983ff072b77fa228dd47024e65a3c72ab4e2ed02901ba43351dcd87beef92036983c42495d9efec5b4ea1113848b53287099cff1ba58a7829af733f19269101da8c10aa1d5d6b34d381dbb0704e58904c3504a1922f6956e95596780a5db08fe944ff3056ec070eafa66f8c1c5d7dcde4ce2c2694f240aec528eb699089e29f669fb3405c47d6309a609936e8b64e003b5f40743be6b7c2d5673e305cc4e2d154b2a046fba889b60913271b00d5321fd15f82cc41b2894ffc2e54d0b0203010001028201007ae930b59b8bf66f6c130a79f42fa9b117187521caf069f005eeda58c0b9fa48f1c9f58a5e41d4e22c880117dc317f4d33efeca2134b8ef2ef0a25e1d09d30e25fb4b162cc8d2c2f50bf0161c78908fd2bed15aa0e6e2ffb78327998529748b7c7e1ffbd8367718e423f390fb8736eb7b596a4067e65e58d5a4b1020927f03a293d5d3b32931d2a06542e9bbeab7e90085afc9fe145d1c28f44a97f8d9eb8c41913ed9f40261ac5f86806254e26aa8502b92779794a7b08ea299865cbdfeab4dd16307169902b46dbe132b035f7e2742f779f5b39a0b40099434a8af14c78f705abaa7474633a7c6306b2673a97aae35b6a3bf6a5fdd9a6b8d17bd6bbfa1872902818100f2bdbf99a43a4064ac5c85ccff42cccf14fa35250a8d77db6746478d0aea456377dc304688a55b1d2b14c46189ff4f92b078902ff66d144116038667cbbf5bfe80a775aa6eb9885686193debf030eaba00a8cbf26a4fdce1cb433a3a0ccd9696d64448141b0c5d9dfb32bdc29a271594d8e2bc0639daeec705b2cc12419876b702818100ecc964d844657b98dc6b3c6df58a4b5adff0cf5ac1a68679de2baccb4cda1b767f879e441769e5cc0065d8e573f9d728bbd4e25553ee8a2ba779eb219ad0a108daea34e7054d1767e644bdb63880234ac8143a9dda28d3f9196508088e2722ab86a3aa10e599b3caf226e69bee90a1ae7f289b945a34a4fed5e34f9d216b284d028180150ba27afda4174523347a5d459c5309793620396feac8037bb6ba295e52e565345520d25cb2896dc3f86ef64df296c18f0f44e103aa7d610f398b03a0c49c833a404a91563c3bb7d4b4878bd72d468c8dd614a895d30ac180cff952631dc7fa97e51fa2ae9da9d83299399e8fa2e7da19dbbe95839a99ad23af56c6166dd38d02818005da6497c3f90e391519c180a65528cfb2416d9ebcb2b5184619a647d03a83fb45e3c051c692638fcb62b91dd2e4162177a327851c720510572f7854785337e7d4217df547f843dfd99d516333ba5724fe1521edccfabd62a6f20c64c9bec5e89f876428cec421e19e62bfc892f918460bf6a101e5c8ef5b2d46552d792a00f102818100b7d0e59415405a3ce9503e95078078518d381f4273106d67863cfee642d2b82186d9932b7cd921bf1867257473ccd2058d9c88a223701701aa8370b90878df96a6950e3b3ed52326a5cabbf376c97aa644c50fafe38f7496fb9e69efdd138b3525d8b7ac162bd75fe84cb4ce7066d6b786e80c42d5e63059ae939c7bcfa497ed00
+Serialized key bytes: 5c4b0403028010030100010508c109308204bd020100300d06092a864886f70d0101010500048204a7308204a30201000282010100e085e33c42d3f3d63434e0bf1b812c444e790ff6c0becf2cc9de895afa601457bd0fafa81e2b977ab818d086d018491d7ff45be40e916c4c81b3d055ac1803b514e1010b983ff072b77fa228dd47024e65a3c72ab4e2ed02901ba43351dcd87beef92036983c42495d9efec5b4ea1113848b53287099cff1ba58a7829af733f19269101da8c10aa1d5d6b34d381dbb0704e58904c3504a1922f6956e95596780a5db08fe944ff3056ec070eafa66f8c1c5d7dcde4ce2c2694f240aec528eb699089e29f669fb3405c47d6309a609936e8b64e003b5f40743be6b7c2d5673e305cc4e2d154b2a046fba889b60913271b00d5321fd15f82cc41b2894ffc2e54d0b0203010001028201007ae930b59b8bf66f6c130a79f42fa9b117187521caf069f005eeda58c0b9fa48f1c9f58a5e41d4e22c880117dc317f4d33efeca2134b8ef2ef0a25e1d09d30e25fb4b162cc8d2c2f50bf0161c78908fd2bed15aa0e6e2ffb78327998529748b7c7e1ffbd8367718e423f390fb8736eb7b596a4067e65e58d5a4b1020927f03a293d5d3b32931d2a06542e9bbeab7e90085afc9fe145d1c28f44a97f8d9eb8c41913ed9f40261ac5f86806254e26aa8502b92779794a7b08ea299865cbdfeab4dd16307169902b46dbe132b035f7e2742f779f5b39a0b40099434a8af14c78f705abaa7474633a7c6306b2673a97aae35b6a3bf6a5fdd9a6b8d17bd6bbfa1872902818100f2bdbf99a43a4064ac5c85ccff42cccf14fa35250a8d77db6746478d0aea456377dc304688a55b1d2b14c46189ff4f92b078902ff66d144116038667cbbf5bfe80a775aa6eb9885686193debf030eaba00a8cbf26a4fdce1cb433a3a0ccd9696d64448141b0c5d9dfb32bdc29a271594d8e2bc0639daeec705b2cc12419876b702818100ecc964d844657b98dc6b3c6df58a4b5adff0cf5ac1a68679de2baccb4cda1b767f879e441769e5cc0065d8e573f9d728bbd4e25553ee8a2ba779eb219ad0a108daea34e7054d1767e644bdb63880234ac8143a9dda28d3f9196508088e2722ab86a3aa10e599b3caf226e69bee90a1ae7f289b945a34a4fed5e34f9d216b284d028180150ba27afda4174523347a5d459c5309793620396feac8037bb6ba295e52e565345520d25cb2896dc3f86ef64df296c18f0f44e103aa7d610f398b03a0c49c833a404a91563c3bb7d4b4878bd72d468c8dd614a895d30ac180cff952631dc7fa97e51fa2ae9da9d83299399e8fa2e7da19dbbe95839a99ad23af56c6166dd38d02818005da6497c3f90e391519c180a65528cfb2416d9ebcb2b5184619a647d03a83fb45e3c051c692638fcb62b91dd2e4162177a327851c720510572f7854785337e7d4217df547f843dfd99d516333ba5724fe1521edccfabd62a6f20c64c9bec5e89f876428cec421e19e62bfc892f918460bf6a101e5c8ef5b2d46552d792a00f102818100b7d0e59415405a3ce9503e95078078518d381f4273106d67863cfee642d2b82186d9932b7cd921bf1867257473ccd2058d9c88a223701701aa8370b90878df96a6950e3b3ed52326a5cabbf376c97aa644c50fafe38f7496fb9e69efdd138b3525d8b7ac162bd75fe84cb4ce7066d6b786e80c42d5e63059ae939c7bcfa497ed
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "private"
@@ -624,7 +624,7 @@
 PASS: clonedKey.algorithm.publicExponent should be [010001] and was
 PASS clonedKey.algorithm.hash.name is "SHA-256"
 PASS clonedKey.usages.join(',') is "sign"
-Serialized key bytes: 4b0403028008030100010609f90430820275020100300d06092a864886f70d01010105000482025f3082025b02010002818100a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137020301000102818033a5042a90b27d4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e894a724ac3c568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9ae55fee896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c31b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b325024100e7e8942720a877517273a356053ea2a1bc0c94aa72d55c6e86296b2dfc967948c0a72cbccca7eacb35706e09a1df55a1535bd9b3cc34160b3b6dcd3eda8e6443024100b69dca1cf7d4d7ec81e75b90fcca874abcde123fd2700180aa90479b6e48de8d67ed24f9f19d85ba275874f542cd20dc723e6963364a1f9425452b269a6799fd024028fa13938655be1f8a159cbaca5a72ea190c30089e19cd274a556f36c4f6e19f554b34c077790427bbdd8dd3ede2448328f385d81b30e8e43b2fffa02786197902401a8b38f398fa712049898d7fb79ee0a77668791299cdfa09efc0e507acb21ed74301ef5bfd48be455eaeb6e1678255827580a8e4e8e14151d1510a82a3f2e729024027156aba4126d24a81f3a528cbfb27f56886f840a9f6e86e17a44b94fe9319584b8e22fdde1e5a2e3bd8aa5ba8d8584194eb2190acf832b847f13a3d24a79f4d00
+Serialized key bytes: 5c4b0403028008030100010609f90430820275020100300d06092a864886f70d01010105000482025f3082025b02010002818100a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137020301000102818033a5042a90b27d4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e894a724ac3c568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9ae55fee896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c31b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b325024100e7e8942720a877517273a356053ea2a1bc0c94aa72d55c6e86296b2dfc967948c0a72cbccca7eacb35706e09a1df55a1535bd9b3cc34160b3b6dcd3eda8e6443024100b69dca1cf7d4d7ec81e75b90fcca874abcde123fd2700180aa90479b6e48de8d67ed24f9f19d85ba275874f542cd20dc723e6963364a1f9425452b269a6799fd024028fa13938655be1f8a159cbaca5a72ea190c30089e19cd274a556f36c4f6e19f554b34c077790427bbdd8dd3ede2448328f385d81b30e8e43b2fffa02786197902401a8b38f398fa712049898d7fb79ee0a77668791299cdfa09efc0e507acb21ed74301ef5bfd48be455eaeb6e1678255827580a8e4e8e14151d1510a82a3f2e729024027156aba4126d24a81f3a528cbfb27f56886f840a9f6e86e17a44b94fe9319584b8e22fdde1e5a2e3bd8aa5ba8d8584194eb2190acf832b847f13a3d24a79f4d
 PASS: Cloned key exported data should be [30820275020100300d06092a864886f70d01010105000482025f3082025b02010002818100a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137020301000102818033a5042a90b27d4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e894a724ac3c568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9ae55fee896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c31b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b325024100e7e8942720a877517273a356053ea2a1bc0c94aa72d55c6e86296b2dfc967948c0a72cbccca7eacb35706e09a1df55a1535bd9b3cc34160b3b6dcd3eda8e6443024100b69dca1cf7d4d7ec81e75b90fcca874abcde123fd2700180aa90479b6e48de8d67ed24f9f19d85ba275874f542cd20dc723e6963364a1f9425452b269a6799fd024028fa13938655be1f8a159cbaca5a72ea190c30089e19cd274a556f36c4f6e19f554b34c077790427bbdd8dd3ede2448328f385d81b30e8e43b2fffa02786197902401a8b38f398fa712049898d7fb79ee0a77668791299cdfa09efc0e507acb21ed74301ef5bfd48be455eaeb6e1678255827580a8e4e8e14151d1510a82a3f2e729024027156aba4126d24a81f3a528cbfb27f56886f840a9f6e86e17a44b94fe9319584b8e22fdde1e5a2e3bd8aa5ba8d8584194eb2190acf832b847f13a3d24a79f4d] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -646,7 +646,7 @@
 PASS: clonedKey.algorithm.publicExponent should be [010001] and was
 PASS clonedKey.algorithm.hash.name is "SHA-256"
 PASS clonedKey.usages.join(',') is "sign"
-Serialized key bytes: 4b0403028010030100010609c109308204bd020100300d06092a864886f70d0101010500048204a7308204a30201000282010100e085e33c42d3f3d63434e0bf1b812c444e790ff6c0becf2cc9de895afa601457bd0fafa81e2b977ab818d086d018491d7ff45be40e916c4c81b3d055ac1803b514e1010b983ff072b77fa228dd47024e65a3c72ab4e2ed02901ba43351dcd87beef92036983c42495d9efec5b4ea1113848b53287099cff1ba58a7829af733f19269101da8c10aa1d5d6b34d381dbb0704e58904c3504a1922f6956e95596780a5db08fe944ff3056ec070eafa66f8c1c5d7dcde4ce2c2694f240aec528eb699089e29f669fb3405c47d6309a609936e8b64e003b5f40743be6b7c2d5673e305cc4e2d154b2a046fba889b60913271b00d5321fd15f82cc41b2894ffc2e54d0b0203010001028201007ae930b59b8bf66f6c130a79f42fa9b117187521caf069f005eeda58c0b9fa48f1c9f58a5e41d4e22c880117dc317f4d33efeca2134b8ef2ef0a25e1d09d30e25fb4b162cc8d2c2f50bf0161c78908fd2bed15aa0e6e2ffb78327998529748b7c7e1ffbd8367718e423f390fb8736eb7b596a4067e65e58d5a4b1020927f03a293d5d3b32931d2a06542e9bbeab7e90085afc9fe145d1c28f44a97f8d9eb8c41913ed9f40261ac5f86806254e26aa8502b92779794a7b08ea299865cbdfeab4dd16307169902b46dbe132b035f7e2742f779f5b39a0b40099434a8af14c78f705abaa7474633a7c6306b2673a97aae35b6a3bf6a5fdd9a6b8d17bd6bbfa1872902818100f2bdbf99a43a4064ac5c85ccff42cccf14fa35250a8d77db6746478d0aea456377dc304688a55b1d2b14c46189ff4f92b078902ff66d144116038667cbbf5bfe80a775aa6eb9885686193debf030eaba00a8cbf26a4fdce1cb433a3a0ccd9696d64448141b0c5d9dfb32bdc29a271594d8e2bc0639daeec705b2cc12419876b702818100ecc964d844657b98dc6b3c6df58a4b5adff0cf5ac1a68679de2baccb4cda1b767f879e441769e5cc0065d8e573f9d728bbd4e25553ee8a2ba779eb219ad0a108daea34e7054d1767e644bdb63880234ac8143a9dda28d3f9196508088e2722ab86a3aa10e599b3caf226e69bee90a1ae7f289b945a34a4fed5e34f9d216b284d028180150ba27afda4174523347a5d459c5309793620396feac8037bb6ba295e52e565345520d25cb2896dc3f86ef64df296c18f0f44e103aa7d610f398b03a0c49c833a404a91563c3bb7d4b4878bd72d468c8dd614a895d30ac180cff952631dc7fa97e51fa2ae9da9d83299399e8fa2e7da19dbbe95839a99ad23af56c6166dd38d02818005da6497c3f90e391519c180a65528cfb2416d9ebcb2b5184619a647d03a83fb45e3c051c692638fcb62b91dd2e4162177a327851c720510572f7854785337e7d4217df547f843dfd99d516333ba5724fe1521edccfabd62a6f20c64c9bec5e89f876428cec421e19e62bfc892f918460bf6a101e5c8ef5b2d46552d792a00f102818100b7d0e59415405a3ce9503e95078078518d381f4273106d67863cfee642d2b82186d9932b7cd921bf1867257473ccd2058d9c88a223701701aa8370b90878df96a6950e3b3ed52326a5cabbf376c97aa644c50fafe38f7496fb9e69efdd138b3525d8b7ac162bd75fe84cb4ce7066d6b786e80c42d5e63059ae939c7bcfa497ed00
+Serialized key bytes: 5c4b0403028010030100010609c109308204bd020100300d06092a864886f70d0101010500048204a7308204a30201000282010100e085e33c42d3f3d63434e0bf1b812c444e790ff6c0becf2cc9de895afa601457bd0fafa81e2b977ab818d086d018491d7ff45be40e916c4c81b3d055ac1803b514e1010b983ff072b77fa228dd47024e65a3c72ab4e2ed02901ba43351dcd87beef92036983c42495d9efec5b4ea1113848b53287099cff1ba58a7829af733f19269101da8c10aa1d5d6b34d381dbb0704e58904c3504a1922f6956e95596780a5db08fe944ff3056ec070eafa66f8c1c5d7dcde4ce2c2694f240aec528eb699089e29f669fb3405c47d6309a609936e8b64e003b5f40743be6b7c2d5673e305cc4e2d154b2a046fba889b60913271b00d5321fd15f82cc41b2894ffc2e54d0b0203010001028201007ae930b59b8bf66f6c130a79f42fa9b117187521caf069f005eeda58c0b9fa48f1c9f58a5e41d4e22c880117dc317f4d33efeca2134b8ef2ef0a25e1d09d30e25fb4b162cc8d2c2f50bf0161c78908fd2bed15aa0e6e2ffb78327998529748b7c7e1ffbd8367718e423f390fb8736eb7b596a4067e65e58d5a4b1020927f03a293d5d3b32931d2a06542e9bbeab7e90085afc9fe145d1c28f44a97f8d9eb8c41913ed9f40261ac5f86806254e26aa8502b92779794a7b08ea299865cbdfeab4dd16307169902b46dbe132b035f7e2742f779f5b39a0b40099434a8af14c78f705abaa7474633a7c6306b2673a97aae35b6a3bf6a5fdd9a6b8d17bd6bbfa1872902818100f2bdbf99a43a4064ac5c85ccff42cccf14fa35250a8d77db6746478d0aea456377dc304688a55b1d2b14c46189ff4f92b078902ff66d144116038667cbbf5bfe80a775aa6eb9885686193debf030eaba00a8cbf26a4fdce1cb433a3a0ccd9696d64448141b0c5d9dfb32bdc29a271594d8e2bc0639daeec705b2cc12419876b702818100ecc964d844657b98dc6b3c6df58a4b5adff0cf5ac1a68679de2baccb4cda1b767f879e441769e5cc0065d8e573f9d728bbd4e25553ee8a2ba779eb219ad0a108daea34e7054d1767e644bdb63880234ac8143a9dda28d3f9196508088e2722ab86a3aa10e599b3caf226e69bee90a1ae7f289b945a34a4fed5e34f9d216b284d028180150ba27afda4174523347a5d459c5309793620396feac8037bb6ba295e52e565345520d25cb2896dc3f86ef64df296c18f0f44e103aa7d610f398b03a0c49c833a404a91563c3bb7d4b4878bd72d468c8dd614a895d30ac180cff952631dc7fa97e51fa2ae9da9d83299399e8fa2e7da19dbbe95839a99ad23af56c6166dd38d02818005da6497c3f90e391519c180a65528cfb2416d9ebcb2b5184619a647d03a83fb45e3c051c692638fcb62b91dd2e4162177a327851c720510572f7854785337e7d4217df547f843dfd99d516333ba5724fe1521edccfabd62a6f20c64c9bec5e89f876428cec421e19e62bfc892f918460bf6a101e5c8ef5b2d46552d792a00f102818100b7d0e59415405a3ce9503e95078078518d381f4273106d67863cfee642d2b82186d9932b7cd921bf1867257473ccd2058d9c88a223701701aa8370b90878df96a6950e3b3ed52326a5cabbf376c97aa644c50fafe38f7496fb9e69efdd138b3525d8b7ac162bd75fe84cb4ce7066d6b786e80c42d5e63059ae939c7bcfa497ed
 PASS: Cloned key exported data should be [308204bd020100300d06092a864886f70d0101010500048204a7308204a30201000282010100e085e33c42d3f3d63434e0bf1b812c444e790ff6c0becf2cc9de895afa601457bd0fafa81e2b977ab818d086d018491d7ff45be40e916c4c81b3d055ac1803b514e1010b983ff072b77fa228dd47024e65a3c72ab4e2ed02901ba43351dcd87beef92036983c42495d9efec5b4ea1113848b53287099cff1ba58a7829af733f19269101da8c10aa1d5d6b34d381dbb0704e58904c3504a1922f6956e95596780a5db08fe944ff3056ec070eafa66f8c1c5d7dcde4ce2c2694f240aec528eb699089e29f669fb3405c47d6309a609936e8b64e003b5f40743be6b7c2d5673e305cc4e2d154b2a046fba889b60913271b00d5321fd15f82cc41b2894ffc2e54d0b0203010001028201007ae930b59b8bf66f6c130a79f42fa9b117187521caf069f005eeda58c0b9fa48f1c9f58a5e41d4e22c880117dc317f4d33efeca2134b8ef2ef0a25e1d09d30e25fb4b162cc8d2c2f50bf0161c78908fd2bed15aa0e6e2ffb78327998529748b7c7e1ffbd8367718e423f390fb8736eb7b596a4067e65e58d5a4b1020927f03a293d5d3b32931d2a06542e9bbeab7e90085afc9fe145d1c28f44a97f8d9eb8c41913ed9f40261ac5f86806254e26aa8502b92779794a7b08ea299865cbdfeab4dd16307169902b46dbe132b035f7e2742f779f5b39a0b40099434a8af14c78f705abaa7474633a7c6306b2673a97aae35b6a3bf6a5fdd9a6b8d17bd6bbfa1872902818100f2bdbf99a43a4064ac5c85ccff42cccf14fa35250a8d77db6746478d0aea456377dc304688a55b1d2b14c46189ff4f92b078902ff66d144116038667cbbf5bfe80a775aa6eb9885686193debf030eaba00a8cbf26a4fdce1cb433a3a0ccd9696d64448141b0c5d9dfb32bdc29a271594d8e2bc0639daeec705b2cc12419876b702818100ecc964d844657b98dc6b3c6df58a4b5adff0cf5ac1a68679de2baccb4cda1b767f879e441769e5cc0065d8e573f9d728bbd4e25553ee8a2ba779eb219ad0a108daea34e7054d1767e644bdb63880234ac8143a9dda28d3f9196508088e2722ab86a3aa10e599b3caf226e69bee90a1ae7f289b945a34a4fed5e34f9d216b284d028180150ba27afda4174523347a5d459c5309793620396feac8037bb6ba295e52e565345520d25cb2896dc3f86ef64df296c18f0f44e103aa7d610f398b03a0c49c833a404a91563c3bb7d4b4878bd72d468c8dd614a895d30ac180cff952631dc7fa97e51fa2ae9da9d83299399e8fa2e7da19dbbe95839a99ad23af56c6166dd38d02818005da6497c3f90e391519c180a65528cfb2416d9ebcb2b5184619a647d03a83fb45e3c051c692638fcb62b91dd2e4162177a327851c720510572f7854785337e7d4217df547f843dfd99d516333ba5724fe1521edccfabd62a6f20c64c9bec5e89f876428cec421e19e62bfc892f918460bf6a101e5c8ef5b2d46552d792a00f102818100b7d0e59415405a3ce9503e95078078518d381f4273106d67863cfee642d2b82186d9932b7cd921bf1867257473ccd2058d9c88a223701701aa8370b90878df96a6950e3b3ed52326a5cabbf376c97aa644c50fafe38f7496fb9e69efdd138b3525d8b7ac162bd75fe84cb4ce7066d6b786e80c42d5e63059ae939c7bcfa497ed] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -668,7 +668,7 @@
 PASS: clonedKey.algorithm.publicExponent should be [010001] and was
 PASS clonedKey.algorithm.hash.name is "SHA-256"
 PASS clonedKey.usages.join(',') is "sign"
-Serialized key bytes: 4b0403028008030100010608f90430820275020100300d06092a864886f70d01010105000482025f3082025b02010002818100a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137020301000102818033a5042a90b27d4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e894a724ac3c568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9ae55fee896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c31b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b325024100e7e8942720a877517273a356053ea2a1bc0c94aa72d55c6e86296b2dfc967948c0a72cbccca7eacb35706e09a1df55a1535bd9b3cc34160b3b6dcd3eda8e6443024100b69dca1cf7d4d7ec81e75b90fcca874abcde123fd2700180aa90479b6e48de8d67ed24f9f19d85ba275874f542cd20dc723e6963364a1f9425452b269a6799fd024028fa13938655be1f8a159cbaca5a72ea190c30089e19cd274a556f36c4f6e19f554b34c077790427bbdd8dd3ede2448328f385d81b30e8e43b2fffa02786197902401a8b38f398fa712049898d7fb79ee0a77668791299cdfa09efc0e507acb21ed74301ef5bfd48be455eaeb6e1678255827580a8e4e8e14151d1510a82a3f2e729024027156aba4126d24a81f3a528cbfb27f56886f840a9f6e86e17a44b94fe9319584b8e22fdde1e5a2e3bd8aa5ba8d8584194eb2190acf832b847f13a3d24a79f4d00
+Serialized key bytes: 5c4b0403028008030100010608f90430820275020100300d06092a864886f70d01010105000482025f3082025b02010002818100a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137020301000102818033a5042a90b27d4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e894a724ac3c568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9ae55fee896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c31b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b325024100e7e8942720a877517273a356053ea2a1bc0c94aa72d55c6e86296b2dfc967948c0a72cbccca7eacb35706e09a1df55a1535bd9b3cc34160b3b6dcd3eda8e6443024100b69dca1cf7d4d7ec81e75b90fcca874abcde123fd2700180aa90479b6e48de8d67ed24f9f19d85ba275874f542cd20dc723e6963364a1f9425452b269a6799fd024028fa13938655be1f8a159cbaca5a72ea190c30089e19cd274a556f36c4f6e19f554b34c077790427bbdd8dd3ede2448328f385d81b30e8e43b2fffa02786197902401a8b38f398fa712049898d7fb79ee0a77668791299cdfa09efc0e507acb21ed74301ef5bfd48be455eaeb6e1678255827580a8e4e8e14151d1510a82a3f2e729024027156aba4126d24a81f3a528cbfb27f56886f840a9f6e86e17a44b94fe9319584b8e22fdde1e5a2e3bd8aa5ba8d8584194eb2190acf832b847f13a3d24a79f4d
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "private"
@@ -689,7 +689,7 @@
 PASS: clonedKey.algorithm.publicExponent should be [010001] and was
 PASS clonedKey.algorithm.hash.name is "SHA-256"
 PASS clonedKey.usages.join(',') is "sign"
-Serialized key bytes: 4b0403028010030100010608c109308204bd020100300d06092a864886f70d0101010500048204a7308204a30201000282010100e085e33c42d3f3d63434e0bf1b812c444e790ff6c0becf2cc9de895afa601457bd0fafa81e2b977ab818d086d018491d7ff45be40e916c4c81b3d055ac1803b514e1010b983ff072b77fa228dd47024e65a3c72ab4e2ed02901ba43351dcd87beef92036983c42495d9efec5b4ea1113848b53287099cff1ba58a7829af733f19269101da8c10aa1d5d6b34d381dbb0704e58904c3504a1922f6956e95596780a5db08fe944ff3056ec070eafa66f8c1c5d7dcde4ce2c2694f240aec528eb699089e29f669fb3405c47d6309a609936e8b64e003b5f40743be6b7c2d5673e305cc4e2d154b2a046fba889b60913271b00d5321fd15f82cc41b2894ffc2e54d0b0203010001028201007ae930b59b8bf66f6c130a79f42fa9b117187521caf069f005eeda58c0b9fa48f1c9f58a5e41d4e22c880117dc317f4d33efeca2134b8ef2ef0a25e1d09d30e25fb4b162cc8d2c2f50bf0161c78908fd2bed15aa0e6e2ffb78327998529748b7c7e1ffbd8367718e423f390fb8736eb7b596a4067e65e58d5a4b1020927f03a293d5d3b32931d2a06542e9bbeab7e90085afc9fe145d1c28f44a97f8d9eb8c41913ed9f40261ac5f86806254e26aa8502b92779794a7b08ea299865cbdfeab4dd16307169902b46dbe132b035f7e2742f779f5b39a0b40099434a8af14c78f705abaa7474633a7c6306b2673a97aae35b6a3bf6a5fdd9a6b8d17bd6bbfa1872902818100f2bdbf99a43a4064ac5c85ccff42cccf14fa35250a8d77db6746478d0aea456377dc304688a55b1d2b14c46189ff4f92b078902ff66d144116038667cbbf5bfe80a775aa6eb9885686193debf030eaba00a8cbf26a4fdce1cb433a3a0ccd9696d64448141b0c5d9dfb32bdc29a271594d8e2bc0639daeec705b2cc12419876b702818100ecc964d844657b98dc6b3c6df58a4b5adff0cf5ac1a68679de2baccb4cda1b767f879e441769e5cc0065d8e573f9d728bbd4e25553ee8a2ba779eb219ad0a108daea34e7054d1767e644bdb63880234ac8143a9dda28d3f9196508088e2722ab86a3aa10e599b3caf226e69bee90a1ae7f289b945a34a4fed5e34f9d216b284d028180150ba27afda4174523347a5d459c5309793620396feac8037bb6ba295e52e565345520d25cb2896dc3f86ef64df296c18f0f44e103aa7d610f398b03a0c49c833a404a91563c3bb7d4b4878bd72d468c8dd614a895d30ac180cff952631dc7fa97e51fa2ae9da9d83299399e8fa2e7da19dbbe95839a99ad23af56c6166dd38d02818005da6497c3f90e391519c180a65528cfb2416d9ebcb2b5184619a647d03a83fb45e3c051c692638fcb62b91dd2e4162177a327851c720510572f7854785337e7d4217df547f843dfd99d516333ba5724fe1521edccfabd62a6f20c64c9bec5e89f876428cec421e19e62bfc892f918460bf6a101e5c8ef5b2d46552d792a00f102818100b7d0e59415405a3ce9503e95078078518d381f4273106d67863cfee642d2b82186d9932b7cd921bf1867257473ccd2058d9c88a223701701aa8370b90878df96a6950e3b3ed52326a5cabbf376c97aa644c50fafe38f7496fb9e69efdd138b3525d8b7ac162bd75fe84cb4ce7066d6b786e80c42d5e63059ae939c7bcfa497ed00
+Serialized key bytes: 5c4b0403028010030100010608c109308204bd020100300d06092a864886f70d0101010500048204a7308204a30201000282010100e085e33c42d3f3d63434e0bf1b812c444e790ff6c0becf2cc9de895afa601457bd0fafa81e2b977ab818d086d018491d7ff45be40e916c4c81b3d055ac1803b514e1010b983ff072b77fa228dd47024e65a3c72ab4e2ed02901ba43351dcd87beef92036983c42495d9efec5b4ea1113848b53287099cff1ba58a7829af733f19269101da8c10aa1d5d6b34d381dbb0704e58904c3504a1922f6956e95596780a5db08fe944ff3056ec070eafa66f8c1c5d7dcde4ce2c2694f240aec528eb699089e29f669fb3405c47d6309a609936e8b64e003b5f40743be6b7c2d5673e305cc4e2d154b2a046fba889b60913271b00d5321fd15f82cc41b2894ffc2e54d0b0203010001028201007ae930b59b8bf66f6c130a79f42fa9b117187521caf069f005eeda58c0b9fa48f1c9f58a5e41d4e22c880117dc317f4d33efeca2134b8ef2ef0a25e1d09d30e25fb4b162cc8d2c2f50bf0161c78908fd2bed15aa0e6e2ffb78327998529748b7c7e1ffbd8367718e423f390fb8736eb7b596a4067e65e58d5a4b1020927f03a293d5d3b32931d2a06542e9bbeab7e90085afc9fe145d1c28f44a97f8d9eb8c41913ed9f40261ac5f86806254e26aa8502b92779794a7b08ea299865cbdfeab4dd16307169902b46dbe132b035f7e2742f779f5b39a0b40099434a8af14c78f705abaa7474633a7c6306b2673a97aae35b6a3bf6a5fdd9a6b8d17bd6bbfa1872902818100f2bdbf99a43a4064ac5c85ccff42cccf14fa35250a8d77db6746478d0aea456377dc304688a55b1d2b14c46189ff4f92b078902ff66d144116038667cbbf5bfe80a775aa6eb9885686193debf030eaba00a8cbf26a4fdce1cb433a3a0ccd9696d64448141b0c5d9dfb32bdc29a271594d8e2bc0639daeec705b2cc12419876b702818100ecc964d844657b98dc6b3c6df58a4b5adff0cf5ac1a68679de2baccb4cda1b767f879e441769e5cc0065d8e573f9d728bbd4e25553ee8a2ba779eb219ad0a108daea34e7054d1767e644bdb63880234ac8143a9dda28d3f9196508088e2722ab86a3aa10e599b3caf226e69bee90a1ae7f289b945a34a4fed5e34f9d216b284d028180150ba27afda4174523347a5d459c5309793620396feac8037bb6ba295e52e565345520d25cb2896dc3f86ef64df296c18f0f44e103aa7d610f398b03a0c49c833a404a91563c3bb7d4b4878bd72d468c8dd614a895d30ac180cff952631dc7fa97e51fa2ae9da9d83299399e8fa2e7da19dbbe95839a99ad23af56c6166dd38d02818005da6497c3f90e391519c180a65528cfb2416d9ebcb2b5184619a647d03a83fb45e3c051c692638fcb62b91dd2e4162177a327851c720510572f7854785337e7d4217df547f843dfd99d516333ba5724fe1521edccfabd62a6f20c64c9bec5e89f876428cec421e19e62bfc892f918460bf6a101e5c8ef5b2d46552d792a00f102818100b7d0e59415405a3ce9503e95078078518d381f4273106d67863cfee642d2b82186d9932b7cd921bf1867257473ccd2058d9c88a223701701aa8370b90878df96a6950e3b3ed52326a5cabbf376c97aa644c50fafe38f7496fb9e69efdd138b3525d8b7ac162bd75fe84cb4ce7066d6b786e80c42d5e63059ae939c7bcfa497ed
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "private"
@@ -710,7 +710,7 @@
 PASS: clonedKey.algorithm.publicExponent should be [010001] and was
 PASS clonedKey.algorithm.hash.name is "SHA-512"
 PASS clonedKey.usages.join(',') is "sign"
-Serialized key bytes: 4b0403028008030100010809f90430820275020100300d06092a864886f70d01010105000482025f3082025b02010002818100a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137020301000102818033a5042a90b27d4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e894a724ac3c568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9ae55fee896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c31b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b325024100e7e8942720a877517273a356053ea2a1bc0c94aa72d55c6e86296b2dfc967948c0a72cbccca7eacb35706e09a1df55a1535bd9b3cc34160b3b6dcd3eda8e6443024100b69dca1cf7d4d7ec81e75b90fcca874abcde123fd2700180aa90479b6e48de8d67ed24f9f19d85ba275874f542cd20dc723e6963364a1f9425452b269a6799fd024028fa13938655be1f8a159cbaca5a72ea190c30089e19cd274a556f36c4f6e19f554b34c077790427bbdd8dd3ede2448328f385d81b30e8e43b2fffa02786197902401a8b38f398fa712049898d7fb79ee0a77668791299cdfa09efc0e507acb21ed74301ef5bfd48be455eaeb6e1678255827580a8e4e8e14151d1510a82a3f2e729024027156aba4126d24a81f3a528cbfb27f56886f840a9f6e86e17a44b94fe9319584b8e22fdde1e5a2e3bd8aa5ba8d8584194eb2190acf832b847f13a3d24a79f4d00
+Serialized key bytes: 5c4b0403028008030100010809f90430820275020100300d06092a864886f70d01010105000482025f3082025b02010002818100a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137020301000102818033a5042a90b27d4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e894a724ac3c568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9ae55fee896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c31b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b325024100e7e8942720a877517273a356053ea2a1bc0c94aa72d55c6e86296b2dfc967948c0a72cbccca7eacb35706e09a1df55a1535bd9b3cc34160b3b6dcd3eda8e6443024100b69dca1cf7d4d7ec81e75b90fcca874abcde123fd2700180aa90479b6e48de8d67ed24f9f19d85ba275874f542cd20dc723e6963364a1f9425452b269a6799fd024028fa13938655be1f8a159cbaca5a72ea190c30089e19cd274a556f36c4f6e19f554b34c077790427bbdd8dd3ede2448328f385d81b30e8e43b2fffa02786197902401a8b38f398fa712049898d7fb79ee0a77668791299cdfa09efc0e507acb21ed74301ef5bfd48be455eaeb6e1678255827580a8e4e8e14151d1510a82a3f2e729024027156aba4126d24a81f3a528cbfb27f56886f840a9f6e86e17a44b94fe9319584b8e22fdde1e5a2e3bd8aa5ba8d8584194eb2190acf832b847f13a3d24a79f4d
 PASS: Cloned key exported data should be [30820275020100300d06092a864886f70d01010105000482025f3082025b02010002818100a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137020301000102818033a5042a90b27d4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e894a724ac3c568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9ae55fee896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c31b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b325024100e7e8942720a877517273a356053ea2a1bc0c94aa72d55c6e86296b2dfc967948c0a72cbccca7eacb35706e09a1df55a1535bd9b3cc34160b3b6dcd3eda8e6443024100b69dca1cf7d4d7ec81e75b90fcca874abcde123fd2700180aa90479b6e48de8d67ed24f9f19d85ba275874f542cd20dc723e6963364a1f9425452b269a6799fd024028fa13938655be1f8a159cbaca5a72ea190c30089e19cd274a556f36c4f6e19f554b34c077790427bbdd8dd3ede2448328f385d81b30e8e43b2fffa02786197902401a8b38f398fa712049898d7fb79ee0a77668791299cdfa09efc0e507acb21ed74301ef5bfd48be455eaeb6e1678255827580a8e4e8e14151d1510a82a3f2e729024027156aba4126d24a81f3a528cbfb27f56886f840a9f6e86e17a44b94fe9319584b8e22fdde1e5a2e3bd8aa5ba8d8584194eb2190acf832b847f13a3d24a79f4d] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -732,7 +732,7 @@
 PASS: clonedKey.algorithm.publicExponent should be [010001] and was
 PASS clonedKey.algorithm.hash.name is "SHA-512"
 PASS clonedKey.usages.join(',') is "sign"
-Serialized key bytes: 4b0403028010030100010809c109308204bd020100300d06092a864886f70d0101010500048204a7308204a30201000282010100e085e33c42d3f3d63434e0bf1b812c444e790ff6c0becf2cc9de895afa601457bd0fafa81e2b977ab818d086d018491d7ff45be40e916c4c81b3d055ac1803b514e1010b983ff072b77fa228dd47024e65a3c72ab4e2ed02901ba43351dcd87beef92036983c42495d9efec5b4ea1113848b53287099cff1ba58a7829af733f19269101da8c10aa1d5d6b34d381dbb0704e58904c3504a1922f6956e95596780a5db08fe944ff3056ec070eafa66f8c1c5d7dcde4ce2c2694f240aec528eb699089e29f669fb3405c47d6309a609936e8b64e003b5f40743be6b7c2d5673e305cc4e2d154b2a046fba889b60913271b00d5321fd15f82cc41b2894ffc2e54d0b0203010001028201007ae930b59b8bf66f6c130a79f42fa9b117187521caf069f005eeda58c0b9fa48f1c9f58a5e41d4e22c880117dc317f4d33efeca2134b8ef2ef0a25e1d09d30e25fb4b162cc8d2c2f50bf0161c78908fd2bed15aa0e6e2ffb78327998529748b7c7e1ffbd8367718e423f390fb8736eb7b596a4067e65e58d5a4b1020927f03a293d5d3b32931d2a06542e9bbeab7e90085afc9fe145d1c28f44a97f8d9eb8c41913ed9f40261ac5f86806254e26aa8502b92779794a7b08ea299865cbdfeab4dd16307169902b46dbe132b035f7e2742f779f5b39a0b40099434a8af14c78f705abaa7474633a7c6306b2673a97aae35b6a3bf6a5fdd9a6b8d17bd6bbfa1872902818100f2bdbf99a43a4064ac5c85ccff42cccf14fa35250a8d77db6746478d0aea456377dc304688a55b1d2b14c46189ff4f92b078902ff66d144116038667cbbf5bfe80a775aa6eb9885686193debf030eaba00a8cbf26a4fdce1cb433a3a0ccd9696d64448141b0c5d9dfb32bdc29a271594d8e2bc0639daeec705b2cc12419876b702818100ecc964d844657b98dc6b3c6df58a4b5adff0cf5ac1a68679de2baccb4cda1b767f879e441769e5cc0065d8e573f9d728bbd4e25553ee8a2ba779eb219ad0a108daea34e7054d1767e644bdb63880234ac8143a9dda28d3f9196508088e2722ab86a3aa10e599b3caf226e69bee90a1ae7f289b945a34a4fed5e34f9d216b284d028180150ba27afda4174523347a5d459c5309793620396feac8037bb6ba295e52e565345520d25cb2896dc3f86ef64df296c18f0f44e103aa7d610f398b03a0c49c833a404a91563c3bb7d4b4878bd72d468c8dd614a895d30ac180cff952631dc7fa97e51fa2ae9da9d83299399e8fa2e7da19dbbe95839a99ad23af56c6166dd38d02818005da6497c3f90e391519c180a65528cfb2416d9ebcb2b5184619a647d03a83fb45e3c051c692638fcb62b91dd2e4162177a327851c720510572f7854785337e7d4217df547f843dfd99d516333ba5724fe1521edccfabd62a6f20c64c9bec5e89f876428cec421e19e62bfc892f918460bf6a101e5c8ef5b2d46552d792a00f102818100b7d0e59415405a3ce9503e95078078518d381f4273106d67863cfee642d2b82186d9932b7cd921bf1867257473ccd2058d9c88a223701701aa8370b90878df96a6950e3b3ed52326a5cabbf376c97aa644c50fafe38f7496fb9e69efdd138b3525d8b7ac162bd75fe84cb4ce7066d6b786e80c42d5e63059ae939c7bcfa497ed00
+Serialized key bytes: 5c4b0403028010030100010809c109308204bd020100300d06092a864886f70d0101010500048204a7308204a30201000282010100e085e33c42d3f3d63434e0bf1b812c444e790ff6c0becf2cc9de895afa601457bd0fafa81e2b977ab818d086d018491d7ff45be40e916c4c81b3d055ac1803b514e1010b983ff072b77fa228dd47024e65a3c72ab4e2ed02901ba43351dcd87beef92036983c42495d9efec5b4ea1113848b53287099cff1ba58a7829af733f19269101da8c10aa1d5d6b34d381dbb0704e58904c3504a1922f6956e95596780a5db08fe944ff3056ec070eafa66f8c1c5d7dcde4ce2c2694f240aec528eb699089e29f669fb3405c47d6309a609936e8b64e003b5f40743be6b7c2d5673e305cc4e2d154b2a046fba889b60913271b00d5321fd15f82cc41b2894ffc2e54d0b0203010001028201007ae930b59b8bf66f6c130a79f42fa9b117187521caf069f005eeda58c0b9fa48f1c9f58a5e41d4e22c880117dc317f4d33efeca2134b8ef2ef0a25e1d09d30e25fb4b162cc8d2c2f50bf0161c78908fd2bed15aa0e6e2ffb78327998529748b7c7e1ffbd8367718e423f390fb8736eb7b596a4067e65e58d5a4b1020927f03a293d5d3b32931d2a06542e9bbeab7e90085afc9fe145d1c28f44a97f8d9eb8c41913ed9f40261ac5f86806254e26aa8502b92779794a7b08ea299865cbdfeab4dd16307169902b46dbe132b035f7e2742f779f5b39a0b40099434a8af14c78f705abaa7474633a7c6306b2673a97aae35b6a3bf6a5fdd9a6b8d17bd6bbfa1872902818100f2bdbf99a43a4064ac5c85ccff42cccf14fa35250a8d77db6746478d0aea456377dc304688a55b1d2b14c46189ff4f92b078902ff66d144116038667cbbf5bfe80a775aa6eb9885686193debf030eaba00a8cbf26a4fdce1cb433a3a0ccd9696d64448141b0c5d9dfb32bdc29a271594d8e2bc0639daeec705b2cc12419876b702818100ecc964d844657b98dc6b3c6df58a4b5adff0cf5ac1a68679de2baccb4cda1b767f879e441769e5cc0065d8e573f9d728bbd4e25553ee8a2ba779eb219ad0a108daea34e7054d1767e644bdb63880234ac8143a9dda28d3f9196508088e2722ab86a3aa10e599b3caf226e69bee90a1ae7f289b945a34a4fed5e34f9d216b284d028180150ba27afda4174523347a5d459c5309793620396feac8037bb6ba295e52e565345520d25cb2896dc3f86ef64df296c18f0f44e103aa7d610f398b03a0c49c833a404a91563c3bb7d4b4878bd72d468c8dd614a895d30ac180cff952631dc7fa97e51fa2ae9da9d83299399e8fa2e7da19dbbe95839a99ad23af56c6166dd38d02818005da6497c3f90e391519c180a65528cfb2416d9ebcb2b5184619a647d03a83fb45e3c051c692638fcb62b91dd2e4162177a327851c720510572f7854785337e7d4217df547f843dfd99d516333ba5724fe1521edccfabd62a6f20c64c9bec5e89f876428cec421e19e62bfc892f918460bf6a101e5c8ef5b2d46552d792a00f102818100b7d0e59415405a3ce9503e95078078518d381f4273106d67863cfee642d2b82186d9932b7cd921bf1867257473ccd2058d9c88a223701701aa8370b90878df96a6950e3b3ed52326a5cabbf376c97aa644c50fafe38f7496fb9e69efdd138b3525d8b7ac162bd75fe84cb4ce7066d6b786e80c42d5e63059ae939c7bcfa497ed
 PASS: Cloned key exported data should be [308204bd020100300d06092a864886f70d0101010500048204a7308204a30201000282010100e085e33c42d3f3d63434e0bf1b812c444e790ff6c0becf2cc9de895afa601457bd0fafa81e2b977ab818d086d018491d7ff45be40e916c4c81b3d055ac1803b514e1010b983ff072b77fa228dd47024e65a3c72ab4e2ed02901ba43351dcd87beef92036983c42495d9efec5b4ea1113848b53287099cff1ba58a7829af733f19269101da8c10aa1d5d6b34d381dbb0704e58904c3504a1922f6956e95596780a5db08fe944ff3056ec070eafa66f8c1c5d7dcde4ce2c2694f240aec528eb699089e29f669fb3405c47d6309a609936e8b64e003b5f40743be6b7c2d5673e305cc4e2d154b2a046fba889b60913271b00d5321fd15f82cc41b2894ffc2e54d0b0203010001028201007ae930b59b8bf66f6c130a79f42fa9b117187521caf069f005eeda58c0b9fa48f1c9f58a5e41d4e22c880117dc317f4d33efeca2134b8ef2ef0a25e1d09d30e25fb4b162cc8d2c2f50bf0161c78908fd2bed15aa0e6e2ffb78327998529748b7c7e1ffbd8367718e423f390fb8736eb7b596a4067e65e58d5a4b1020927f03a293d5d3b32931d2a06542e9bbeab7e90085afc9fe145d1c28f44a97f8d9eb8c41913ed9f40261ac5f86806254e26aa8502b92779794a7b08ea299865cbdfeab4dd16307169902b46dbe132b035f7e2742f779f5b39a0b40099434a8af14c78f705abaa7474633a7c6306b2673a97aae35b6a3bf6a5fdd9a6b8d17bd6bbfa1872902818100f2bdbf99a43a4064ac5c85ccff42cccf14fa35250a8d77db6746478d0aea456377dc304688a55b1d2b14c46189ff4f92b078902ff66d144116038667cbbf5bfe80a775aa6eb9885686193debf030eaba00a8cbf26a4fdce1cb433a3a0ccd9696d64448141b0c5d9dfb32bdc29a271594d8e2bc0639daeec705b2cc12419876b702818100ecc964d844657b98dc6b3c6df58a4b5adff0cf5ac1a68679de2baccb4cda1b767f879e441769e5cc0065d8e573f9d728bbd4e25553ee8a2ba779eb219ad0a108daea34e7054d1767e644bdb63880234ac8143a9dda28d3f9196508088e2722ab86a3aa10e599b3caf226e69bee90a1ae7f289b945a34a4fed5e34f9d216b284d028180150ba27afda4174523347a5d459c5309793620396feac8037bb6ba295e52e565345520d25cb2896dc3f86ef64df296c18f0f44e103aa7d610f398b03a0c49c833a404a91563c3bb7d4b4878bd72d468c8dd614a895d30ac180cff952631dc7fa97e51fa2ae9da9d83299399e8fa2e7da19dbbe95839a99ad23af56c6166dd38d02818005da6497c3f90e391519c180a65528cfb2416d9ebcb2b5184619a647d03a83fb45e3c051c692638fcb62b91dd2e4162177a327851c720510572f7854785337e7d4217df547f843dfd99d516333ba5724fe1521edccfabd62a6f20c64c9bec5e89f876428cec421e19e62bfc892f918460bf6a101e5c8ef5b2d46552d792a00f102818100b7d0e59415405a3ce9503e95078078518d381f4273106d67863cfee642d2b82186d9932b7cd921bf1867257473ccd2058d9c88a223701701aa8370b90878df96a6950e3b3ed52326a5cabbf376c97aa644c50fafe38f7496fb9e69efdd138b3525d8b7ac162bd75fe84cb4ce7066d6b786e80c42d5e63059ae939c7bcfa497ed] and was
 
 PASS importedKey.extraProperty is "hi"
@@ -754,7 +754,7 @@
 PASS: clonedKey.algorithm.publicExponent should be [010001] and was
 PASS clonedKey.algorithm.hash.name is "SHA-512"
 PASS clonedKey.usages.join(',') is "sign"
-Serialized key bytes: 4b0403028008030100010808f90430820275020100300d06092a864886f70d01010105000482025f3082025b02010002818100a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137020301000102818033a5042a90b27d4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e894a724ac3c568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9ae55fee896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c31b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b325024100e7e8942720a877517273a356053ea2a1bc0c94aa72d55c6e86296b2dfc967948c0a72cbccca7eacb35706e09a1df55a1535bd9b3cc34160b3b6dcd3eda8e6443024100b69dca1cf7d4d7ec81e75b90fcca874abcde123fd2700180aa90479b6e48de8d67ed24f9f19d85ba275874f542cd20dc723e6963364a1f9425452b269a6799fd024028fa13938655be1f8a159cbaca5a72ea190c30089e19cd274a556f36c4f6e19f554b34c077790427bbdd8dd3ede2448328f385d81b30e8e43b2fffa02786197902401a8b38f398fa712049898d7fb79ee0a77668791299cdfa09efc0e507acb21ed74301ef5bfd48be455eaeb6e1678255827580a8e4e8e14151d1510a82a3f2e729024027156aba4126d24a81f3a528cbfb27f56886f840a9f6e86e17a44b94fe9319584b8e22fdde1e5a2e3bd8aa5ba8d8584194eb2190acf832b847f13a3d24a79f4d00
+Serialized key bytes: 5c4b0403028008030100010808f90430820275020100300d06092a864886f70d01010105000482025f3082025b02010002818100a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137020301000102818033a5042a90b27d4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e894a724ac3c568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9ae55fee896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c31b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b325024100e7e8942720a877517273a356053ea2a1bc0c94aa72d55c6e86296b2dfc967948c0a72cbccca7eacb35706e09a1df55a1535bd9b3cc34160b3b6dcd3eda8e6443024100b69dca1cf7d4d7ec81e75b90fcca874abcde123fd2700180aa90479b6e48de8d67ed24f9f19d85ba275874f542cd20dc723e6963364a1f9425452b269a6799fd024028fa13938655be1f8a159cbaca5a72ea190c30089e19cd274a556f36c4f6e19f554b34c077790427bbdd8dd3ede2448328f385d81b30e8e43b2fffa02786197902401a8b38f398fa712049898d7fb79ee0a77668791299cdfa09efc0e507acb21ed74301ef5bfd48be455eaeb6e1678255827580a8e4e8e14151d1510a82a3f2e729024027156aba4126d24a81f3a528cbfb27f56886f840a9f6e86e17a44b94fe9319584b8e22fdde1e5a2e3bd8aa5ba8d8584194eb2190acf832b847f13a3d24a79f4d
 
 PASS importedKey.extraProperty is "hi"
 PASS importedKey.type is "private"
@@ -775,7 +775,7 @@
 PASS: clonedKey.algorithm.publicExponent should be [010001] and was
 PASS clonedKey.algorithm.hash.name is "SHA-512"
 PASS clonedKey.usages.join(',') is "sign"
-Serialized key bytes: 4b0403028010030100010808c109308204bd020100300d06092a864886f70d0101010500048204a7308204a30201000282010100e085e33c42d3f3d63434e0bf1b812c444e790ff6c0becf2cc9de895afa601457bd0fafa81e2b977ab818d086d018491d7ff45be40e916c4c81b3d055ac1803b514e1010b983ff072b77fa228dd47024e65a3c72ab4e2ed02901ba43351dcd87beef92036983c42495d9efec5b4ea1113848b53287099cff1ba58a7829af733f19269101da8c10aa1d5d6b34d381dbb0704e58904c3504a1922f6956e95596780a5db08fe944ff3056ec070eafa66f8c1c5d7dcde4ce2c2694f240aec528eb699089e29f669fb3405c47d6309a609936e8b64e003b5f40743be6b7c2d5673e305cc4e2d154b2a046fba889b60913271b00d5321fd15f82cc41b2894ffc2e54d0b0203010001028201007ae930b59b8bf66f6c130a79f42fa9b117187521caf069f005eeda58c0b9fa48f1c9f58a5e41d4e22c880117dc317f4d33efeca2134b8ef2ef0a25e1d09d30e25fb4b162cc8d2c2f50bf0161c78908fd2bed15aa0e6e2ffb78327998529748b7c7e1ffbd8367718e423f390fb8736eb7b596a4067e65e58d5a4b1020927f03a293d5d3b32931d2a06542e9bbeab7e90085afc9fe145d1c28f44a97f8d9eb8c41913ed9f40261ac5f86806254e26aa8502b92779794a7b08ea299865cbdfeab4dd16307169902b46dbe132b035f7e2742f779f5b39a0b40099434a8af14c78f705abaa7474633a7c6306b2673a97aae35b6a3bf6a5fdd9a6b8d17bd6bbfa1872902818100f2bdbf99a43a4064ac5c85ccff42cccf14fa35250a8d77db6746478d0aea456377dc304688a55b1d2b14c46189ff4f92b078902ff66d144116038667cbbf5bfe80a775aa6eb9885686193debf030eaba00a8cbf26a4fdce1cb433a3a0ccd9696d64448141b0c5d9dfb32bdc29a271594d8e2bc0639daeec705b2cc12419876b702818100ecc964d844657b98dc6b3c6df58a4b5adff0cf5ac1a68679de2baccb4cda1b767f879e441769e5cc0065d8e573f9d728bbd4e25553ee8a2ba779eb219ad0a108daea34e7054d1767e644bdb63880234ac8143a9dda28d3f9196508088e2722ab86a3aa10e599b3caf226e69bee90a1ae7f289b945a34a4fed5e34f9d216b284d028180150ba27afda4174523347a5d459c5309793620396feac8037bb6ba295e52e565345520d25cb2896dc3f86ef64df296c18f0f44e103aa7d610f398b03a0c49c833a404a91563c3bb7d4b4878bd72d468c8dd614a895d30ac180cff952631dc7fa97e51fa2ae9da9d83299399e8fa2e7da19dbbe95839a99ad23af56c6166dd38d02818005da6497c3f90e391519c180a65528cfb2416d9ebcb2b5184619a647d03a83fb45e3c051c692638fcb62b91dd2e4162177a327851c720510572f7854785337e7d4217df547f843dfd99d516333ba5724fe1521edccfabd62a6f20c64c9bec5e89f876428cec421e19e62bfc892f918460bf6a101e5c8ef5b2d46552d792a00f102818100b7d0e59415405a3ce9503e95078078518d381f4273106d67863cfee642d2b82186d9932b7cd921bf1867257473ccd2058d9c88a223701701aa8370b90878df96a6950e3b3ed52326a5cabbf376c97aa644c50fafe38f7496fb9e69efdd138b3525d8b7ac162bd75fe84cb4ce7066d6b786e80c42d5e63059ae939c7bcfa497ed00
+Serialized key bytes: 5c4b0403028010030100010808c109308204bd020100300d06092a864886f70d0101010500048204a7308204a30201000282010100e085e33c42d3f3d63434e0bf1b812c444e790ff6c0becf2cc9de895afa601457bd0fafa81e2b977ab818d086d018491d7ff45be40e916c4c81b3d055ac1803b514e1010b983ff072b77fa228dd47024e65a3c72ab4e2ed02901ba43351dcd87beef92036983c42495d9efec5b4ea1113848b53287099cff1ba58a7829af733f19269101da8c10aa1d5d6b34d381dbb0704e58904c3504a1922f6956e95596780a5db08fe944ff3056ec070eafa66f8c1c5d7dcde4ce2c2694f240aec528eb699089e29f669fb3405c47d6309a609936e8b64e003b5f40743be6b7c2d5673e305cc4e2d154b2a046fba889b60913271b00d5321fd15f82cc41b2894ffc2e54d0b0203010001028201007ae930b59b8bf66f6c130a79f42fa9b117187521caf069f005eeda58c0b9fa48f1c9f58a5e41d4e22c880117dc317f4d33efeca2134b8ef2ef0a25e1d09d30e25fb4b162cc8d2c2f50bf0161c78908fd2bed15aa0e6e2ffb78327998529748b7c7e1ffbd8367718e423f390fb8736eb7b596a4067e65e58d5a4b1020927f03a293d5d3b32931d2a06542e9bbeab7e90085afc9fe145d1c28f44a97f8d9eb8c41913ed9f40261ac5f86806254e26aa8502b92779794a7b08ea299865cbdfeab4dd16307169902b46dbe132b035f7e2742f779f5b39a0b40099434a8af14c78f705abaa7474633a7c6306b2673a97aae35b6a3bf6a5fdd9a6b8d17bd6bbfa1872902818100f2bdbf99a43a4064ac5c85ccff42cccf14fa35250a8d77db6746478d0aea456377dc304688a55b1d2b14c46189ff4f92b078902ff66d144116038667cbbf5bfe80a775aa6eb9885686193debf030eaba00a8cbf26a4fdce1cb433a3a0ccd9696d64448141b0c5d9dfb32bdc29a271594d8e2bc0639daeec705b2cc12419876b702818100ecc964d844657b98dc6b3c6df58a4b5adff0cf5ac1a68679de2baccb4cda1b767f879e441769e5cc0065d8e573f9d728bbd4e25553ee8a2ba779eb219ad0a108daea34e7054d1767e644bdb63880234ac8143a9dda28d3f9196508088e2722ab86a3aa10e599b3caf226e69bee90a1ae7f289b945a34a4fed5e34f9d216b284d028180150ba27afda4174523347a5d459c5309793620396feac8037bb6ba295e52e565345520d25cb2896dc3f86ef64df296c18f0f44e103aa7d610f398b03a0c49c833a404a91563c3bb7d4b4878bd72d468c8dd614a895d30ac180cff952631dc7fa97e51fa2ae9da9d83299399e8fa2e7da19dbbe95839a99ad23af56c6166dd38d02818005da6497c3f90e391519c180a65528cfb2416d9ebcb2b5184619a647d03a83fb45e3c051c692638fcb62b91dd2e4162177a327851c720510572f7854785337e7d4217df547f843dfd99d516333ba5724fe1521edccfabd62a6f20c64c9bec5e89f876428cec421e19e62bfc892f918460bf6a101e5c8ef5b2d46552d792a00f102818100b7d0e59415405a3ce9503e95078078518d381f4273106d67863cfee642d2b82186d9932b7cd921bf1867257473ccd2058d9c88a223701701aa8370b90878df96a6950e3b3ed52326a5cabbf376c97aa644c50fafe38f7496fb9e69efdd138b3525d8b7ac162bd75fe84cb4ce7066d6b786e80c42d5e63059ae939c7bcfa497ed
 
 PASS successfullyParsed is true
 
diff --git a/third_party/WebKit/LayoutTests/css3/blending/background-blend-mode-data-uri-svg-image-expected.png b/third_party/WebKit/LayoutTests/css3/blending/background-blend-mode-data-uri-svg-image-expected.png
index d41d9808..dd9a170 100644
--- a/third_party/WebKit/LayoutTests/css3/blending/background-blend-mode-data-uri-svg-image-expected.png
+++ b/third_party/WebKit/LayoutTests/css3/blending/background-blend-mode-data-uri-svg-image-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/css3/flexbox/flexitem-expected.txt b/third_party/WebKit/LayoutTests/css3/flexbox/flexitem-expected.txt
deleted file mode 100644
index 3d3db47..0000000
--- a/third_party/WebKit/LayoutTests/css3/flexbox/flexitem-expected.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-This is a testharness.js-based test.
-PASS .flexbox 1 
-PASS .flexbox 2 
-PASS .flexbox 3 
-PASS .flexbox 4 
-PASS .flexbox 5 
-PASS .flexbox 6 
-PASS .flexbox 7 
-PASS .flexbox 8 
-PASS .flexbox 9 
-PASS .flexbox 10 
-PASS .flexbox 11 
-FAIL .flexbox 12 assert_equals: 
-<div class="flexbox">
-  <!-- FIXME: This table should flex. -->
-  <div data-expected-display="table" data-expected-width="600" style="display: inline-table"></div>
-</div>
-width expected 600 but got 0
-PASS .flexbox 13 
-PASS .flexbox 14 
-PASS .flexbox 15 
-PASS .flexbox 16 
-PASS .flexbox 17 
-PASS .flexbox 18 
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/editing/deleting/password-delete-contents-expected.txt b/third_party/WebKit/LayoutTests/editing/deleting/password-delete-contents-expected.txt
deleted file mode 100644
index 76926963..0000000
--- a/third_party/WebKit/LayoutTests/editing/deleting/password-delete-contents-expected.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-This makes sure we are able to delete the contents of a password field: deleting a selection and evaluating the field contents.
-
-PASS passwordField.value='helllo'; passwordField.setSelectionRange(3, 4); testRunner.execCommand('Delete', false, null); passwordField.value is 'hello'
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/WebKit/LayoutTests/editing/deleting/password-delete-contents.html b/third_party/WebKit/LayoutTests/editing/deleting/password-delete-contents.html
deleted file mode 100644
index 3e4461b..0000000
--- a/third_party/WebKit/LayoutTests/editing/deleting/password-delete-contents.html
+++ /dev/null
@@ -1,32 +0,0 @@
-<!DOCTYPE>
-<html>
-<head>
-<script src="../../resources/js-test.js"></script>
-</head>
-<body>
-<p id="description">This makes sure we are able to delete the contents of a password field: deleting a selection and evaluating the field contents.</p>
-<div id="console"></div>
-<input type="password" id="passwordField">
-<script>
-
-if (!window.testRunner || !window.internals)
-    testFailed('This test requires access to window.internals');
-
-var textField;
-var desiredString = "hello";
-function runTest(element) {
-    textField = element;
-
-    textField.value = "helllo";
-    textField.focus();
-
-    shouldBe("passwordField.value='helllo'; passwordField.setSelectionRange(3, 4); testRunner.execCommand('Delete', false, null); passwordField.value", "'hello'");
-
-    textField.parentNode.removeChild(textField);
-}
-
-runTest(document.getElementById('passwordField'));
-
-</script>
-</body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/dom/self-origin.sub-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/html/dom/self-origin.sub-expected.txt
deleted file mode 100644
index 27256cf..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/html/dom/self-origin.sub-expected.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-This is a testharness.js-based test.
-PASS Assigning blob url 
-PASS Should have the right origin for cross-origin subframe 
-PASS Should have the right origin for cross-origin subframe after setting document.domain 
-PASS Should have the right origin for IDN subframe 
-PASS Should have the right origin for IDN subframe after setting document.domain 
-PASS Should have the right origin for sandboxed iframe 
-FAIL We should have the right origin for our page assert_equals: expected (string) "http://web-platform.test:8001" but got (undefined) undefined
-FAIL about:blank subframe origins assert_equals: Should have the right origin for about:blank iframe expected (string) "http://web-platform.test:8001" but got (undefined) undefined
-FAIL blob: subframe origins assert_equals: Should have the right origin for blob: iframe expected (string) "http://web-platform.test:8001" but got (undefined) undefined
-FAIL javascript: subframe origins assert_equals: Should have the right origin for javascript: iframe expected (string) "http://web-platform.test:8001" but got (undefined) undefined
-FAIL srcdoc subframe origins assert_equals: Should have the right origin for srcdoc iframe expected (string) "http://web-platform.test:8001" but got (undefined) undefined
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/webappapis/the-windoworworkerglobalscope-mixin/Worker_Self_Origin.html b/third_party/WebKit/LayoutTests/external/wpt/html/webappapis/the-windoworworkerglobalscope-mixin/Worker_Self_Origin.html
new file mode 100644
index 0000000..22b28b3e3
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/webappapis/the-windoworworkerglobalscope-mixin/Worker_Self_Origin.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Test workers self.origin</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+function assertOriginWorker(workerSource, expectedOrigin, testName) {
+  async_test(function(t) {
+    w = new Worker(workerSource);
+    w.onmessage = t.step_func(function(e) {
+      assert_equals(e.data, expectedOrigin);
+      t.done();
+    });
+  }, testName + ' Worker');
+}
+
+function assertOriginSharedWorker(workerSource, expectedOrigin, testName) {
+  async_test(function(t) {
+    w = new SharedWorker(workerSource);
+    w.port.start();
+    w.port.onmessage = t.step_func(function(e) {
+      assert_equals(e.data, expectedOrigin);
+      t.done();
+    });
+  }, testName + ' SharedWorker');
+}
+
+// Test same-origin workers
+assertOriginWorker("./support/WorkerSelfOriginWorker.js", self.origin, "Same Origin");
+assertOriginSharedWorker("./support/WorkerSelfOriginSharedWorker.js", self.origin, "Same Origin");
+
+// Test data url workers have opaque origin
+assertOriginWorker("data:application/javascript,postMessage(self.origin);", "null", "Data Url");
+assertOriginSharedWorker("data:application/javascript,onconnect = function(e) { e.ports[0].postMessage(self.origin); }", "null", "Data Url");
+
+// Test blob url workers
+blob = new Blob(["postMessage(self.origin);"]);
+blobUrl = URL.createObjectURL(blob);
+assertOriginWorker(blobUrl, self.origin, "Blob Url");
+
+blob = new Blob(["onconnect = function(e) { e.ports[0].postMessage(self.origin); }"]);
+blobUrl = URL.createObjectURL(blob);
+assertOriginSharedWorker(blobUrl, self.origin, "Blob Url");
+</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/webappapis/the-windoworworkerglobalscope-mixin/support/WorkerSelfOriginSharedWorker.js b/third_party/WebKit/LayoutTests/external/wpt/html/webappapis/the-windoworworkerglobalscope-mixin/support/WorkerSelfOriginSharedWorker.js
new file mode 100644
index 0000000..3acc5710
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/webappapis/the-windoworworkerglobalscope-mixin/support/WorkerSelfOriginSharedWorker.js
@@ -0,0 +1,5 @@
+// Post back the location of the worker
+
+onconnect = function(e) {
+  e.ports[0].postMessage(self.origin);
+}
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/webappapis/the-windoworworkerglobalscope-mixin/support/WorkerSelfOriginWorker.js b/third_party/WebKit/LayoutTests/external/wpt/html/webappapis/the-windoworworkerglobalscope-mixin/support/WorkerSelfOriginWorker.js
new file mode 100644
index 0000000..1a69b55
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/webappapis/the-windoworworkerglobalscope-mixin/support/WorkerSelfOriginWorker.js
@@ -0,0 +1,4 @@
+// Post back the location of the worker
+
+postMessage(self.origin);
+
diff --git a/third_party/WebKit/LayoutTests/external/wpt/media/CanvasTest.ttf b/third_party/WebKit/LayoutTests/external/wpt/media/CanvasTest.ttf
new file mode 100644
index 0000000..9023592
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/media/CanvasTest.ttf
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/external/wpt/preload/download-resources.html b/third_party/WebKit/LayoutTests/external/wpt/preload/download-resources.html
index 390487a..c1c72f1a 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/preload/download-resources.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/preload/download-resources.html
@@ -8,7 +8,7 @@
 <link rel=preload href="resources/dummy.js" as=script>
 <link rel=preload href="resources/dummy.css" as=style>
 <link rel=preload href="resources/square.png" as=image>
-<link rel=preload href="/fonts/CanvasTest.ttf" as=font crossorigin>
+<link rel=preload href="/media/CanvasTest.ttf" as=font crossorigin>
 <link rel=preload href="/media/white.mp4" as=media>
 <link rel=preload href="/media/sound_5.oga" as=media>
 <link rel=preload href="/media/foo.vtt" as=media>
@@ -21,7 +21,7 @@
         verifyPreloadAndRTSupport()
         verifyNumberOfDownloads("resources/dummy.js", 1);
         verifyNumberOfDownloads("resources/dummy.css", 1);
-        verifyNumberOfDownloads("/fonts/CanvasTest.ttf", 1);
+        verifyNumberOfDownloads("/media/CanvasTest.ttf", 1);
         verifyNumberOfDownloads("/media/white.mp4", 1);
         verifyNumberOfDownloads("/media/sound_5.oga", 1);
         verifyNumberOfDownloads("/media/foo.vtt", 1);
diff --git a/third_party/WebKit/LayoutTests/external/wpt/preload/onload-event.html b/third_party/WebKit/LayoutTests/external/wpt/preload/onload-event.html
index 5a1a6010..3d4ac368 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/preload/onload-event.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/preload/onload-event.html
@@ -18,7 +18,7 @@
 <link rel=preload href="resources/dummy.js" as=script onload="scriptLoaded = true;">
 <link rel=preload href="resources/dummy.css" as=style onload="styleLoaded = true;">
 <link rel=preload href="resources/square.png" as=image onload="imageLoaded = true;">
-<link rel=preload href="/fonts/CanvasTest.ttf" as=font crossorigin onload="fontLoaded = true;">
+<link rel=preload href="/media/CanvasTest.ttf" as=font crossorigin onload="fontLoaded = true;">
 <link rel=preload href="/media/white.mp4" as=media onload="videoLoaded = true;">
 <link rel=preload href="/media/sound_5.oga" as=media onload="audioLoaded = true;">
 <link rel=preload href="/media/foo.vtt" as=media onload="trackLoaded = true;">
diff --git a/third_party/WebKit/LayoutTests/external/wpt/preload/preload-with-type.html b/third_party/WebKit/LayoutTests/external/wpt/preload/preload-with-type.html
index 5bce1da..cfe6408 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/preload/preload-with-type.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/preload/preload-with-type.html
@@ -31,7 +31,7 @@
 <link rel=preload href="resources/dummy.js" as=script type="text/javascript" onload="scriptLoaded = true;">
 <link rel=preload href="resources/dummy.css" as=style type="text/css" onload="styleLoaded = true;">
 <link rel=preload href="resources/square.png" as=image type="image/png" onload="imageLoaded = true;">
-<link rel=preload href="/fonts/CanvasTest.ttf" as=font type="font/ttf" crossorigin onload="fontLoaded = true;">
+<link rel=preload href="/media/CanvasTest.ttf" as=font type="font/ttf" crossorigin onload="fontLoaded = true;">
 <script>
     document.write('<link rel=preload href="' + videoURL + '" as=media type="video/' + videoFormat + '" onload="videoLoaded = true;">');
     document.write('<link rel=preload href="' + audioURL + '" as=media type="audio/' + audioFormat + '" onload="audioLoaded = true;">');
@@ -40,7 +40,7 @@
 <link rel=preload href="resources/dummy.js" as=script type="application/foobar" onload="gibberishLoaded++;">
 <link rel=preload href="resources/dummy.css" as=style type="text/foobar" onload="gibberishLoaded++;">
 <link rel=preload href="resources/square.png" as=image type="image/foobar" onload="gibberishLoaded++;">
-<link rel=preload href="/fonts/CanvasTest.ttf" as=font type="font/foobar" crossorigin onload="gibberishLoaded++;">
+<link rel=preload href="/media/CanvasTest.ttf" as=font type="font/foobar" crossorigin onload="gibberishLoaded++;">
 <script>
     document.write('<link rel=preload href="' + videoURL + '" as=media type="video/foobar" onload="gibberishLoaded++;">');
     document.write('<link rel=preload href="' + audioURL + '" as=media type="audio/foobar" onload="gibberishLoaded++;">');
diff --git a/third_party/WebKit/LayoutTests/external/wpt/preload/single-download-preload.html b/third_party/WebKit/LayoutTests/external/wpt/preload/single-download-preload.html
index c06e3e57..4535947 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/preload/single-download-preload.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/preload/single-download-preload.html
@@ -9,14 +9,14 @@
 <link rel=preload href="resources/dummy.css" as=style>
 <link rel=preload href="resources/square.png" as=image>
 <link rel=preload href="resources/square.png?background" as=image>
-<link rel=preload href="/fonts/CanvasTest.ttf" as=font crossorigin>
+<link rel=preload href="/media/CanvasTest.ttf" as=font crossorigin>
 <link rel=preload href="/media/white.mp4" as=media>
 <link rel=preload href="/media/sound_5.oga" as=media>
 <link rel=preload href="/media/foo.vtt" as=media>
 <link rel=preload href="resources/dummy.xml?foo=bar" as=foobarxmlthing>
 <link rel=preload href="resources/dummy.xml">
 <body>
-<script src="resources/dummy.js?pipe=trickle(d5)"></script>
+<script src="resources/dummy.js?pipe=trickle(d3)"></script>
 <style>
     #background {
         width: 200px;
@@ -25,7 +25,7 @@
     }
     @font-face {
       font-family:ahem;
-      src: url(/fonts/CanvasTest.ttf);
+      src: url(/media/CanvasTest.ttf);
     }
     span { font-family: ahem, Arial; }
 </style>
@@ -49,7 +49,7 @@
             verifyNumberOfDownloads("resources/dummy.css", 1);
             verifyNumberOfDownloads("resources/square.png", 1);
             verifyNumberOfDownloads("resources/square.png?background", 1);
-            verifyNumberOfDownloads("/fonts/CanvasTest.ttf", 1);
+            verifyNumberOfDownloads("/media/CanvasTest.ttf", 1);
             verifyNumberOfDownloads("resources/dummy.xml?foobar", 0);
             verifyNumberOfDownloads("/media/foo.vtt", 1);
             verifyNumberOfDownloads("resources/dummy.xml", 1);
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/floating-point-total-queue-size-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/floating-point-total-queue-size-expected.txt
new file mode 100644
index 0000000..41e78c1b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/floating-point-total-queue-size-expected.txt
@@ -0,0 +1,7 @@
+This is a testharness.js-based test.
+FAIL Floating point arithmetic must manifest near NUMBER.MAX_SAFE_INTEGER (total ends up positive) assert_equals: [[queueTotalSize]] must clamp to 0 if it becomes negative expected 0 but got 1
+FAIL Floating point arithmetic must manifest near 0 (total ends up positive, but clamped) assert_equals: [[queueTotalSize]] must clamp to 0 if it becomes negative expected 0 but got 1.1102230246251565e-16
+PASS Floating point arithmetic must manifest near 0 (total ends up positive, and not clamped) 
+PASS Floating point arithmetic must manifest near 0 (total ends up zero) 
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/floating-point-total-queue-size.serviceworker.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/floating-point-total-queue-size.serviceworker.https-expected.txt
new file mode 100644
index 0000000..a2c0250b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/streams/readable-streams/floating-point-total-queue-size.serviceworker.https-expected.txt
@@ -0,0 +1,8 @@
+This is a testharness.js-based test.
+PASS Service worker test setup 
+FAIL Floating point arithmetic must manifest near NUMBER.MAX_SAFE_INTEGER (total ends up positive) assert_equals: [[queueTotalSize]] must clamp to 0 if it becomes negative expected 0 but got 1
+FAIL Floating point arithmetic must manifest near 0 (total ends up positive, but clamped) assert_equals: [[queueTotalSize]] must clamp to 0 if it becomes negative expected 0 but got 1.1102230246251565e-16
+PASS Floating point arithmetic must manifest near 0 (total ends up positive, and not clamped) 
+PASS Floating point arithmetic must manifest near 0 (total ends up zero) 
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/floating-point-total-queue-size-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/floating-point-total-queue-size-expected.txt
new file mode 100644
index 0000000..41e78c1b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/floating-point-total-queue-size-expected.txt
@@ -0,0 +1,7 @@
+This is a testharness.js-based test.
+FAIL Floating point arithmetic must manifest near NUMBER.MAX_SAFE_INTEGER (total ends up positive) assert_equals: [[queueTotalSize]] must clamp to 0 if it becomes negative expected 0 but got 1
+FAIL Floating point arithmetic must manifest near 0 (total ends up positive, but clamped) assert_equals: [[queueTotalSize]] must clamp to 0 if it becomes negative expected 0 but got 1.1102230246251565e-16
+PASS Floating point arithmetic must manifest near 0 (total ends up positive, and not clamped) 
+PASS Floating point arithmetic must manifest near 0 (total ends up zero) 
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/floating-point-total-queue-size.serviceworker.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/floating-point-total-queue-size.serviceworker.https-expected.txt
new file mode 100644
index 0000000..a2c0250b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/streams/writable-streams/floating-point-total-queue-size.serviceworker.https-expected.txt
@@ -0,0 +1,8 @@
+This is a testharness.js-based test.
+PASS Service worker test setup 
+FAIL Floating point arithmetic must manifest near NUMBER.MAX_SAFE_INTEGER (total ends up positive) assert_equals: [[queueTotalSize]] must clamp to 0 if it becomes negative expected 0 but got 1
+FAIL Floating point arithmetic must manifest near 0 (total ends up positive, but clamped) assert_equals: [[queueTotalSize]] must clamp to 0 if it becomes negative expected 0 but got 1.1102230246251565e-16
+PASS Floating point arithmetic must manifest near 0 (total ends up positive, and not clamped) 
+PASS Floating point arithmetic must manifest near 0 (total ends up zero) 
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/fast/alignment/parse-place-content.html b/third_party/WebKit/LayoutTests/fast/alignment/parse-place-content.html
new file mode 100644
index 0000000..36cf4816
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/alignment/parse-place-content.html
@@ -0,0 +1,245 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+#placeContentNormal {
+    place-content: normal;
+}
+#placeContentBaseline {
+    place-content: baseline;
+}
+#placeContentStart {
+    place-content: start;
+}
+#placeContentFlexStart {
+    place-content: flex-start;
+}
+#placeContentEnd {
+    place-content: end;
+}
+#placeContentSpaceBetween {
+    place-content: space-between;
+}
+#placeContentStretch {
+    place-content: stretch;
+}
+#placeContentStartEnd {
+    place-content: start end;
+}
+#placeContentStartSpaceEvenly {
+    place-content: start space-evenly;
+}
+#placeContentStartBaseline {
+    place-content: start baseline;
+}
+
+<!-- Invalid CSS cases -->
+#placeContentEmpty {
+    place-content:;
+}
+#placeContentAuto {
+    place-content: auto;
+}
+#placeContentNone {
+    place-content: none;
+}
+#placeContentSafe {
+    place-content: safe;
+}
+#placeContentStartSafe {
+    place-content: start safe;
+}
+#placeContentStartEndLeft {
+    place-content: start end left;
+}
+</style>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script src="resources/alignment-parsing-utils-th.js"></script>
+</head>
+<body>
+    <p>Test to verify that the new place-content alignment shorthand is parsed as expected and correctly sets the longhand values.</p>
+    <div id="log"></div>
+
+    <div id="placeContentNormal"></div>
+    <div id="placeContentBaseline"></div>
+    <div id="placeContentStart"></div>
+    <div id="placeContentFlexStart"></div>
+    <div id="placeContentEnd"></div>
+    <div id="placeContentSpaceBetween"></div>
+    <div id="placeContentStretch"></div>
+    <div id="placeContentStartEnd"></div>
+    <div id="placeContentStartSpaceEvenly"></div>
+    <div id="placeContentStartBaseline"></div>
+
+    <div id="placeContentEmpty"></div>
+    <div id="placeContentAuto"></div>
+    <div id="placeContentNone"></div>
+    <div id="placeContentSafe"></div>
+    <div id="placeContentStartSafe"></div>
+    <div id="placeContentBaselineSafe"></div>
+    <div id="placeContentStartEndLeft"></div>
+<script>
+function checkPlaceContentValues(element, value, alignValue, justifyValue)
+{
+     var res = value.split(" ");
+     if (res.length < 2)
+         res[1] = res[0];
+     checkValues(element, "alignContent", "align-content", res[0], alignValue);
+     checkValues(element, "justifyContent", "justify-content", res[1], justifyValue);
+}
+
+function checkPlaceContentValuesJS(value, alignValue, justifyValue)
+{
+   element = document.createElement("div");
+   document.body.appendChild(element);
+   element.style.placeContent = value;
+   checkValues(element, "placeContent", "place-content", value, alignValue + ' ' + justifyValue)
+   checkPlaceContentValues(element, value, alignValue, justifyValue)
+}
+
+function checkPlaceContentValuesBadJS(value)
+{
+   element.style.placeContent = "";
+   element.style.placeContent = value;
+   checkPlaceContentValues(element, "", "normal", "normal")
+}
+
+function checkPlaceContentInitialValue()
+{
+   element = document.createElement("div");
+   document.body.appendChild(element);
+   checkValues(element, "placeContent", "place-content", "", "normal normal");
+   element.style.placeContent = "center";
+   checkPlaceContentValues(element, "center", "center", "center");
+   element.style.placeContent = "initial";
+   checkValues(element, "placeContent", "place-content", "initial", "normal normal");
+   checkPlaceContentValues(element, "initial", "normal", "normal");
+}
+
+function checkPlaceContentInheritValue()
+{
+   document.body.style.placeContent = "start";
+   var anotherElement = document.createElement("div");
+   document.body.appendChild(anotherElement);
+   checkPlaceContentValues(anotherElement, "", "normal", "normal");
+   anotherElement.style.placeContent = "inherit";
+   checkPlaceContentValues(anotherElement, "inherit", "start", "start");
+}
+
+
+test(function() {
+    checkValues(placeContentNormal, "placeContent", "place-content", "", "normal normal");
+    checkPlaceContentValues(placeContentNormal, "", "normal", "normal");
+}, "Test getting the Computed Value of place-content's longhand properties when setting 'normal' value through CSS.");
+
+test(function() {
+    checkValues(placeContentBaseline, "placeContent", "place-content", "", "baseline baseline");
+    checkPlaceContentValues(placeContentBaseline, "", "baseline", "baseline");
+}, "Test getting the Computed Value of place-content's longhand properties when setting 'baseline' value through CSS.");
+
+test(function() {
+    checkValues(placeContentStart, "placeContent", "place-content", "", "start start");
+    checkPlaceContentValues(placeContentStart, "", "start", "start");
+}, "Test getting the Computed Value of place-content's longhand properties when setting 'start' value through CSS.");
+
+test(function() {
+    checkValues(placeContentFlexStart, "placeContent", "place-content", "", "flex-start flex-start");
+    checkPlaceContentValues(placeContentFlexStart, "", "flex-start", "flex-start");
+}, "Test getting the Computed Value of place-content's longhand properties when setting 'flex-start' value through CSS.");
+
+test(function() {
+    checkValues(placeContentEnd, "placeContent", "place-content", "", "end end");
+    checkPlaceContentValues(placeContentEnd, "", "end", "end");
+}, "Test getting the Computed Value of place-content's longhand properties when setting 'end' value through CSS.");
+
+test(function() {
+    checkValues(placeContentSpaceBetween, "placeContent", "place-content", "", "space-between space-between");
+    checkPlaceContentValues(placeContentSpaceBetween, "", "space-between", "space-between");
+}, "Test getting the Computed Value of place-content's longhand properties when setting 'space-between' value through CSS.");
+
+test(function() {
+    checkValues(placeContentStretch, "placeContent", "place-content", "", "stretch stretch");
+    checkPlaceContentValues(placeContentStretch, "", "stretch", "stretch");
+}, "Test getting the Computed Value of place-content's longhand properties when setting 'stretch' value through CSS.");
+
+test(function() {
+    checkValues(placeContentStartEnd, "placeContent", "place-content", "", "start end");
+    checkPlaceContentValues(placeContentStartEnd, "", "start", "end");
+}, "Test getting the Computed Value of place-content's longhand properties when setting 'start end' value through CSS.");
+
+test(function() {
+    checkValues(placeContentStartSpaceEvenly, "placeContent", "place-content", "", "start space-evenly");
+    checkPlaceContentValues(placeContentStartSpaceEvenly, "", "start", "space-evenly");
+}, "Test getting the Computed Value of place-content's longhand properties when setting 'start space-evenly' value through CSS.");
+
+test(function() {
+    checkValues(placeContentStartBaseline, "placeContent", "place-content", "", "start baseline");
+    checkPlaceContentValues(placeContentStartBaseline, "", "start", "baseline");
+}, "Test getting the Computed Value of place-content's longhand properties when setting 'start baseline' value through CSS.");
+
+test(function() {
+    checkValues(placeContentAuto, "placeContent", "place-content", "", "normal normal");
+    checkPlaceContentValues(placeContentAuto, "", "normal", "normal");
+}, "Test setting '' as incorrect value through CSS.");
+
+test(function() {
+    checkValues(placeContentAuto, "placeContent", "place-content", "", "normal normal");
+    checkPlaceContentValues(placeContentAuto, "", "normal", "normal");
+}, "Test setting 'auto' as incorrect value through CSS.");
+
+test(function() {
+    checkValues(placeContentNone, "placeContent", "place-content", "", "normal normal");
+    checkPlaceContentValues(placeContentNone, "", "normal", "normal");
+}, "Test setting 'none' as incorrect value through CSS.");
+
+test(function() {
+    checkValues(placeContentSafe, "placeContent", "place-content", "", "normal normal");
+    checkPlaceContentValues(placeContentSafe, "", "normal", "normal");
+}, "Test setting 'safe' as incorrect value through CSS.");
+
+test(function() {
+    checkValues(placeContentStartSafe, "placeContent", "place-content", "", "normal normal");
+    checkPlaceContentValues(placeContentStartSafe, "", "normal", "normal");
+}, "Test setting 'start safe' as incorrect value through CSS.");
+
+test(function() {
+    checkValues(placeContentStartSafe, "placeContent", "place-content", "", "normal normal");
+    checkPlaceContentValues(placeContentStartSafe, "", "normal", "normal");
+}, "Test setting 'baseline safe' as incorrect value through CSS.");
+
+test(function() {
+    checkValues(placeContentStartEndLeft, "placeContent", "place-content", "", "normal normal");
+    checkPlaceContentValues(placeContentStartEndLeft, "", "normal", "normal");
+}, "Test setting 'start end left' as incorrect value through CSS.");
+
+test(function() {
+    checkPlaceContentValuesJS("center", "center", "center");
+    checkPlaceContentValuesJS("center start", "center", "start");
+    checkPlaceContentValuesJS("space-between end", "space-between", "end");
+    checkPlaceContentValuesJS("normal end", "normal", "end");
+}, "Test setting values through JS.");
+
+test(function() {
+    checkPlaceContentValuesBadJS("center safe", "normal", "normal");
+    checkPlaceContentValuesBadJS("center space-between center", "normal", "normal");
+    checkPlaceContentValuesBadJS("asrt", "normal", "normal");
+    checkPlaceContentValuesBadJS("auto", "normal", "normal");
+    checkPlaceContentValuesBadJS("10px", "normal", "normal");
+    checkPlaceContentValuesBadJS("stretch safe", "normal", "normal");
+    checkPlaceContentValuesBadJS("space-between start end", "normal", "normal");
+    checkPlaceContentValuesBadJS("", "normal", "normal");
+}, "Test setting incorrect values through JS.");
+
+test(function() {
+    checkPlaceContentInitialValue();
+}, "Test the 'initial' value of the place-content shorthand and its longhand properties' Computed value");
+
+test(function() {
+    checkPlaceContentInheritValue();
+}, "Test the 'inherit' value of the place-content shorthand and its longhand properties' Computed value");
+
+
+</script>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/fast/alignment/resources/alignment-parsing-utils-th.js b/third_party/WebKit/LayoutTests/fast/alignment/resources/alignment-parsing-utils-th.js
index ee35414d..43d3d57 100644
--- a/third_party/WebKit/LayoutTests/fast/alignment/resources/alignment-parsing-utils-th.js
+++ b/third_party/WebKit/LayoutTests/fast/alignment/resources/alignment-parsing-utils-th.js
@@ -2,7 +2,7 @@
 {
     window.element = element;
     var elementID = element.id || "element";
-    assert_equals(eval("element.style." + property), value, property + " specified value is not what it should..");
+    assert_equals(eval('element.style.' + property), value, property + ' specified value is not what it should..');
     assert_equals(eval("window.getComputedStyle(" + elementID + ", '').getPropertyValue('" + propertyID + "')"), computedValue, property + " is not what is should.");
 }
 
diff --git a/third_party/WebKit/LayoutTests/fast/borders/border-mixed-alpha-expected.png b/third_party/WebKit/LayoutTests/fast/borders/border-mixed-alpha-expected.png
index 554d248e..a099959 100644
--- a/third_party/WebKit/LayoutTests/fast/borders/border-mixed-alpha-expected.png
+++ b/third_party/WebKit/LayoutTests/fast/borders/border-mixed-alpha-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/borders/border-mixed-alpha2-expected.png b/third_party/WebKit/LayoutTests/fast/borders/border-mixed-alpha2-expected.png
index 3c3aae5..aa216192 100644
--- a/third_party/WebKit/LayoutTests/fast/borders/border-mixed-alpha2-expected.png
+++ b/third_party/WebKit/LayoutTests/fast/borders/border-mixed-alpha2-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/borders/borderRadiusDotted01-expected.png b/third_party/WebKit/LayoutTests/fast/borders/borderRadiusDotted01-expected.png
index 04bb653..b5fcef5 100644
--- a/third_party/WebKit/LayoutTests/fast/borders/borderRadiusDotted01-expected.png
+++ b/third_party/WebKit/LayoutTests/fast/borders/borderRadiusDotted01-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/borders/borderRadiusDotted02-expected.png b/third_party/WebKit/LayoutTests/fast/borders/borderRadiusDotted02-expected.png
index 27a6262..94e6ced5 100644
--- a/third_party/WebKit/LayoutTests/fast/borders/borderRadiusDotted02-expected.png
+++ b/third_party/WebKit/LayoutTests/fast/borders/borderRadiusDotted02-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/borders/borderRadiusDotted03-expected.png b/third_party/WebKit/LayoutTests/fast/borders/borderRadiusDotted03-expected.png
index efb5edda..d384b5a 100644
--- a/third_party/WebKit/LayoutTests/fast/borders/borderRadiusDotted03-expected.png
+++ b/third_party/WebKit/LayoutTests/fast/borders/borderRadiusDotted03-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/borders/borderRadiusDotted04-expected.png b/third_party/WebKit/LayoutTests/fast/borders/borderRadiusDotted04-expected.png
index edc0f1c..991543c0 100644
--- a/third_party/WebKit/LayoutTests/fast/borders/borderRadiusDotted04-expected.png
+++ b/third_party/WebKit/LayoutTests/fast/borders/borderRadiusDotted04-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/borders/borderRadiusDotted05-expected.png b/third_party/WebKit/LayoutTests/fast/borders/borderRadiusDotted05-expected.png
index 7b2eb48..df892d3 100644
--- a/third_party/WebKit/LayoutTests/fast/borders/borderRadiusDotted05-expected.png
+++ b/third_party/WebKit/LayoutTests/fast/borders/borderRadiusDotted05-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/borders/borderRadiusDotted06-expected.png b/third_party/WebKit/LayoutTests/fast/borders/borderRadiusDotted06-expected.png
index a40c1f4..29a6b49f 100644
--- a/third_party/WebKit/LayoutTests/fast/borders/borderRadiusDotted06-expected.png
+++ b/third_party/WebKit/LayoutTests/fast/borders/borderRadiusDotted06-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/css/fontfaceset-ready.html b/third_party/WebKit/LayoutTests/fast/css/fontfaceset-ready.html
index c55b7f3..479f677 100644
--- a/third_party/WebKit/LayoutTests/fast/css/fontfaceset-ready.html
+++ b/third_party/WebKit/LayoutTests/fast/css/fontfaceset-ready.html
@@ -2,6 +2,7 @@
 <title>FontFaceSet.ready attribute</title>
 <script src="../../resources/testharness.js"></script>
 <script src="../../resources/testharnessreport.js"></script>
+<div style="font-family: ahem">A</div>
 <script>
 
 promise_test(function(t) {
@@ -36,4 +37,16 @@
         });
 }, 'FontFaceSet.ready attribute');
 
+promise_test(function(t) {
+    var face = new FontFace('ahem', 'url(../../resources/Ahem.ttf)');
+
+    return document.fonts.ready
+        .then(function(fonts) {
+            document.fonts.add(face);
+            return document.fonts.ready;
+        }).then(function(fonts) {
+            assert_equals(face.status, 'loaded');
+        });
+}, 'FontFaceSet.ready should be resolved after layout operations which may cause font loads.');
+
 </script>
diff --git a/third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-style-expected.png b/third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-style-expected.png
index 901c2dd..ebfb8bb1 100644
--- a/third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-style-expected.png
+++ b/third_party/WebKit/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-style-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/dom/HTMLDialogElement-crash-style-recalc-after-dialog-close-expected.html b/third_party/WebKit/LayoutTests/fast/dom/HTMLDialogElement-crash-style-recalc-after-dialog-close-expected.html
new file mode 100644
index 0000000..27e4ca1
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/dom/HTMLDialogElement-crash-style-recalc-after-dialog-close-expected.html
@@ -0,0 +1,2 @@
+<!DOCTYPE html>
+<div>The test passes if it doesn't crash</div>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/HTMLDialogElement-crash-style-recalc-after-dialog-close.html b/third_party/WebKit/LayoutTests/fast/dom/HTMLDialogElement-crash-style-recalc-after-dialog-close.html
new file mode 100644
index 0000000..d76af48
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/dom/HTMLDialogElement-crash-style-recalc-after-dialog-close.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<div>The test passes if it doesn't crash</div>
+<br>
+<dialog id="dialog" style="position: relative">
+<input>
+<script>
+    dialog.show();
+    document.body.offsetTop; // force layout
+    dialog.close();
+</script>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/fast/dom/MutationObserver/observe-gc.html b/third_party/WebKit/LayoutTests/fast/dom/MutationObserver/observe-gc.html
new file mode 100644
index 0000000..ab0b0b4a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/dom/MutationObserver/observe-gc.html
@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<script src="../../../resources/gc.js"></script>
+<script src='../../../resources/testharness.js'></script>
+<script src='../../../resources/testharnessreport.js'></script>
+<script>
+
+// All the following tests make sure that the observer callback is called even
+// if there are no references to the nodes and a garbage collection kicks in
+// before returning to the event loop.
+
+async_test(function(t) {
+
+    (function simple() {
+        var d = document.createElement('div');
+        var c = document.createElement('div');
+        var obs = new MutationObserver(t.step_func_done(function() {}));
+        obs.observe(d, {childList: true});
+        d.appendChild(c);
+    })();
+    gc();
+}, "Tests that pending callbacks retain the nodes even in the presence of garbage collection");
+
+async_test(function(t) {
+    (function addedChildNodes() {
+        var d = document.createElement('div');
+        var c = document.createElement('div');
+        c.expando = "c";
+        var obs = new MutationObserver(t.step_func_done(function(records) {
+            assert_equals(1, records[0].addedNodes.length, "one node added");
+            assert_equals("c", records[0].addedNodes[0].expando, "expando preserved");
+        }));
+        obs.observe(d, {childList: true});
+        d.appendChild(c);
+    })();
+    gc();
+}, "Tests that pending callbacks retain the nodes even in the presence of garbage collection");
+
+async_test(function(t) {
+    (function siblings() {
+        var d = document.createElement('div');
+        var b = document.createElement('b');
+        var i = document.createElement('i');
+        var p = document.createElement('p');
+        d.appendChild(b);
+        d.appendChild(i);
+        d.appendChild(p);
+        b.expando = "hello";
+        p.expando = "goodbye";
+
+        var obs = new MutationObserver(t.step_func_done(function(records) {
+            assert_equals(3, records.length, "number of records");
+            assert_equals("hello", records[0].previousSibling.expando, "expando preserved");
+            assert_equals("goodbye", records[0].nextSibling.expando, "expando preserved");
+        }));
+        obs.observe(d, {childList: true});
+        d = null;
+        i.remove();
+        i = null;
+        b.remove();
+        b = null;
+        p.remove();
+        p = null;
+    })();
+    gc();
+}, "Tests that pending callbacks retain the nodes even in the presence of garbage collection");
+
+</script>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/fast/dom/MutationObserver/weak-callback-gc-crash-expected.txt b/third_party/WebKit/LayoutTests/fast/dom/MutationObserver/weak-callback-gc-crash-expected.txt
index 0d88634..2634613 100644
--- a/third_party/WebKit/LayoutTests/fast/dom/MutationObserver/weak-callback-gc-crash-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/dom/MutationObserver/weak-callback-gc-crash-expected.txt
@@ -1 +1,2 @@
+CONSOLE MESSAGE: line 13: MutationObserver callback
 Test passes if it does not crash
diff --git a/third_party/WebKit/LayoutTests/fast/dom/MutationObserver/weak-callback-gc-crash.html b/third_party/WebKit/LayoutTests/fast/dom/MutationObserver/weak-callback-gc-crash.html
index fb8d2b3..673bbc8 100644
--- a/third_party/WebKit/LayoutTests/fast/dom/MutationObserver/weak-callback-gc-crash.html
+++ b/third_party/WebKit/LayoutTests/fast/dom/MutationObserver/weak-callback-gc-crash.html
@@ -10,7 +10,7 @@
 
 function initializeObserver() {
     observer = new MutationObserver(
-                   function() {console.log('Should not appear')});
+                   function() {console.log('MutationObserver callback')});
     div = document.createElement('div');
     observer.observe(div, {attributes: true});
     div.id = 'foo';
diff --git a/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-properties-after-frame-navigated-expected.txt b/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-properties-after-frame-navigated-expected.txt
index 0daa4a8..dba5987e 100644
--- a/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-properties-after-frame-navigated-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-properties-after-frame-navigated-expected.txt
@@ -1,4 +1,4 @@
-CONSOLE WARNING: line 101: 'window.webkitStorageInfo' is deprecated. Please use 'navigator.webkitTemporaryStorage' or 'navigator.webkitPersistentStorage' instead.
+CONSOLE WARNING: line 104: 'window.webkitStorageInfo' is deprecated. Please use 'navigator.webkitTemporaryStorage' or 'navigator.webkitPersistentStorage' instead.
 Tests access of cached DOMWindow properties after the associated frame is navigated. Test should not crash and properties should be set to sane defaults.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git a/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-and-gced-expected.txt b/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-and-gced-expected.txt
index 03fb6d55..01269ba 100644
--- a/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-and-gced-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-and-gced-expected.txt
@@ -1,4 +1,4 @@
-CONSOLE WARNING: line 101: 'window.webkitStorageInfo' is deprecated. Please use 'navigator.webkitTemporaryStorage' or 'navigator.webkitPersistentStorage' instead.
+CONSOLE WARNING: line 104: 'window.webkitStorageInfo' is deprecated. Please use 'navigator.webkitTemporaryStorage' or 'navigator.webkitPersistentStorage' instead.
 Tests access of cached DOMWindow properties after the associated frame is removed from a web page and garbage collected. Test should not crash and properties should be set to sane defaults.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git a/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-expected.txt b/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-expected.txt
index d7a8ab8..cf6c1de 100644
--- a/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-expected.txt
@@ -1,4 +1,4 @@
-CONSOLE WARNING: line 101: 'window.webkitStorageInfo' is deprecated. Please use 'navigator.webkitTemporaryStorage' or 'navigator.webkitPersistentStorage' instead.
+CONSOLE WARNING: line 104: 'window.webkitStorageInfo' is deprecated. Please use 'navigator.webkitTemporaryStorage' or 'navigator.webkitPersistentStorage' instead.
 Tests access of cached DOMWindow properties after the associated frame is no longer in a web page. Test should not crash and properties should be set to sane defaults.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git a/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-window-after-frame-navigated-expected.txt b/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-window-after-frame-navigated-expected.txt
index da7a2c82..a72f27b 100644
--- a/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-window-after-frame-navigated-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-window-after-frame-navigated-expected.txt
@@ -1,4 +1,4 @@
-CONSOLE WARNING: line 101: 'window.webkitStorageInfo' is deprecated. Please use 'navigator.webkitTemporaryStorage' or 'navigator.webkitPersistentStorage' instead.
+CONSOLE WARNING: line 104: 'window.webkitStorageInfo' is deprecated. Please use 'navigator.webkitTemporaryStorage' or 'navigator.webkitPersistentStorage' instead.
 Tests property access on a cached DOMWindow after the associated frame is navigated. Test should not crash and properties read from the cached DOMWindow should be identical to properties through the 'current' DOMWindow.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
@@ -166,6 +166,7 @@
 PASS oldChildWindow.onwebkittransitionend is newChildWindow.onwebkittransitionend
 PASS oldChildWindow.onwheel is newChildWindow.onwheel
 PASS oldChildWindow.opener is newChildWindow.opener
+PASS oldChildWindow.origin is newChildWindow.origin
 PASS oldChildWindow.outerHeight is newChildWindow.outerHeight
 PASS oldChildWindow.outerWidth is newChildWindow.outerWidth
 PASS oldChildWindow.pageXOffset is newChildWindow.pageXOffset
diff --git a/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-window-after-frame-removed-and-gced-expected.txt b/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-window-after-frame-removed-and-gced-expected.txt
index cdb184ea..02dd68e4 100644
--- a/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-window-after-frame-removed-and-gced-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-window-after-frame-removed-and-gced-expected.txt
@@ -1,4 +1,4 @@
-CONSOLE WARNING: line 101: 'window.webkitStorageInfo' is deprecated. Please use 'navigator.webkitTemporaryStorage' or 'navigator.webkitPersistentStorage' instead.
+CONSOLE WARNING: line 104: 'window.webkitStorageInfo' is deprecated. Please use 'navigator.webkitTemporaryStorage' or 'navigator.webkitPersistentStorage' instead.
 Tests property access on a cached DOMWindow after the associated frame is removed from a web page and garbage collected. Test should not crash and properties should be set to sane defaults.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
@@ -138,6 +138,7 @@
 PASS childWindow.onwebkittransitionend is null
 PASS childWindow.onwheel is null
 PASS childWindow.opener is null
+PASS childWindow.origin is 'file://'
 PASS childWindow.outerHeight is 0
 PASS childWindow.outerWidth is 0
 PASS childWindow.pageXOffset is 0
diff --git a/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-window-after-frame-removed-expected.txt b/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-window-after-frame-removed-expected.txt
index 18f6536..95b48e5a 100644
--- a/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-window-after-frame-removed-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/dom/Window/property-access-on-cached-window-after-frame-removed-expected.txt
@@ -1,4 +1,4 @@
-CONSOLE WARNING: line 101: 'window.webkitStorageInfo' is deprecated. Please use 'navigator.webkitTemporaryStorage' or 'navigator.webkitPersistentStorage' instead.
+CONSOLE WARNING: line 104: 'window.webkitStorageInfo' is deprecated. Please use 'navigator.webkitTemporaryStorage' or 'navigator.webkitPersistentStorage' instead.
 Tests property access on a cached DOMWindow after the associated frame is no longer in a web page. Test should not crash and properties should be set to sane defaults.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
@@ -138,6 +138,7 @@
 PASS childWindow.onwebkittransitionend is null
 PASS childWindow.onwheel is null
 PASS childWindow.opener is null
+PASS childWindow.origin is 'file://'
 PASS childWindow.outerHeight is 0
 PASS childWindow.outerWidth is 0
 PASS childWindow.pageXOffset is 0
diff --git a/third_party/WebKit/LayoutTests/fast/dom/Window/resources/window-property-collector.js b/third_party/WebKit/LayoutTests/fast/dom/Window/resources/window-property-collector.js
index bf28968..fd228a0 100644
--- a/third_party/WebKit/LayoutTests/fast/dom/Window/resources/window-property-collector.js
+++ b/third_party/WebKit/LayoutTests/fast/dom/Window/resources/window-property-collector.js
@@ -54,6 +54,9 @@
     case "location.origin":
         expected = "'null'";
         break;
+    case "origin":
+        expected = "'file://'";
+        break;
     case "location.pathname":
         expected = "'blank'";
         break;
diff --git a/third_party/WebKit/LayoutTests/fast/forms/textarea/textarea-selection-preservation-expected.txt b/third_party/WebKit/LayoutTests/fast/forms/textarea/textarea-selection-preservation-expected.txt
index fa168e7..5b2446a07 100644
--- a/third_party/WebKit/LayoutTests/fast/forms/textarea/textarea-selection-preservation-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/forms/textarea/textarea-selection-preservation-expected.txt
@@ -37,8 +37,8 @@
 PASS ta.selectionStart is 12
 PASS ta.selectionEnd is 12
 - append a empty text node
-PASS ta.selectionStart is 12
-PASS ta.selectionEnd is 12
+PASS ta.selectionStart is 2
+PASS ta.selectionEnd is 3
 PASS successfullyParsed is true
 
 TEST COMPLETE
diff --git a/third_party/WebKit/LayoutTests/fast/forms/textarea/textarea-selection-preservation.html b/third_party/WebKit/LayoutTests/fast/forms/textarea/textarea-selection-preservation.html
index fb04acd..699a998 100644
--- a/third_party/WebKit/LayoutTests/fast/forms/textarea/textarea-selection-preservation.html
+++ b/third_party/WebKit/LayoutTests/fast/forms/textarea/textarea-selection-preservation.html
@@ -68,8 +68,8 @@
     debug("- append a empty text node");
     ta.setSelectionRange(2, 3);
     ta.appendChild(document.createTextNode(''));
-    shouldBe('ta.selectionStart', '12');
-    shouldBe('ta.selectionEnd', '12');
+    shouldBe('ta.selectionStart', '2');
+    shouldBe('ta.selectionEnd', '3');
 </script>
 </body>
 </html>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/nested-and-unbreakable-crash.html b/third_party/WebKit/LayoutTests/fast/multicol/nested-and-unbreakable-crash.html
new file mode 100644
index 0000000..424e469
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/multicol/nested-and-unbreakable-crash.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<p>PASS if no crash or assertion failure.</p>
+<div style="columns:7; column-fill:auto; height:20px;">
+    <div style="columns:2;">
+        <div style="columns:1; overflow-y:scroll; column-fill:auto; height:1px; margin-top:1em;">
+            <div style="height:50px;"></div>
+            <div style="margin-top:1px;"></div>
+        </div>
+    </div>
+</div>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script>
+test(() => { }, "No crash or assertion failure.");
+</script>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/nested-writing-mode-root-crash.html b/third_party/WebKit/LayoutTests/fast/multicol/nested-writing-mode-root-crash.html
new file mode 100644
index 0000000..becdc782
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/multicol/nested-writing-mode-root-crash.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<p>PASS if no crash or assertion failure.</p>
+<div style="columns:2;">
+    <div style="columns:2; writing-mode:vertical-rl;"><br></div>
+</div>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script>
+    test(() => { }, "No crash or assertion failure.");
+</script>
diff --git a/third_party/WebKit/LayoutTests/fast/table/table-size-must-consider-stretch-alignment.html b/third_party/WebKit/LayoutTests/fast/table/table-size-must-consider-stretch-alignment.html
new file mode 100644
index 0000000..58b3e3a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/table/table-size-must-consider-stretch-alignment.html
@@ -0,0 +1,142 @@
+<!DOCTYPE HTML>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script src="../../resources/check-layout-th.js"></script>
+<style>
+.block {
+  width: 200px;
+  height: 200px;
+  background: lightgrey;
+}
+
+.flex { display: flex; }
+.grid {
+   display: grid;
+   grid: 100px / 150px;
+}
+
+.itemsStart {
+   align-items: start;
+   justify-items: start;
+}
+.itemsFlexStart {
+   align-items: flex-start;
+   justify-items: flex-start;
+}
+
+.item {
+  display: table;
+  background: lime;
+  border-spacing: 0px;
+  font: 10px/1 Ahem;
+}
+
+td { padding: 0px; }
+caption { background: grey; }
+
+</style>
+
+<p>This test verifies that table sizing logic considers stretch alignment when computing its width and height.</p>
+
+<p>Regular block container of a table element and 1 implicit row and column.<br>The align-self property doesn't apply to block-level boxes.</br>The justify-self property has its initial/default value 'normal', which behaves like 'start'.</p>
+<div class="block">
+    <div class="item" data-expected-width="100" data-expected-height="10">table cell</div>
+</div>
+
+<br><br>
+
+<p>Regular block container of an empty table.<br>The align-self property doesn't apply to block-level boxes.</br>The justify-self property has its initial/default value 'normal', which behaves like 'start'.</p>
+<div class="block">
+    <table class="item" data-expected-width="70" data-expected-height="10">
+        <caption>caption</caption>
+    </table>
+</div>
+
+<br><br>
+
+<p>Regular block container of a table element and 1 explicit row and column.<br>The align-self property doesn't apply to block-level boxes.</br>The justify-self property has its initial/default value 'normal', which behaves like 'start'.</p>
+<div class="block">
+    <table class="item" data-expected-width="100" data-expected-height="20">
+        <tr data-expected-width="100" data-expected-height="10">
+            <td>table cell</td>
+        </tr>
+        <caption>caption</caption>
+    </table>
+</div>
+
+<br><br>
+
+<p>Grid container of table element and 1 implicit row and column.<br>Both the align-self and justify-self properties have their initial/default value 'normal', which behaves like 'stretch'.</p>
+<div class="block grid">
+    <div class="item" data-expected-width="150" data-expected-height="100">table cell</div>
+</div>
+
+<br><br>
+
+<p>Grid container of an empty table element.<br>Both the align-self and justify-self properties have their initial/default value 'normal', which behaves like 'stretch'.</p>
+<div class="block grid">
+    <table class="item" data-expected-width="150" data-expected-height="110">
+        <caption>caption</caption>
+    </table>
+</div>
+
+<br><br>
+
+<p>Grid container of an empty table element.<br>Both the align-self and justify-self properties have a value 'start', which should prevent the item to be stretched.</p>
+<div class="block grid itemsStart">
+    <table class="item" data-expected-width="70" data-expected-height="10">
+        <caption>caption</caption>
+    </table>
+</div>
+
+<br><br>
+
+<p>Grid container of table element and 1 explicit row and column.<br>Both the align-self and justify-self properties have their initial/default value 'normal', which behaves like 'stretch'.</p>
+<div class="block grid">
+    <table class="item" data-expected-width="150" data-expected-height="110">
+        <tr data-expected-width="150" data-expected-height="100">
+            <td>table cell</td>
+        </tr>
+        <caption>caption</caption>
+    </table>
+</div>
+
+<br><br>
+
+<p>Flex container of table element and 1 implicit row and column.<br>Both the align-self and justify-self properties have their initial/default value 'normal', which behaves like 'stretch'.</p>
+<div class="block flex">
+    <div class="item" class="item" data-expected-width="200" data-expected-height="200">table cell</div>
+</div>
+
+<br><br>
+
+<p>Flex container of an empty table element.<br>Both the align-self and justify-self properties have their initial/default value 'normal', which behaves like 'stretch'.</p>
+<div class="block flex">
+    <table class="item" data-expected-width="200" data-expected-height="210">
+        <caption>caption</caption>
+    </table>
+</div>
+
+<br><br>
+
+<p>Flex container of an empty table element.<br>Both the align-self and justify-self properties have a value 'start', which should prevent the item to be stretched.</p>
+<div class="block flex itemsFlexStart">
+    <table class="item" data-expected-width="70" data-expected-height="10">
+        <caption>caption</caption>
+    </table>
+</div>
+
+<br><br>
+
+<p>Flex container of table element and 1 explicit row and column.<br>Both the align-self and justify-self properties have their initial/default value 'normal', which behaves like 'stretch'.</p>
+<div class="block flex">
+    <table class="item" class="item" data-expected-width="200" data-expected-height="210">
+        <tr data-expected-width="200" data-expected-height="200">
+            <td>table cell</td>
+        </tr>
+        <caption>caption</caption>
+    </table>
+</div>
+<script>
+    checkLayout('.block');
+</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
index 4553b0d..a8a5d7b 100644
--- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -2179,6 +2179,7 @@
     getter onerror
     getter onrejectionhandled
     getter onunhandledrejection
+    getter origin
     getter performance
     getter self
     method atob
@@ -2194,6 +2195,7 @@
     setter onerror
     setter onrejectionhandled
     setter onunhandledrejection
+    setter origin
 interface WorkerLocation
     getter hash
     getter host
diff --git a/third_party/WebKit/LayoutTests/http/tests/websocket/handshake-fail-by-maxlength-expected.txt b/third_party/WebKit/LayoutTests/http/tests/websocket/handshake-fail-by-maxlength-expected.txt
index 8718944..2bc1d3c 100644
--- a/third_party/WebKit/LayoutTests/http/tests/websocket/handshake-fail-by-maxlength-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/websocket/handshake-fail-by-maxlength-expected.txt
@@ -6,7 +6,7 @@
 PASS onerror() was called
 PASS timedOut is false
 PASS connected is false
-PASS origin is undefined.
+PASS wsOrigin is undefined.
 PASS successfullyParsed is true
 
 TEST COMPLETE
diff --git a/third_party/WebKit/LayoutTests/http/tests/websocket/handshake-fail-by-maxlength.html b/third_party/WebKit/LayoutTests/http/tests/websocket/handshake-fail-by-maxlength.html
index 42bd8cf..34406e9 100644
--- a/third_party/WebKit/LayoutTests/http/tests/websocket/handshake-fail-by-maxlength.html
+++ b/third_party/WebKit/LayoutTests/http/tests/websocket/handshake-fail-by-maxlength.html
@@ -13,12 +13,12 @@
 
 var timedOut = false;
 var connected = false;
-var origin;
+var wsOrigin;
 
 function endTest() {
     shouldBeFalse('timedOut');
     shouldBeFalse('connected');
-    shouldBeUndefined('origin');
+    shouldBeUndefined('wsOrigin');
     clearTimeout(timeoutID);
     finishJSTest();
 }
@@ -34,8 +34,8 @@
 
 ws.onmessage = function(messageEvent)
 {
-    origin = messageEvent.data;
-    debug('origin = ' + origin);
+    wsOrigin = messageEvent.data;
+    debug('origin = ' + wsOrigin);
     ws.close();
 }
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/websocket/handshake-fail-by-prepended-null-expected.txt b/third_party/WebKit/LayoutTests/http/tests/websocket/handshake-fail-by-prepended-null-expected.txt
index 0035b19..9a45109 100644
--- a/third_party/WebKit/LayoutTests/http/tests/websocket/handshake-fail-by-prepended-null-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/websocket/handshake-fail-by-prepended-null-expected.txt
@@ -6,7 +6,7 @@
 PASS onerror() was called
 PASS timedOut is false
 PASS connected is false
-PASS origin is undefined.
+PASS wsOrigin is undefined.
 PASS successfullyParsed is true
 
 TEST COMPLETE
diff --git a/third_party/WebKit/LayoutTests/http/tests/websocket/handshake-fail-by-prepended-null.html b/third_party/WebKit/LayoutTests/http/tests/websocket/handshake-fail-by-prepended-null.html
index 11423ffb..04cf68a8 100644
--- a/third_party/WebKit/LayoutTests/http/tests/websocket/handshake-fail-by-prepended-null.html
+++ b/third_party/WebKit/LayoutTests/http/tests/websocket/handshake-fail-by-prepended-null.html
@@ -13,12 +13,12 @@
 
 var timedOut = false;
 var connected = false;
-var origin;
+var wsOrigin;
 
 function endTest() {
     shouldBeFalse('timedOut');
     shouldBeFalse('connected');
-    shouldBeUndefined('origin');
+    shouldBeUndefined('wsOrigin');
     clearTimeout(timeoutID);
     finishJSTest();
 }
@@ -34,8 +34,8 @@
 
 ws.onmessage = function(messageEvent)
 {
-    origin = messageEvent.data;
-    debug('origin = ' + origin);
+    wsOrigin = messageEvent.data;
+    debug('origin = ' + wsOrigin);
     ws.close();
 }
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/websocket/iframe-sandbox-expected.txt b/third_party/WebKit/LayoutTests/http/tests/websocket/iframe-sandbox-expected.txt
index 721bad5..6a5e047 100644
--- a/third_party/WebKit/LayoutTests/http/tests/websocket/iframe-sandbox-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/websocket/iframe-sandbox-expected.txt
@@ -3,7 +3,7 @@
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-PASS origin is "null"
+PASS wsOrigin is "null"
 PASS successfullyParsed is true
 
 TEST COMPLETE
diff --git a/third_party/WebKit/LayoutTests/http/tests/websocket/iframe-sandbox.html b/third_party/WebKit/LayoutTests/http/tests/websocket/iframe-sandbox.html
index 76657dd..003768b 100644
--- a/third_party/WebKit/LayoutTests/http/tests/websocket/iframe-sandbox.html
+++ b/third_party/WebKit/LayoutTests/http/tests/websocket/iframe-sandbox.html
@@ -7,12 +7,12 @@
 
 window.addEventListener("message", receiveMessage, false);
 
-var origin;
+var wsOrigin;
 
 function receiveMessage(event)
 {
-    origin = event.data;
-    shouldBeEqualToString("origin", "null");
+    wsOrigin = event.data;
+    shouldBeEqualToString("wsOrigin", "null");
     finishJSTest();
 }
 </script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/websocket/send-onmessage-origin-expected.txt b/third_party/WebKit/LayoutTests/http/tests/websocket/send-onmessage-origin-expected.txt
index 2201655..a337073 100644
--- a/third_party/WebKit/LayoutTests/http/tests/websocket/send-onmessage-origin-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/websocket/send-onmessage-origin-expected.txt
@@ -5,9 +5,9 @@
 
 Connected.
 PASS data is firstMessageToSend
-PASS origin is "ws://localhost:8880"
+PASS wsOrigin is "ws://localhost:8880"
 PASS data is secondMessageToSend
-PASS origin is "ws://localhost:8880"
+PASS wsOrigin is "ws://localhost:8880"
 Closed.
 PASS successfullyParsed is true
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/websocket/send-onmessage-origin.html b/third_party/WebKit/LayoutTests/http/tests/websocket/send-onmessage-origin.html
index 7633d2f..96bdfd7 100644
--- a/third_party/WebKit/LayoutTests/http/tests/websocket/send-onmessage-origin.html
+++ b/third_party/WebKit/LayoutTests/http/tests/websocket/send-onmessage-origin.html
@@ -21,7 +21,7 @@
 var secondMessageToSend = "This is the second.";
 // needs to be global to be accessbile from shouldBe().
 var data = "";
-var origin = "";
+var wsOrigin = "";
 
 ws.onopen = function()
 {
@@ -34,14 +34,14 @@
     // The server should echo back the first message.
     data = messageEvent.data;
     shouldBe("data", "firstMessageToSend");
-    origin = messageEvent.origin;
-    shouldBeEqualToString("origin", "ws://localhost:8880");
+    wsOrigin = messageEvent.origin;
+    shouldBeEqualToString("wsOrigin", "ws://localhost:8880");
     ws.onmessage = function(messageEvent) {
         // The server should echo back the second message.
         data = messageEvent.data;
         shouldBe("data", "secondMessageToSend");
-        origin = messageEvent.origin;
-        shouldBeEqualToString("origin", "ws://localhost:8880");
+        wsOrigin = messageEvent.origin;
+        shouldBeEqualToString("wsOrigin", "ws://localhost:8880");
     };
     ws.send(secondMessageToSend);
 };
diff --git a/third_party/WebKit/LayoutTests/media/controls/video-overlay-play-button.html b/third_party/WebKit/LayoutTests/media/controls/video-overlay-play-button.html
new file mode 100644
index 0000000..9534c57a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/media/controls/video-overlay-play-button.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<title>Test that the overlay play button respects the controls attribute.</title>
+<script src='../../resources/testharness.js'></script>
+<script src='../../resources/testharnessreport.js'></script>
+<script src='../media-file.js'></script>
+<script src='../media-controls.js'></script>
+<body>
+<script>
+async_test(function(t) {
+  var mediaControlsOverlayPlayButtonValue =
+      internals.runtimeFlags.mediaControlsOverlayPlayButtonEnabled;
+  internals.runtimeFlags.mediaControlsOverlayPlayButtonEnabled = true;
+
+  t.add_cleanup(() => {
+    internals.runtimeFlags.mediaControlsOverlayPlayButtonEnabled =
+        mediaControlsOverlayPlayButtonValue;
+  });
+
+  // Add video dynamically, since otherwise the controls are created, but
+  // hidden, before the setting is set, causing the setting to be ignored.
+  var video = document.createElement('video');
+  document.body.appendChild(video);
+
+  video.controls = true;
+  var button = mediaControlsButton(video, 'overlay-play-button')
+  assert_equals(getComputedStyle(button).display, 'flex');
+
+  var watcher = new EventWatcher(t, video, ['loadeddata', 'play', 'pause']);
+  watcher.wait_for('loadeddata').then(t.step_func(function() {
+    video.play();
+    return watcher.wait_for('play');
+  })).then(t.step_func(function() {
+    assert_equals(getComputedStyle(button).display, 'none');
+    video.pause();
+    return watcher.wait_for('pause');
+  })).then(t.step_func(function() {
+    assert_equals(getComputedStyle(button).display, 'flex');
+    video.controls = false;
+    assert_equals(getComputedStyle(button).display, 'none');
+    video.play();
+    return watcher.wait_for('play');
+  })).then(t.step_func(function() {
+    assert_equals(getComputedStyle(button).display, 'none');
+    video.pause();
+    return watcher.wait_for('pause');
+  })).then(t.step_func_done(function() {
+    assert_equals(getComputedStyle(button).display, 'none');
+    video.controls = true;
+    assert_equals(getComputedStyle(button).display, 'flex');
+  }));
+
+  video.src = findMediaFile('video', '../content/test');
+});
+</script>
diff --git a/third_party/WebKit/LayoutTests/media/video-controls-overlay-play-button.html b/third_party/WebKit/LayoutTests/media/video-controls-overlay-play-button.html
deleted file mode 100644
index e9e8f32..0000000
--- a/third_party/WebKit/LayoutTests/media/video-controls-overlay-play-button.html
+++ /dev/null
@@ -1,47 +0,0 @@
-<!DOCTYPE html>
-<title>Test that the overlay play button respects the controls attribute.</title>
-<script src="../resources/testharness.js"></script>
-<script src="../resources/testharnessreport.js"></script>
-<script src="media-file.js"></script>
-<script src="media-controls.js"></script>
-<body>
-<script>
-async_test(function(t) {
-    internals.settings.setMediaControlsOverlayPlayButtonEnabled(true);
-
-    // Add video dynamically, since otherwise the controls are created, but
-    // hidden, before the setting is set, causing the setting to be ignored.
-    var video = document.createElement("video");
-    document.body.appendChild(video);
-
-    video.controls = true;
-    var button = mediaControlsButton(video, "overlay-play-button")
-    assert_equals(getComputedStyle(button).display, "flex");
-
-    var watcher = new EventWatcher(t, video, ["loadeddata", "play", "pause"]);
-    watcher.wait_for("loadeddata").then(t.step_func(function() {
-        video.play();
-        return watcher.wait_for("play");
-    })).then(t.step_func(function() {
-        assert_equals(getComputedStyle(button).display, "none");
-        video.pause();
-        return watcher.wait_for("pause");
-    })).then(t.step_func(function() {
-        assert_equals(getComputedStyle(button).display, "flex");
-        video.controls = false;
-        assert_equals(getComputedStyle(button).display, "none");
-        video.play();
-        return watcher.wait_for("play");
-    })).then(t.step_func(function() {
-        assert_equals(getComputedStyle(button).display, "none");
-        video.pause();
-        return watcher.wait_for("pause");
-    })).then(t.step_func_done(function() {
-        assert_equals(getComputedStyle(button).display, "none");
-        video.controls = true;
-        assert_equals(getComputedStyle(button).display, "flex");
-    }));
-
-    video.src = findMediaFile("video", "content/test");
-});
-</script>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/first-line-with-first-letter-expected.html b/third_party/WebKit/LayoutTests/paint/invalidation/first-line-with-first-letter-expected.html
new file mode 100644
index 0000000..7389da8de
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/paint/invalidation/first-line-with-first-letter-expected.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<style>
+  div::first-letter { color: white }
+  div::first-line { background: green }
+</style>
+<div>
+  First letter should be white, and the first line should have a green
+  background.
+</div>
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/first-line-with-first-letter.html b/third_party/WebKit/LayoutTests/paint/invalidation/first-line-with-first-letter.html
new file mode 100644
index 0000000..5d46894
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/paint/invalidation/first-line-with-first-letter.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<style>
+  #t1::first-letter { color: white }
+  #t1::first-line { background: red }
+  #t1.green::first-line { background: green }
+</style>
+<div id="t1">
+  First letter should be white, and the first line should have a green
+  background.
+</div>
+<script>
+  if (window.testRunner)
+    testRunner.waitUntilDone();
+
+  requestAnimationFrame(() =>
+    requestAnimationFrame(() => {
+      t1.className = "green";
+      if (window.testRunner)
+        testRunner.notifyDone();
+    }));
+</script>
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/table-cell-vertical-overflow-expected.png b/third_party/WebKit/LayoutTests/paint/invalidation/table-cell-vertical-overflow-expected.png
new file mode 100644
index 0000000..87e33894
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/paint/invalidation/table-cell-vertical-overflow-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_style-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_style-expected.png
index ca8e6a114..eb3fb83 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_style-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_style-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t0805-c5517-brdr-s-00-c-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t0805-c5517-brdr-s-00-c-expected.png
index ec92b614..c550e031c 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t0805-c5517-brdr-s-00-c-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t0805-c5517-brdr-s-00-c-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-04-d-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-04-d-expected.png
index a1c83df..b16e102 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-04-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-04-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-14-d-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-14-d-expected.png
index 2e05ca1..585c6b7 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-14-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-14-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-24-d-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-24-d-expected.png
index 6ef24e9d..0c11227 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-24-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-24-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-34-d-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-34-d-expected.png
index 0d3514d0..c91ea61 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-34-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-34-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-41-d-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-41-d-expected.png
index 2e979d7..857f30e2 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-41-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-41-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-42-d-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-42-d-expected.png
index 4ce085c..ca26a4b 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-42-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-42-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-43-d-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-43-d-expected.png
index 9ad9fa85..b22f0cac 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-43-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-43-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-44-d-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-44-d-expected.png
index 6c4f16e..cfdb230 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-44-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-44-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-45-d-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-45-d-expected.png
index 11a2c4e..6a913877 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-45-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-45-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-46-d-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-46-d-expected.png
index 58888e5..d2bfa3be 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-46-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-46-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-47-d-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-47-d-expected.png
index 8f3499e..a1b7706e 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-47-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-47-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-48-d-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-48-d-expected.png
index 1cb892eb..00d144d2 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-48-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-48-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-49-d-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-49-d-expected.png
index 92868be..158993e 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-49-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-49-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-54-d-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-54-d-expected.png
index 8e0f717..2d97670 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-54-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-54-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-64-d-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-64-d-expected.png
index 23d6644..eb59afd 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-64-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-64-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-74-d-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-74-d-expected.png
index 1ace87a0..061322e 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-74-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-74-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-84-d-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-84-d-expected.png
index 26cadcdd..d1de84d 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-84-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-84-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-94-d-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-94-d-expected.png
index 0ccb7d7..06e9e90 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-94-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t170602-bdr-conflct-w-94-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-mixed-alpha-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-mixed-alpha-expected.png
index 31bc9f4..1c4bf784 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-mixed-alpha-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-mixed-alpha-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-mixed-alpha2-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-mixed-alpha2-expected.png
index 3fe1f68f..2c1bbc1 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-mixed-alpha2-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-mixed-alpha2-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/borderRadiusAllStylesAllCorners-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/borderRadiusAllStylesAllCorners-expected.png
index 70aa9d769..30a76bf 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/borderRadiusAllStylesAllCorners-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/borderRadiusAllStylesAllCorners-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/outline-alpha-block-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/outline-alpha-block-expected.png
index d4a8ff3..f45948a7 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/outline-alpha-block-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/outline-alpha-block-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/outline-alpha-inline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/outline-alpha-inline-expected.png
index 46c6f7e..fbae8eb 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/outline-alpha-inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/outline-alpha-inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/box-shadow/inset-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/box-shadow/inset-expected.png
index 187631e..a76e50c 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/box-shadow/inset-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/box-shadow/inset-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/box-shadow/inset-subpixel-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/box-shadow/inset-subpixel-expected.png
index c71abde..2b758aa4 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/box-shadow/inset-subpixel-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/box-shadow/inset-subpixel-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/css3-text/css3-text-decoration/text-decoration-style-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/css3-text/css3-text-decoration/text-decoration-style-expected.png
index 4c58378..880ccd3 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/css3-text/css3-text-decoration/text-decoration-style-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/css3-text/css3-text-decoration/text-decoration-style-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/dom/Window/property-access-on-cached-properties-after-frame-navigated-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/dom/Window/property-access-on-cached-properties-after-frame-navigated-expected.txt
index 0daa4a8..dba5987e 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/dom/Window/property-access-on-cached-properties-after-frame-navigated-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/dom/Window/property-access-on-cached-properties-after-frame-navigated-expected.txt
@@ -1,4 +1,4 @@
-CONSOLE WARNING: line 101: 'window.webkitStorageInfo' is deprecated. Please use 'navigator.webkitTemporaryStorage' or 'navigator.webkitPersistentStorage' instead.
+CONSOLE WARNING: line 104: 'window.webkitStorageInfo' is deprecated. Please use 'navigator.webkitTemporaryStorage' or 'navigator.webkitPersistentStorage' instead.
 Tests access of cached DOMWindow properties after the associated frame is navigated. Test should not crash and properties should be set to sane defaults.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-and-gced-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-and-gced-expected.txt
index 03fb6d55..01269ba 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-and-gced-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-and-gced-expected.txt
@@ -1,4 +1,4 @@
-CONSOLE WARNING: line 101: 'window.webkitStorageInfo' is deprecated. Please use 'navigator.webkitTemporaryStorage' or 'navigator.webkitPersistentStorage' instead.
+CONSOLE WARNING: line 104: 'window.webkitStorageInfo' is deprecated. Please use 'navigator.webkitTemporaryStorage' or 'navigator.webkitPersistentStorage' instead.
 Tests access of cached DOMWindow properties after the associated frame is removed from a web page and garbage collected. Test should not crash and properties should be set to sane defaults.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-expected.txt
index d7a8ab8..cf6c1de 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-expected.txt
@@ -1,4 +1,4 @@
-CONSOLE WARNING: line 101: 'window.webkitStorageInfo' is deprecated. Please use 'navigator.webkitTemporaryStorage' or 'navigator.webkitPersistentStorage' instead.
+CONSOLE WARNING: line 104: 'window.webkitStorageInfo' is deprecated. Please use 'navigator.webkitTemporaryStorage' or 'navigator.webkitPersistentStorage' instead.
 Tests access of cached DOMWindow properties after the associated frame is no longer in a web page. Test should not crash and properties should be set to sane defaults.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/dom/Window/property-access-on-cached-window-after-frame-navigated-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/dom/Window/property-access-on-cached-window-after-frame-navigated-expected.txt
index da7a2c82..a72f27b 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/dom/Window/property-access-on-cached-window-after-frame-navigated-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/dom/Window/property-access-on-cached-window-after-frame-navigated-expected.txt
@@ -1,4 +1,4 @@
-CONSOLE WARNING: line 101: 'window.webkitStorageInfo' is deprecated. Please use 'navigator.webkitTemporaryStorage' or 'navigator.webkitPersistentStorage' instead.
+CONSOLE WARNING: line 104: 'window.webkitStorageInfo' is deprecated. Please use 'navigator.webkitTemporaryStorage' or 'navigator.webkitPersistentStorage' instead.
 Tests property access on a cached DOMWindow after the associated frame is navigated. Test should not crash and properties read from the cached DOMWindow should be identical to properties through the 'current' DOMWindow.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
@@ -166,6 +166,7 @@
 PASS oldChildWindow.onwebkittransitionend is newChildWindow.onwebkittransitionend
 PASS oldChildWindow.onwheel is newChildWindow.onwheel
 PASS oldChildWindow.opener is newChildWindow.opener
+PASS oldChildWindow.origin is newChildWindow.origin
 PASS oldChildWindow.outerHeight is newChildWindow.outerHeight
 PASS oldChildWindow.outerWidth is newChildWindow.outerWidth
 PASS oldChildWindow.pageXOffset is newChildWindow.pageXOffset
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/layers/opacity-outline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/layers/opacity-outline-expected.png
index 3c77136..ebea94f 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/layers/opacity-outline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/layers/opacity-outline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/overflow/overflow-with-local-background-attachment-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/overflow/overflow-with-local-background-attachment-expected.png
index c2c4907..5b50328 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/overflow/overflow-with-local-background-attachment-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/overflow/overflow-with-local-background-attachment-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-cell-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-cell-collapsed-border-expected.png
index cac3666..4f2088e9 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-cell-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-cell-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-cell-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-cell-expected.png
index c349ed9..7d8d82e7 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-cell-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-cell-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-collapsed-border-expected.png
index 148c8fa6e..1ce32b1a 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-column-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-column-collapsed-border-expected.png
index e388fc87..73a88d78 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-column-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-column-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-column-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-column-expected.png
index 3a332b2..4e418a0 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-column-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-column-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-column-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-column-group-collapsed-border-expected.png
index 483126f..8a45686 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-column-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-column-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-column-group-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-column-group-expected.png
index 67afd0d..1b31819 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-column-group-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-column-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-expected.png
index dee4155..d3612ae 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-quirks-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-quirks-collapsed-border-expected.png
index 6b00a3ef..8317788 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-quirks-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-quirks-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-quirks-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-quirks-expected.png
index e91838df..6a9675b1 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-quirks-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-quirks-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-row-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-row-collapsed-border-expected.png
index f75f54e8..b095342 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-row-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-row-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-row-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-row-expected.png
index 23628318..2910998 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-row-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-row-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-row-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-row-group-collapsed-border-expected.png
index 48b0d21..506c540 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-row-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-row-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-row-group-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-row-group-expected.png
index 77de645..4cb982cf 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-row-group-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_border-table-row-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_layers-hide-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_layers-hide-collapsed-border-expected.png
index 5c885906..16f29cae 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_layers-hide-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_layers-hide-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_layers-hide-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_layers-hide-expected.png
index 3cbdea6..9efc8dc 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_layers-hide-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_layers-hide-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-cell-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-cell-collapsed-border-expected.png
index e078d4a..346091d 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-cell-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-cell-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-cell-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-cell-expected.png
index d366ef6..c2f90a5 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-cell-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-cell-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-collapsed-border-expected.png
index f3dd6a45..f54398b 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-column-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-column-collapsed-border-expected.png
index f8b0aa62..e342e671 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-column-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-column-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-column-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-column-expected.png
index f8cf68f4..a42a5ad 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-column-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-column-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-column-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-column-group-collapsed-border-expected.png
index e9acf9f..ca43f93 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-column-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-column-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-column-group-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-column-group-expected.png
index 071f73a..f8d4445c 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-column-group-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-column-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-expected.png
index 3da3ad2..2cb5468 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-row-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-row-collapsed-border-expected.png
index 889b297a..003e000 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-row-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-row-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-row-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-row-expected.png
index 2e3e7b1b..5cb255d 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-row-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-row-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-row-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-row-group-collapsed-border-expected.png
index d71a473..16806d00a 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-row-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-row-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-row-group-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-row-group-expected.png
index 4559904..a85b30c 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-row-group-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_position-table-row-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-cell-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
index 0f806a0..aaac313 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-cell-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-cell-expected.png
index edd618c4..a41d6f7 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-cell-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-cell-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-collapsed-border-expected.png
index 654a55f4..6fd8573 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-column-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-column-collapsed-border-expected.png
index 1a5657d..1124fc8 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-column-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-column-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-column-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-column-expected.png
index 68191ed..4d19843 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-column-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-column-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
index 2e2a956..a79f8dd 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-column-group-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-column-group-expected.png
index cf9e768..64fc2c6d 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-column-group-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-column-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-expected.png
index e2d4b97..2709293f 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-row-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-row-collapsed-border-expected.png
index 49c6f17..b989e6aa0 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-row-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-row-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-row-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-row-expected.png
index 9dce23d..1134642 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-row-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-row-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
index 9137e4c9..97e6af9 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-row-group-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-row-group-expected.png
index e6c5275..4b033b62 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-row-group-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-row-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/border-collapsing/001-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/border-collapsing/001-expected.png
index ed56511..13746729 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/border-collapsing/001-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/border-collapsing/001-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/border-collapsing/001-vertical-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/border-collapsing/001-vertical-expected.png
index fadc2863..f25c3842 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/border-collapsing/001-vertical-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/border-collapsing/001-vertical-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/ietestcenter/css3/bordersbackgrounds/border-radius-style-001-expected.png b/third_party/WebKit/LayoutTests/platform/linux/ietestcenter/css3/bordersbackgrounds/border-radius-style-001-expected.png
index 5ea28b0..195cb05a 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/ietestcenter/css3/bordersbackgrounds/border-radius-style-001-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/ietestcenter/css3/bordersbackgrounds/border-radius-style-001-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/ietestcenter/css3/bordersbackgrounds/border-radius-style-002-expected.png b/third_party/WebKit/LayoutTests/platform/linux/ietestcenter/css3/bordersbackgrounds/border-radius-style-002-expected.png
index e87a6e0f..e910926 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/ietestcenter/css3/bordersbackgrounds/border-radius-style-002-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/ietestcenter/css3/bordersbackgrounds/border-radius-style-002-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/layer-child-outline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/layer-child-outline-expected.png
index 03125f8..ebc25c2 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/layer-child-outline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/layer-child-outline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/custom/no-inherited-dashed-stroke-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/custom/no-inherited-dashed-stroke-expected.png
index 305a10f..96230150 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/svg/custom/no-inherited-dashed-stroke-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/svg/custom/no-inherited-dashed-stroke-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
index 563bc900..b6e64adc 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spinvalidation/paint/invalidation/layer-child-outline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spinvalidation/paint/invalidation/layer-child-outline-expected.png
index 03125f8..ebc25c2 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spinvalidation/paint/invalidation/layer-child-outline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/disable-spinvalidation/paint/invalidation/layer-child-outline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu/fast/canvas/canvas-arc-circumference-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu/fast/canvas/canvas-arc-circumference-expected.png
new file mode 100644
index 0000000..0a57ca31
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu/fast/canvas/canvas-arc-circumference-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu/fast/canvas/canvas-arc-circumference-fill-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu/fast/canvas/canvas-arc-circumference-fill-expected.png
deleted file mode 100644
index 5cd5cb1..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu/fast/canvas/canvas-arc-circumference-fill-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu/fast/canvas/canvas-incremental-repaint-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu/fast/canvas/canvas-incremental-repaint-expected.png
index 38e7f272..4a240e8 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu/fast/canvas/canvas-incremental-repaint-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu/fast/canvas/canvas-incremental-repaint-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_style-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_style-expected.png
new file mode 100644
index 0000000..eb3fb83
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_style-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_style-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_style-expected.png
index d103c556..0d2bf63 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_style-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_style-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-cell-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-cell-collapsed-border-expected.png
index 4bbfb61..265f173 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-cell-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-cell-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-cell-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-cell-expected.png
index c5b225de..73b2cb3e 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-cell-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-cell-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-collapsed-border-expected.png
index 1b2bf4d8..875000ef 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-column-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-column-collapsed-border-expected.png
index 991ba5bf..19ef114 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-column-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-column-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-column-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-column-expected.png
index c9947f8..1524657 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-column-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-column-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-column-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-column-group-collapsed-border-expected.png
index c91a474..54703d0 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-column-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-column-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-column-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-column-group-expected.png
index d2da6a7..c86255b 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-column-group-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-column-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-expected.png
index 97c2c350..f301a7c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-quirks-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-quirks-collapsed-border-expected.png
index b636956..1b91f95c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-quirks-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-quirks-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-quirks-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-quirks-expected.png
index acd701d9..c718c94 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-quirks-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-quirks-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-row-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-row-collapsed-border-expected.png
index ec08b8d..683ac556 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-row-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-row-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-row-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-row-expected.png
index b6f500e..1e3c368 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-row-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-row-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-row-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-row-group-collapsed-border-expected.png
index 704ad035..1af82603 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-row-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-row-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-row-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-row-group-expected.png
index 653682f..19884ac 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-row-group-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_border-table-row-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_layers-hide-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_layers-hide-collapsed-border-expected.png
index 16a66be..5d5273b 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_layers-hide-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_layers-hide-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_layers-hide-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_layers-hide-expected.png
index 5785c54..9e4950d 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_layers-hide-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_layers-hide-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-cell-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-cell-collapsed-border-expected.png
index c756d37..aeafadd 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-cell-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-cell-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-cell-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-cell-expected.png
index 068afc0..b2e2f876 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-cell-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-cell-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-collapsed-border-expected.png
index aa585755..16f7de5 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-column-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-column-collapsed-border-expected.png
index 57143aab..6e91128b 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-column-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-column-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-column-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-column-expected.png
index 33e1bec..b107d0c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-column-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-column-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-column-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-column-group-collapsed-border-expected.png
index a034446..b7be808 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-column-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-column-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-column-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-column-group-expected.png
index d1c2b480..03dcdaa 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-column-group-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-column-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-expected.png
index 8986885..93c5578d 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-row-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-row-collapsed-border-expected.png
index 1633403..ab214f3b 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-row-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-row-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-row-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-row-expected.png
index 52bfc05d..30b3b4a3 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-row-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-row-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-row-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-row-group-collapsed-border-expected.png
index 1fb1395..c66265c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-row-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-row-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-row-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-row-group-expected.png
index 118fafe9..656c08e8 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-row-group-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_position-table-row-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-cell-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
index 867aee1..52df295c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-cell-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-cell-expected.png
index 104af65..017fb331 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-cell-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-cell-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-collapsed-border-expected.png
index b9f12c3..0dfd327 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-column-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-column-collapsed-border-expected.png
index 426fe1e..c2aa3d8c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-column-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-column-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-column-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-column-expected.png
index 8c76cfd5..8c0f1cd0 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-column-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-column-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
index 17be6e4..3760da9 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-column-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-column-group-expected.png
index c431008b..3907118 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-column-group-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-column-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-expected.png
index 2ea6701b..04d94cd 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-row-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-row-collapsed-border-expected.png
index 5b1421d..1fae286 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-row-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-row-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-row-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-row-expected.png
index 36012dd..4f2d1d8 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-row-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-row-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
index a6f3e52..8b103e5 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-row-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-row-group-expected.png
index dc795f3..c36d7d9 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-row-group-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-row-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
index ef8ce75..419f766 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_style-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_style-expected.png
new file mode 100644
index 0000000..0d2bf63
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_style-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/compositing/overflow/border-radius-styles-with-composited-child-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/compositing/overflow/border-radius-styles-with-composited-child-expected.png
new file mode 100644
index 0000000..4dda4ab
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/compositing/overflow/border-radius-styles-with-composited-child-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/borders/borderRadiusAllStylesAllCorners-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/borders/borderRadiusAllStylesAllCorners-expected.png
new file mode 100644
index 0000000..78310ca
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/borders/borderRadiusAllStylesAllCorners-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/borders/borderRadiusDashed01-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/borders/borderRadiusDashed01-expected.png
new file mode 100644
index 0000000..cfc557f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/borders/borderRadiusDashed01-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/borders/borderRadiusDashed02-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/borders/borderRadiusDashed02-expected.png
new file mode 100644
index 0000000..24f0ce3a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/borders/borderRadiusDashed02-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/borders/borderRadiusDashed03-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/borders/borderRadiusDashed03-expected.png
new file mode 100644
index 0000000..dd29cce
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/borders/borderRadiusDashed03-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/borders/borderRadiusDashed04-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/borders/borderRadiusDashed04-expected.png
new file mode 100644
index 0000000..50f367a5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/borders/borderRadiusDashed04-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/borders/borderRadiusDashed05-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/borders/borderRadiusDashed05-expected.png
new file mode 100644
index 0000000..d9ac765
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/borders/borderRadiusDashed05-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/borders/borderRadiusDashed06-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/borders/borderRadiusDashed06-expected.png
new file mode 100644
index 0000000..06e8f66
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/borders/borderRadiusDashed06-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/borders/borderRadiusDotted01-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/borders/borderRadiusDotted01-expected.png
new file mode 100644
index 0000000..e60883c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/borders/borderRadiusDotted01-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/borders/borderRadiusDotted04-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/borders/borderRadiusDotted04-expected.png
new file mode 100644
index 0000000..ed9ed195
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/borders/borderRadiusDotted04-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/box-shadow/inset-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/box-shadow/inset-expected.png
new file mode 100644
index 0000000..ee304d5f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/box-shadow/inset-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/box-shadow/inset-subpixel-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/box-shadow/inset-subpixel-expected.png
new file mode 100644
index 0000000..d9ce72b3
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/box-shadow/inset-subpixel-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/ietestcenter/css3/bordersbackgrounds/border-radius-style-001-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/ietestcenter/css3/bordersbackgrounds/border-radius-style-001-expected.png
new file mode 100644
index 0000000..dade1ad4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/ietestcenter/css3/bordersbackgrounds/border-radius-style-001-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/ietestcenter/css3/bordersbackgrounds/border-radius-style-002-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/ietestcenter/css3/bordersbackgrounds/border-radius-style-002-expected.png
new file mode 100644
index 0000000..3741297
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/ietestcenter/css3/bordersbackgrounds/border-radius-style-002-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/gpu/fast/canvas/canvas-arc-circumference-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/gpu/fast/canvas/canvas-arc-circumference-expected.png
new file mode 100644
index 0000000..0a57ca31
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/gpu/fast/canvas/canvas-arc-circumference-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/gpu/fast/canvas/canvas-arc-circumference-fill-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/gpu/fast/canvas/canvas-arc-circumference-fill-expected.png
new file mode 100644
index 0000000..411b819
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/gpu/fast/canvas/canvas-arc-circumference-fill-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/gpu/fast/canvas/canvas-ellipse-circumference-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/gpu/fast/canvas/canvas-ellipse-circumference-expected.png
new file mode 100644
index 0000000..9f0bf823
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/gpu/fast/canvas/canvas-ellipse-circumference-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/gpu/fast/canvas/canvas-ellipse-circumference-fill-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/gpu/fast/canvas/canvas-ellipse-circumference-fill-expected.png
new file mode 100644
index 0000000..ce87211
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/gpu/fast/canvas/canvas-ellipse-circumference-fill-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/gpu/fast/canvas/canvas-incremental-repaint-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/gpu/fast/canvas/canvas-incremental-repaint-expected.png
new file mode 100644
index 0000000..e27292e0
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/gpu/fast/canvas/canvas-incremental-repaint-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/prefer_compositing_to_lcd_text/compositing/overflow/border-radius-styles-with-composited-child-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/prefer_compositing_to_lcd_text/compositing/overflow/border-radius-styles-with-composited-child-expected.png
new file mode 100644
index 0000000..4dda4ab
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/prefer_compositing_to_lcd_text/compositing/overflow/border-radius-styles-with-composited-child-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/border_style-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/border_style-expected.png
index 3544bd9e..704158d 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/border_style-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/border_style-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/overflow/overflow-with-local-background-attachment-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/overflow/overflow-with-local-background-attachment-expected.png
index 098ae866..a686ade 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/overflow/overflow-with-local-background-attachment-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/overflow/overflow-with-local-background-attachment-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-cell-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-cell-collapsed-border-expected.png
index 1045a33..8c8d31f 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-cell-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-cell-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-cell-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-cell-expected.png
index ed3597ba..474fc6c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-cell-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-cell-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-column-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-column-collapsed-border-expected.png
index bf67ce4..2b368ea3 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-column-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-column-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-column-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-column-expected.png
index b7c44dd..11b3cfd 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-column-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-column-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-column-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-column-group-collapsed-border-expected.png
index 20a416f..9937402 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-column-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-column-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-column-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-column-group-expected.png
index 3eed2112..d4915ae 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-column-group-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-column-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-expected.png
index 6654227..0db2fcd 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-row-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-row-collapsed-border-expected.png
index 67b1987..958fe07 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-row-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-row-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-row-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-row-expected.png
index c7d8515..cf72fcd 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-row-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-row-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-row-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-row-group-collapsed-border-expected.png
index a2bd2bd0..5f96ab8 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-row-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-row-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-row-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-row-group-expected.png
index 7e2fbee8..68195dc 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-row-group-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_border-table-row-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_layers-hide-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_layers-hide-expected.png
index 4b5327e..48c1130 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_layers-hide-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_layers-hide-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-cell-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-cell-collapsed-border-expected.png
index 553c171..c7be85c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-cell-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-cell-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-cell-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-cell-expected.png
index 7a7810d..c3ab278 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-cell-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-cell-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-column-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-column-collapsed-border-expected.png
index f460de8..9b5bae3 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-column-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-column-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-column-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-column-expected.png
index 85c573b..713524e 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-column-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-column-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-column-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-column-group-collapsed-border-expected.png
index e49cf75..14ffce5 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-column-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-column-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-column-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-column-group-expected.png
index 844b07dd..5293e7b 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-column-group-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-column-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-row-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-row-collapsed-border-expected.png
index a9a6454..9aa02d8 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-row-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-row-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-row-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-row-expected.png
index 29529b57..31af6bb 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-row-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-row-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-row-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-row-group-collapsed-border-expected.png
index 1e5123b1..ce7a74c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-row-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-row-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-row-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-row-group-expected.png
index 894d3ef..0b90384f 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-row-group-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_position-table-row-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-cell-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
index 094beb62..05c4400 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-cell-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-cell-expected.png
index 06d918c..95b4b83 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-cell-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-cell-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-collapsed-border-expected.png
index 4398428..529f735 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-column-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-column-collapsed-border-expected.png
index 6cffd7e..ae35c90 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-column-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-column-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-column-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-column-expected.png
index 2c309b9a..338e328 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-column-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-column-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
index 6879c80..87d38e45 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-column-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-column-group-expected.png
index 7e95424..71f83030 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-column-group-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-column-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-expected.png
index 39bdb26..d31b08f 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-row-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-row-collapsed-border-expected.png
index 3b8d73a..a04f6494 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-row-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-row-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-row-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-row-expected.png
index c59ff9b..100c14a3 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-row-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-row-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
index 9aa9152..bcaf9f0 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-row-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-row-group-expected.png
index 40dac59..56906a91 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-row-group-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-row-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
index d2fec69..4d22418 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/border_style-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/border_style-expected.png
new file mode 100644
index 0000000..704158d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/border_style-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/compositing/overflow/border-radius-styles-with-composited-child-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/compositing/overflow/border-radius-styles-with-composited-child-expected.png
new file mode 100644
index 0000000..4dda4ab
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/compositing/overflow/border-radius-styles-with-composited-child-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/borders/borderRadiusAllStylesAllCorners-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/borders/borderRadiusAllStylesAllCorners-expected.png
new file mode 100644
index 0000000..78310ca
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/borders/borderRadiusAllStylesAllCorners-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/borders/borderRadiusDashed01-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/borders/borderRadiusDashed01-expected.png
new file mode 100644
index 0000000..cfc557f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/borders/borderRadiusDashed01-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/borders/borderRadiusDashed02-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/borders/borderRadiusDashed02-expected.png
new file mode 100644
index 0000000..24f0ce3a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/borders/borderRadiusDashed02-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/borders/borderRadiusDashed03-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/borders/borderRadiusDashed03-expected.png
new file mode 100644
index 0000000..dd29cce
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/borders/borderRadiusDashed03-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/borders/borderRadiusDashed04-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/borders/borderRadiusDashed04-expected.png
new file mode 100644
index 0000000..50f367a5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/borders/borderRadiusDashed04-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/borders/borderRadiusDashed05-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/borders/borderRadiusDashed05-expected.png
new file mode 100644
index 0000000..d9ac765
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/borders/borderRadiusDashed05-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/borders/borderRadiusDashed06-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/borders/borderRadiusDashed06-expected.png
new file mode 100644
index 0000000..06e8f66
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/borders/borderRadiusDashed06-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/borders/borderRadiusDotted01-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/borders/borderRadiusDotted01-expected.png
new file mode 100644
index 0000000..e60883c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/borders/borderRadiusDotted01-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/borders/borderRadiusDotted04-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/borders/borderRadiusDotted04-expected.png
new file mode 100644
index 0000000..ed9ed195
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/borders/borderRadiusDotted04-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/box-shadow/inset-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/box-shadow/inset-expected.png
new file mode 100644
index 0000000..ee304d5f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/box-shadow/inset-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/box-shadow/inset-subpixel-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/box-shadow/inset-subpixel-expected.png
new file mode 100644
index 0000000..d9ce72b3
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/box-shadow/inset-subpixel-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/ietestcenter/css3/bordersbackgrounds/border-radius-style-001-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/ietestcenter/css3/bordersbackgrounds/border-radius-style-001-expected.png
new file mode 100644
index 0000000..dade1ad4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/ietestcenter/css3/bordersbackgrounds/border-radius-style-001-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/ietestcenter/css3/bordersbackgrounds/border-radius-style-002-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/ietestcenter/css3/bordersbackgrounds/border-radius-style-002-expected.png
new file mode 100644
index 0000000..3741297
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/ietestcenter/css3/bordersbackgrounds/border-radius-style-002-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/gpu/fast/canvas/canvas-arc-circumference-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/gpu/fast/canvas/canvas-arc-circumference-expected.png
new file mode 100644
index 0000000..0a57ca31
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/gpu/fast/canvas/canvas-arc-circumference-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/gpu/fast/canvas/canvas-arc-circumference-fill-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/gpu/fast/canvas/canvas-arc-circumference-fill-expected.png
new file mode 100644
index 0000000..411b819
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/gpu/fast/canvas/canvas-arc-circumference-fill-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/gpu/fast/canvas/canvas-ellipse-circumference-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/gpu/fast/canvas/canvas-ellipse-circumference-expected.png
new file mode 100644
index 0000000..9f0bf823
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/gpu/fast/canvas/canvas-ellipse-circumference-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/gpu/fast/canvas/canvas-ellipse-circumference-fill-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/gpu/fast/canvas/canvas-ellipse-circumference-fill-expected.png
new file mode 100644
index 0000000..ce87211
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/gpu/fast/canvas/canvas-ellipse-circumference-fill-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/gpu/fast/canvas/canvas-incremental-repaint-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/gpu/fast/canvas/canvas-incremental-repaint-expected.png
new file mode 100644
index 0000000..e27292e0
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/gpu/fast/canvas/canvas-incremental-repaint-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/prefer_compositing_to_lcd_text/compositing/overflow/border-radius-styles-with-composited-child-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/prefer_compositing_to_lcd_text/compositing/overflow/border-radius-styles-with-composited-child-expected.png
new file mode 100644
index 0000000..4dda4ab
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/prefer_compositing_to_lcd_text/compositing/overflow/border-radius-styles-with-composited-child-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_style-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_style-expected.png
index 41956c2..ade8054 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_style-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_style-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t0805-c5517-brdr-s-00-c-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t0805-c5517-brdr-s-00-c-expected.png
index 74059e1..68d490b 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t0805-c5517-brdr-s-00-c-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t0805-c5517-brdr-s-00-c-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-04-d-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-04-d-expected.png
index 9876199..ec4533e5 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-04-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-04-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-14-d-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-14-d-expected.png
index 76a2716..f103a27 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-14-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-14-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-24-d-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-24-d-expected.png
index 398932a..59bf8d7 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-24-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-24-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-34-d-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-34-d-expected.png
index c4b63ac..609bb48 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-34-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-34-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-41-d-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-41-d-expected.png
index 2301268f..251af43 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-41-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-41-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-42-d-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-42-d-expected.png
index c8a85f0..dcb4a4c1 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-42-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-42-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-43-d-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-43-d-expected.png
index 429dc82..21c1b3e2 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-43-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-43-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-44-d-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-44-d-expected.png
index 830ce4d..e29d9ac 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-44-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-44-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-45-d-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-45-d-expected.png
index 2b29906..abb0165 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-45-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-45-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-46-d-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-46-d-expected.png
index d1e5a01..f28aef4 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-46-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-46-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-47-d-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-47-d-expected.png
index 25a7c53..ab7e7b8 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-47-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-47-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-48-d-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-48-d-expected.png
index 11698b4..8437d7b 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-48-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-48-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-49-d-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-49-d-expected.png
index 68e64d59..e508e18a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-49-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-49-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-54-d-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-54-d-expected.png
index 019a088..c816650 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-54-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-54-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-64-d-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-64-d-expected.png
index 8ccd571..d4665c7 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-64-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-64-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-74-d-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-74-d-expected.png
index 53d4524..2b09780 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-74-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-74-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-84-d-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-84-d-expected.png
index aeb8ac49..614eaa0 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-84-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-84-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-94-d-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-94-d-expected.png
index 1e1e7a1a..f8f7d9b 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-94-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t170602-bdr-conflct-w-94-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/borderRadiusAllStylesAllCorners-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/borderRadiusAllStylesAllCorners-expected.png
index 039dba9..c8700a7 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/borderRadiusAllStylesAllCorners-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/borderRadiusAllStylesAllCorners-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/outline-alpha-block-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/outline-alpha-block-expected.png
index 5f9f515..e2ad331 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/outline-alpha-block-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/outline-alpha-block-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/outline-alpha-inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/outline-alpha-inline-expected.png
index 62db17a2..795df42c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/outline-alpha-inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/outline-alpha-inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/layers/opacity-outline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/layers/opacity-outline-expected.png
index 2c5f1a9..713e8503 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/layers/opacity-outline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/layers/opacity-outline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/overflow/overflow-with-local-background-attachment-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/overflow/overflow-with-local-background-attachment-expected.png
index c68d1d47..a7e124c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/overflow/overflow-with-local-background-attachment-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/overflow/overflow-with-local-background-attachment-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-cell-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-cell-collapsed-border-expected.png
index fab80b5..c5bc6c2 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-cell-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-cell-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-cell-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-cell-expected.png
index de54438f..d6a6512 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-cell-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-cell-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-collapsed-border-expected.png
index b86ae61..02d2b110 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-column-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-column-collapsed-border-expected.png
index 7dcb611..9f1ee845 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-column-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-column-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-column-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-column-expected.png
index eaf2d2e1..77fdce6 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-column-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-column-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-column-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-column-group-collapsed-border-expected.png
index 4285920..975b8d03 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-column-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-column-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-column-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-column-group-expected.png
index 59a5db8e..65acf813 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-column-group-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-column-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-expected.png
index c39693a..202652bb 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-quirks-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-quirks-collapsed-border-expected.png
index 4d33c01..523fe9e 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-quirks-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-quirks-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-quirks-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-quirks-expected.png
index 2880f09..fe0322f 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-quirks-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-quirks-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-row-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-row-collapsed-border-expected.png
index ed07ff1..4891242 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-row-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-row-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-row-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-row-expected.png
index 620b0cf..261f23e 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-row-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-row-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-row-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-row-group-collapsed-border-expected.png
index 8a2cdd5..7df742e 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-row-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-row-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-row-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-row-group-expected.png
index 1b9db53..d8eb459 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-row-group-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_border-table-row-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_layers-hide-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_layers-hide-collapsed-border-expected.png
index 64a186f..abf36394 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_layers-hide-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_layers-hide-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_layers-hide-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_layers-hide-expected.png
index 2b8e2b3..b91877f 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_layers-hide-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_layers-hide-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-cell-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-cell-collapsed-border-expected.png
index abe4753..a9b0063 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-cell-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-cell-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-cell-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-cell-expected.png
index cd87e477..19c3ffde 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-cell-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-cell-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-collapsed-border-expected.png
index a882d703..f242a6c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-column-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-column-collapsed-border-expected.png
index f64d8ea..5e37186d 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-column-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-column-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-column-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-column-expected.png
index 2c543f9f..445938af4 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-column-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-column-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-column-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-column-group-collapsed-border-expected.png
index 95aeea4..db47f1bc 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-column-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-column-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-column-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-column-group-expected.png
index ef1502c..545922f 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-column-group-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-column-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-expected.png
index 79e773e..7cb9d4c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-row-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-row-collapsed-border-expected.png
index fe96405..5a6c7f31 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-row-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-row-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-row-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-row-expected.png
index 09640fe8..782e5e0 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-row-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-row-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-row-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-row-group-collapsed-border-expected.png
index cbde8c2..0c5d6965 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-row-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-row-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-row-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-row-group-expected.png
index 1c0ce1e..35d05f7 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-row-group-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_position-table-row-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-cell-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
index c2faf54..7784140e 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-cell-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-cell-expected.png
index 73c740d..463591e 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-cell-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-cell-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-collapsed-border-expected.png
index 4cf080d2c..186b07b 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-collapsed-border-expected.png
index 6b9143a..9a151a5 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-expected.png
index 543042c..1d4af9b2 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
index 81456061..b7f45d0 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-group-expected.png
index 7cec1d8..aa3ac26 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-group-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-expected.png
index 024b62f..96f9663 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-collapsed-border-expected.png
index b4aa2f4..bd5aecd 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-expected.png
index 7a75624..f258886 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
index d8ae2f6..f25bdad 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-group-expected.png
index 89fca61..cea8c892 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-group-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/border-collapsing/001-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/border-collapsing/001-expected.png
index ba5b13d8..45823dc 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/border-collapsing/001-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/border-collapsing/001-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/border-collapsing/001-vertical-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/border-collapsing/001-vertical-expected.png
index 5553778..4596775 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/border-collapsing/001-vertical-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/border-collapsing/001-vertical-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/border-radius-style-001-expected.png b/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/border-radius-style-001-expected.png
index f6f7dbf4..9483302 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/border-radius-style-001-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/border-radius-style-001-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/layer-child-outline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/layer-child-outline-expected.png
index 88e00e59..d15a3d63 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/layer-child-outline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/layer-child-outline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/table-cell-vertical-overflow-expected.png b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/table-cell-vertical-overflow-expected.png
deleted file mode 100644
index fc96e112..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/table-cell-vertical-overflow-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/custom/no-inherited-dashed-stroke-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/custom/no-inherited-dashed-stroke-expected.png
index db05196..ed297e6b 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/svg/custom/no-inherited-dashed-stroke-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/svg/custom/no-inherited-dashed-stroke-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
index a62c20d..20d9f95 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-spinvalidation/paint/invalidation/layer-child-outline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-spinvalidation/paint/invalidation/layer-child-outline-expected.png
index 88e00e59..d15a3d63 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-spinvalidation/paint/invalidation/layer-child-outline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/disable-spinvalidation/paint/invalidation/layer-child-outline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_style-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_style-expected.png
new file mode 100644
index 0000000..ade8054
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_style-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/stable/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/stable/webexposed/global-interface-listing-expected.txt
index 4b46d00c..a75dd6e 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/stable/webexposed/global-interface-listing-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/stable/webexposed/global-interface-listing-expected.txt
@@ -7599,6 +7599,7 @@
     getter onwebkitanimationstart
     getter onwebkittransitionend
     getter onwheel
+    getter origin
     getter outerHeight
     getter outerWidth
     getter pageXOffset
@@ -7774,6 +7775,7 @@
     setter onwebkitanimationstart
     setter onwebkittransitionend
     setter onwheel
+    setter origin
     setter outerHeight
     setter outerWidth
     setter pageXOffset
diff --git a/third_party/WebKit/LayoutTests/platform/win/compositing/overflow/border-radius-styles-with-composited-child-expected.png b/third_party/WebKit/LayoutTests/platform/win/compositing/overflow/border-radius-styles-with-composited-child-expected.png
new file mode 100644
index 0000000..4dda4ab
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/compositing/overflow/border-radius-styles-with-composited-child-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_style-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_style-expected.png
index 3cec260..c7145a3 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_style-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_style-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css2.1/t0805-c5517-brdr-s-00-c-expected.png b/third_party/WebKit/LayoutTests/platform/win/css2.1/t0805-c5517-brdr-s-00-c-expected.png
index 3cca8f3..665b34b 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css2.1/t0805-c5517-brdr-s-00-c-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css2.1/t0805-c5517-brdr-s-00-c-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-04-d-expected.png b/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-04-d-expected.png
index 44fb330..a9c62f8 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-04-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-04-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-14-d-expected.png b/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-14-d-expected.png
index e80b0a6..f8ed37a 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-14-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-14-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-24-d-expected.png b/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-24-d-expected.png
index 2465f3c..7644f56 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-24-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-24-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-34-d-expected.png b/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-34-d-expected.png
index 9d652f5..b28f5667 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-34-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-34-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-41-d-expected.png b/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-41-d-expected.png
index f51fa31..a5f2827b 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-41-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-41-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-42-d-expected.png b/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-42-d-expected.png
index 1c66a94..3982111 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-42-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-42-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-43-d-expected.png b/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-43-d-expected.png
index 6348ffa..7a2479c 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-43-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-43-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-44-d-expected.png b/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-44-d-expected.png
index b0c83210..dd40861 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-44-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-44-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-45-d-expected.png b/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-45-d-expected.png
index 78c81c3d..6504a56 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-45-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-45-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-46-d-expected.png b/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-46-d-expected.png
index 1eed2b5..d6867d49 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-46-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-46-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-47-d-expected.png b/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-47-d-expected.png
index 5e6b96a..fa9eaeac 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-47-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-47-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-48-d-expected.png b/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-48-d-expected.png
index 66357e9c..ca2613b0 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-48-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-48-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-49-d-expected.png b/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-49-d-expected.png
index 6cfdf89..e9abae3b 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-49-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-49-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-54-d-expected.png b/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-54-d-expected.png
index cddb39e..31bcac2 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-54-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-54-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-64-d-expected.png b/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-64-d-expected.png
index f918cc1..d3859b12 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-64-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-64-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-74-d-expected.png b/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-74-d-expected.png
index 335e7bf..a10669e 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-74-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-74-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-84-d-expected.png b/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-84-d-expected.png
index 839fc2f..030b765 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-84-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-84-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-94-d-expected.png b/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-94-d-expected.png
index 45ddea16..c6f18a0 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-94-d-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css2.1/t170602-bdr-conflct-w-94-d-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/borders/borderRadiusAllStylesAllCorners-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/borders/borderRadiusAllStylesAllCorners-expected.png
index 9f61ecb..abfe4f76 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/borders/borderRadiusAllStylesAllCorners-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/borders/borderRadiusAllStylesAllCorners-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/borders/borderRadiusDashed01-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/borders/borderRadiusDashed01-expected.png
new file mode 100644
index 0000000..cfc557f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/borders/borderRadiusDashed01-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/borders/borderRadiusDashed02-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/borders/borderRadiusDashed02-expected.png
new file mode 100644
index 0000000..24f0ce3a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/borders/borderRadiusDashed02-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/borders/borderRadiusDashed03-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/borders/borderRadiusDashed03-expected.png
new file mode 100644
index 0000000..dd29cce
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/borders/borderRadiusDashed03-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/borders/borderRadiusDashed04-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/borders/borderRadiusDashed04-expected.png
new file mode 100644
index 0000000..50f367a5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/borders/borderRadiusDashed04-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/borders/borderRadiusDashed05-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/borders/borderRadiusDashed05-expected.png
new file mode 100644
index 0000000..d9ac765
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/borders/borderRadiusDashed05-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/borders/borderRadiusDashed06-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/borders/borderRadiusDashed06-expected.png
new file mode 100644
index 0000000..06e8f66
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/borders/borderRadiusDashed06-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/borders/borderRadiusDotted01-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/borders/borderRadiusDotted01-expected.png
new file mode 100644
index 0000000..e60883c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/borders/borderRadiusDotted01-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/borders/borderRadiusDotted04-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/borders/borderRadiusDotted04-expected.png
new file mode 100644
index 0000000..ed9ed195
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/borders/borderRadiusDotted04-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/borders/outline-alpha-block-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/borders/outline-alpha-block-expected.png
index d70a664b..c787adac 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/borders/outline-alpha-block-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/borders/outline-alpha-block-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/borders/outline-alpha-inline-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/borders/outline-alpha-inline-expected.png
index 52d1931..8bcd321 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/borders/outline-alpha-inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/borders/outline-alpha-inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/box-shadow/inset-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/box-shadow/inset-expected.png
index 550ca8cc..d127e00 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/box-shadow/inset-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/box-shadow/inset-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/box-shadow/inset-subpixel-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/box-shadow/inset-subpixel-expected.png
index c45040a..251b561 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/box-shadow/inset-subpixel-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/box-shadow/inset-subpixel-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/layers/opacity-outline-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/layers/opacity-outline-expected.png
index 27064d7..aa2fa4d 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/layers/opacity-outline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/layers/opacity-outline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/overflow/overflow-with-local-background-attachment-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/overflow/overflow-with-local-background-attachment-expected.png
index 7092ff5..ffb1dc0 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/overflow/overflow-with-local-background-attachment-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/overflow/overflow-with-local-background-attachment-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/border-collapsing/001-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/border-collapsing/001-expected.png
index 09c81c7..a1d0ee97 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/table/border-collapsing/001-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/border-collapsing/001-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/border-collapsing/001-vertical-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/border-collapsing/001-vertical-expected.png
index c0855d9..a5c1f0c 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/table/border-collapsing/001-vertical-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/border-collapsing/001-vertical-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/ietestcenter/css3/bordersbackgrounds/border-radius-style-001-expected.png b/third_party/WebKit/LayoutTests/platform/win/ietestcenter/css3/bordersbackgrounds/border-radius-style-001-expected.png
index 0d770620..11af621 100644
--- a/third_party/WebKit/LayoutTests/platform/win/ietestcenter/css3/bordersbackgrounds/border-radius-style-001-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/ietestcenter/css3/bordersbackgrounds/border-radius-style-001-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/ietestcenter/css3/bordersbackgrounds/border-radius-style-002-expected.png b/third_party/WebKit/LayoutTests/platform/win/ietestcenter/css3/bordersbackgrounds/border-radius-style-002-expected.png
index 4afe4e8..858e02d 100644
--- a/third_party/WebKit/LayoutTests/platform/win/ietestcenter/css3/bordersbackgrounds/border-radius-style-002-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/ietestcenter/css3/bordersbackgrounds/border-radius-style-002-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/layer-child-outline-expected.png b/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/layer-child-outline-expected.png
index c98b5433..7344b8d 100644
--- a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/layer-child-outline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/layer-child-outline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/table-cell-vertical-overflow-expected.png b/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/table-cell-vertical-overflow-expected.png
deleted file mode 100644
index 870cfc83..0000000
--- a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/table-cell-vertical-overflow-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/custom/no-inherited-dashed-stroke-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/custom/no-inherited-dashed-stroke-expected.png
index 42913617..e22ab81 100644
--- a/third_party/WebKit/LayoutTests/platform/win/svg/custom/no-inherited-dashed-stroke-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/svg/custom/no-inherited-dashed-stroke-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
index 20645fd9..a3f7fea 100644
--- a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/disable-spinvalidation/paint/invalidation/layer-child-outline-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/disable-spinvalidation/paint/invalidation/layer-child-outline-expected.png
index c98b5433..7344b8d 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/disable-spinvalidation/paint/invalidation/layer-child-outline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/disable-spinvalidation/paint/invalidation/layer-child-outline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/canvas-arc-circumference-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/canvas-arc-circumference-expected.png
new file mode 100644
index 0000000..285f605
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/canvas-arc-circumference-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/canvas-arc-circumference-fill-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/canvas-arc-circumference-fill-expected.png
index f1d41e6..411b819 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/canvas-arc-circumference-fill-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/canvas-arc-circumference-fill-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/canvas-ellipse-circumference-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/canvas-ellipse-circumference-expected.png
new file mode 100644
index 0000000..9f0bf823
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/canvas-ellipse-circumference-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/canvas-ellipse-circumference-fill-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/canvas-ellipse-circumference-fill-expected.png
new file mode 100644
index 0000000..ce87211
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/canvas-ellipse-circumference-fill-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/canvas-incremental-repaint-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/canvas-incremental-repaint-expected.png
index 54a21f4b..98bafae 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/canvas-incremental-repaint-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/canvas-incremental-repaint-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_style-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_style-expected.png
new file mode 100644
index 0000000..c7145a3
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_style-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/prefer_compositing_to_lcd_text/compositing/overflow/border-radius-styles-with-composited-child-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/prefer_compositing_to_lcd_text/compositing/overflow/border-radius-styles-with-composited-child-expected.png
new file mode 100644
index 0000000..4dda4ab
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/prefer_compositing_to_lcd_text/compositing/overflow/border-radius-styles-with-composited-child-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/stable/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/platform/win/virtual/stable/webexposed/global-interface-listing-expected.txt
index e431e54..0053cec5 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/stable/webexposed/global-interface-listing-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/stable/webexposed/global-interface-listing-expected.txt
@@ -7527,6 +7527,7 @@
     getter onwebkitanimationstart
     getter onwebkittransitionend
     getter onwheel
+    getter origin
     getter outerHeight
     getter outerWidth
     getter pageXOffset
@@ -7702,6 +7703,7 @@
     setter onwebkitanimationstart
     setter onwebkittransitionend
     setter onwheel
+    setter origin
     setter outerHeight
     setter outerWidth
     setter pageXOffset
diff --git a/third_party/WebKit/LayoutTests/platform/win7/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png b/third_party/WebKit/LayoutTests/platform/win7/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
index 6e9e165..abe417d 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/resources/bluetooth/heart-rate-two-iframes.html b/third_party/WebKit/LayoutTests/resources/bluetooth/heart-rate-two-iframes.html
index fe4f46c..91f7a98 100644
--- a/third_party/WebKit/LayoutTests/resources/bluetooth/heart-rate-two-iframes.html
+++ b/third_party/WebKit/LayoutTests/resources/bluetooth/heart-rate-two-iframes.html
@@ -10,23 +10,36 @@
       .then(device => device.gatt.connect())
       .then(gattServer => {
         // iframe1 can access heart_rate service.
-        gattServer.getPrimaryService('heart_rate');
+        return gattServer.getPrimaryService('heart_rate');
+      }).then(() => {
         parent.postMessage('Iframe1Connected', '*');
       }).catch(err => {
         console.error(err);
         parent.postMessage('FAIL: ' + err, '*');
       });
+    } else if (messageEvent.data === 'Iframe1TryAccessGenericAccessService') {
+      navigator.bluetooth.requestDevice({
+        filters: [{services: ['heart_rate']}]
+      })
+      .then(device => device.gatt.connect())
+      .then(gattServer => {
+        // iframe1 can not access generic_access service.
+        return gattServer.getPrimaryService('generic_access');
+      }).catch(err => {
+        parent.postMessage('Iframe1AccessGenericAccessServiceFailed', '*');
+      });
     } else if (messageEvent.data === 'Iframe2RequestAndConnect') {
       navigator.bluetooth.requestDevice({
         filters: [{services: ['generic_access']}]
       })
       .then(device => device.gatt.connect())
       .then(gattServer => {
-        gattServer.getPrimaryService('generic_access');
         // Since iframe1 can access heart_rate service, and iframe2 has the
         // same origin as iframe1, iframe2 should also be able to access
         // heart_rate service.
-        gattServer.getPrimaryService('heart_rate');
+        return Promise.all([gattServer.getPrimaryService('generic_access'),
+          gattServer.getPrimaryService('heart_rate')]);
+      }).then(() => {
         parent.postMessage('Iframe2Connected', '*');
       }).catch(err => {
         console.error(err);
@@ -41,7 +54,8 @@
         // Since iframe2 can access generic_access service, and iframe1 has the
         // same origin as iframe2, iframe1 should also be able to access
         // generic_access service.
-        gattServer.getPrimaryService('generic_access');
+        return gattServer.getPrimaryService('generic_access');
+      }).then(() => {
         parent.postMessage('DoneTest', '*');
       }).catch(err => {
         console.error(err);
diff --git a/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
index 1db384c..ef85d30 100644
--- a/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/virtual/service-worker-navigation-preload/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -2187,6 +2187,7 @@
     getter onerror
     getter onrejectionhandled
     getter onunhandledrejection
+    getter origin
     getter performance
     getter self
     method atob
@@ -2202,6 +2203,7 @@
     setter onerror
     setter onrejectionhandled
     setter onunhandledrejection
+    setter origin
 interface WorkerLocation
     getter hash
     getter host
diff --git a/third_party/WebKit/LayoutTests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/WebKit/LayoutTests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
index 04d3d68..041a2cfe 100644
--- a/third_party/WebKit/LayoutTests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -644,6 +644,7 @@
     getter onerror
     getter onrejectionhandled
     getter onunhandledrejection
+    getter origin
     getter performance
     getter self
     method atob
@@ -659,6 +660,7 @@
     setter onerror
     setter onrejectionhandled
     setter onunhandledrejection
+    setter origin
 interface WorkerLocation
     getter hash
     getter host
diff --git a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/css-properties-as-js-properties-expected.txt b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/css-properties-as-js-properties-expected.txt
index f4f541d..b4247c98 100644
--- a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/css-properties-as-js-properties-expected.txt
+++ b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/css-properties-as-js-properties-expected.txt
@@ -226,6 +226,7 @@
 parentRule
 perspective
 perspectiveOrigin
+placeContent
 pointerEvents
 position
 quotes
diff --git a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt
index e65ab97..dbbc460 100644
--- a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt
@@ -646,6 +646,7 @@
 [Worker]     getter onerror
 [Worker]     getter onrejectionhandled
 [Worker]     getter onunhandledrejection
+[Worker]     getter origin
 [Worker]     getter performance
 [Worker]     getter self
 [Worker]     method atob
@@ -661,6 +662,7 @@
 [Worker]     setter onerror
 [Worker]     setter onrejectionhandled
 [Worker]     setter onunhandledrejection
+[Worker]     setter origin
 [Worker] interface WorkerLocation
 [Worker]     attribute @@toStringTag
 [Worker]     getter hash
diff --git a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt
index 0928ce5..73ba7bf 100644
--- a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt
@@ -646,6 +646,7 @@
 [Worker]     getter onerror
 [Worker]     getter onrejectionhandled
 [Worker]     getter onunhandledrejection
+[Worker]     getter origin
 [Worker]     getter performance
 [Worker]     getter self
 [Worker]     method atob
@@ -661,6 +662,7 @@
 [Worker]     setter onerror
 [Worker]     setter onrejectionhandled
 [Worker]     setter onunhandledrejection
+[Worker]     setter origin
 [Worker] interface WorkerLocation
 [Worker]     attribute @@toStringTag
 [Worker]     getter hash
diff --git a/third_party/WebKit/LayoutTests/webexposed/css-properties-as-js-properties-expected.txt b/third_party/WebKit/LayoutTests/webexposed/css-properties-as-js-properties-expected.txt
index 41ca12bc..11bfac0 100644
--- a/third_party/WebKit/LayoutTests/webexposed/css-properties-as-js-properties-expected.txt
+++ b/third_party/WebKit/LayoutTests/webexposed/css-properties-as-js-properties-expected.txt
@@ -234,6 +234,7 @@
 parentRule
 perspective
 perspectiveOrigin
+placeContent
 pointerEvents
 position
 quotes
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt
index 76c8ece..9660576c 100644
--- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt
@@ -2192,6 +2192,7 @@
 [Worker]     getter onerror
 [Worker]     getter onrejectionhandled
 [Worker]     getter onunhandledrejection
+[Worker]     getter origin
 [Worker]     getter performance
 [Worker]     getter self
 [Worker]     method atob
@@ -2207,6 +2208,7 @@
 [Worker]     setter onerror
 [Worker]     setter onrejectionhandled
 [Worker]     setter onunhandledrejection
+[Worker]     setter origin
 [Worker] interface WorkerLocation
 [Worker]     attribute @@toStringTag
 [Worker]     getter hash
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 2653d2b..31fb26a 100644
--- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
+++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -8871,6 +8871,7 @@
     getter onwebkitanimationstart
     getter onwebkittransitionend
     getter onwheel
+    getter origin
     getter outerHeight
     getter outerWidth
     getter pageXOffset
@@ -9050,6 +9051,7 @@
     setter onwebkitanimationstart
     setter onwebkittransitionend
     setter onwheel
+    setter origin
     setter outerHeight
     setter outerWidth
     setter pageXOffset
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt
index 2b59c05..9d8c96f3 100644
--- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt
@@ -2192,6 +2192,7 @@
 [Worker]     getter onerror
 [Worker]     getter onrejectionhandled
 [Worker]     getter onunhandledrejection
+[Worker]     getter origin
 [Worker]     getter performance
 [Worker]     getter self
 [Worker]     method atob
@@ -2207,6 +2208,7 @@
 [Worker]     setter onerror
 [Worker]     setter onrejectionhandled
 [Worker]     setter onunhandledrejection
+[Worker]     setter origin
 [Worker] interface WorkerLocation
 [Worker]     attribute @@toStringTag
 [Worker]     getter hash
diff --git a/third_party/WebKit/PerformanceTests/Editing/delete-in-password-field.html b/third_party/WebKit/PerformanceTests/Editing/delete-in-password-field.html
new file mode 100644
index 0000000..c5c5a9d
--- /dev/null
+++ b/third_party/WebKit/PerformanceTests/Editing/delete-in-password-field.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<script src="../resources/runner.js"></script>
+<div id="hidden" style="height:0px; overflow:hidden;"></div>
+<input type="password">
+<script>
+const kCount = 100;
+const hidden = document.getElementById('hidden');
+const password = document.querySelector('input[type=password]');
+hidden.innerHTML= '<p>foo bar</p>'.repeat(999);
+
+PerfTestRunner.measureTime({
+  description: 'Measures performance of delete in password field with many hidden elements',
+  setup: () => {
+    password.value = 'x'.repeat(kCount);
+    password.focus();
+  },
+  run: () => {
+    for (let counter = 0; counter < kCount; ++counter)
+      document.execCommand('delete');
+  },
+});
+</script>
diff --git a/third_party/WebKit/PerformanceTests/Editing/move-down-with-hidden-elements.html b/third_party/WebKit/PerformanceTests/Editing/move-down-with-hidden-elements.html
index 17b86fd..69de6a9 100644
--- a/third_party/WebKit/PerformanceTests/Editing/move-down-with-hidden-elements.html
+++ b/third_party/WebKit/PerformanceTests/Editing/move-down-with-hidden-elements.html
@@ -2,7 +2,6 @@
 <script src="../resources/runner.js"></script>
 <div id="sample"></div>
 <script>
-const kCount = 10;
 const kElements = 10000;
 
 const metaElements = (() => {
@@ -13,21 +12,25 @@
 })();
 const sample = document.getElementById('sample');
 sample.innerHTML =   [
-  '<div hiddent>', ...metaElements, '</div>',
-  '<h1 id="target">first line of renderered text</h1>',
-  '<div hiddent>', ...metaElements, '</div>',
+  '<h1 id="before">first line of renderered text</h1>',
+  '<div hidden>', ...metaElements, '</div>',
+  '<h1 id="target">second line of renderered text</h1>',
+  '<div hidden>', ...metaElements, '</div>',
+  '<h1 id="after">third line of renderered text</h1>',
 ].join('');
 
 const selection = window.getSelection();
-const target = document.getElementById('target');
 
-PerfTestRunner.measureRunsPerSecond({
+PerfTestRunner.measureTime({
   description: 'Measures performance of move-down through non-renderered elements',
+  setup: () => {
+    selection.removeAllRanges();
+    const target = document.getElementById('target');
+    selection.collapse(target.firstChild, 5);
+    selection.extend(target.firstChild, 10);
+  },
   run: () => {
-    selection.collapse(target, 0);
-    selection.extend(target, target.childNodes.length);
-    for (let counter = 0; counter < kCount; ++counter)
-      selection.modify('move', 'forward', 'line');
-    },
+    selection.modify('extend', 'forward', 'line');
+  },
 });
 </script>
diff --git a/third_party/WebKit/PerformanceTests/Editing/move-up-with-hidden-elements.html b/third_party/WebKit/PerformanceTests/Editing/move-up-with-hidden-elements.html
index b2def76..17891155 100644
--- a/third_party/WebKit/PerformanceTests/Editing/move-up-with-hidden-elements.html
+++ b/third_party/WebKit/PerformanceTests/Editing/move-up-with-hidden-elements.html
@@ -2,7 +2,6 @@
 <script src="../resources/runner.js"></script>
 <div id="sample"></div>
 <script>
-const kCount = 10;
 const kElements = 10000;
 
 const metaElements = (() => {
@@ -13,21 +12,25 @@
 })();
 const sample = document.getElementById('sample');
 sample.innerHTML =   [
-  '<div hiddent>', ...metaElements, '</div>',
-  '<h1 id="target">first line of renderered text</h1>',
-  '<div hiddent>', ...metaElements, '</div>',
+  '<h1 id="before">first line of renderered text</h1>',
+  '<div hidden>', ...metaElements, '</div>',
+  '<h1 id="target">second line of renderered text</h1>',
+  '<div hidden>', ...metaElements, '</div>',
+  '<h1 id="after">third line of renderered text</h1>',
 ].join('');
 
 const selection = window.getSelection();
-const target = document.getElementById('target');
 
-PerfTestRunner.measureRunsPerSecond({
+PerfTestRunner.measureTime({
   description: 'Measures performance of move-up through non-renderered elements',
+  setup: () => {
+    selection.removeAllRanges();
+    const target = document.getElementById('target');
+    selection.collapse(target.firstChild, 5);
+    selection.extend(target.firstChild, 10);
+  },
   run: () => {
-    selection.collapse(target, 0);
-    selection.extend(target, target.childNodes.length);
-    for (let counter = 0; counter < kCount; ++counter)
-      selection.modify('move', 'backward', 'line');
-    },
+    selection.modify('extend', 'backward', 'line');
+  },
 });
 </script>
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScheduledAction.cpp b/third_party/WebKit/Source/bindings/core/v8/ScheduledAction.cpp
index 1f40c6b..c889703 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScheduledAction.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/ScheduledAction.cpp
@@ -40,6 +40,7 @@
 #include "core/dom/Document.h"
 #include "core/dom/ExecutionContext.h"
 #include "core/frame/LocalFrame.h"
+#include "core/frame/UseCounter.h"
 #include "core/workers/WorkerGlobalScope.h"
 #include "core/workers/WorkerThread.h"
 #include "platform/instrumentation/tracing/TraceEvent.h"
@@ -52,9 +53,13 @@
                                          const Vector<ScriptValue>& arguments) {
   ASSERT(handler.isFunction());
   if (!scriptState->world().isWorkerWorld()) {
-    DCHECK(BindingSecurity::shouldAllowAccessToFrame(
-        enteredDOMWindow(scriptState->isolate()), toDocument(target)->frame(),
-        BindingSecurity::ErrorReportOption::DoNotReport));
+    if (!BindingSecurity::shouldAllowAccessToFrame(
+            enteredOrMicrotaskDOMWindow(scriptState->isolate()),
+            toDocument(target)->frame(),
+            BindingSecurity::ErrorReportOption::DoNotReport)) {
+      UseCounter::count(target, UseCounter::ScheduledActionIgnored);
+      return new ScheduledAction(scriptState);
+    }
   }
   return new ScheduledAction(scriptState, handler, arguments);
 }
@@ -63,9 +68,13 @@
                                          ExecutionContext* target,
                                          const String& handler) {
   if (!scriptState->world().isWorkerWorld()) {
-    DCHECK(BindingSecurity::shouldAllowAccessToFrame(
-        enteredDOMWindow(scriptState->isolate()), toDocument(target)->frame(),
-        BindingSecurity::ErrorReportOption::DoNotReport));
+    if (!BindingSecurity::shouldAllowAccessToFrame(
+            enteredOrMicrotaskDOMWindow(scriptState->isolate()),
+            toDocument(target)->frame(),
+            BindingSecurity::ErrorReportOption::DoNotReport)) {
+      UseCounter::count(target, UseCounter::ScheduledActionIgnored);
+      return new ScheduledAction(scriptState);
+    }
   }
   return new ScheduledAction(scriptState, handler);
 }
@@ -124,6 +133,11 @@
       m_info(scriptState->isolate()),
       m_code(code, KURL()) {}
 
+ScheduledAction::ScheduledAction(ScriptState* scriptState)
+    : m_scriptState(scriptState),
+      m_info(scriptState->isolate()),
+      m_code(String(), KURL()) {}
+
 void ScheduledAction::execute(LocalFrame* frame) {
   if (!m_scriptState->contextIsValid()) {
     DVLOG(1) << "ScheduledAction::execute " << this << ": context is empty";
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScheduledAction.h b/third_party/WebKit/Source/bindings/core/v8/ScheduledAction.h
index f5385b3..13656a6 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScheduledAction.h
+++ b/third_party/WebKit/Source/bindings/core/v8/ScheduledAction.h
@@ -71,6 +71,9 @@
                   const Vector<ScriptValue>& arguments);
   ScheduledAction(ScriptState*, const String& handler);
 
+  // Creates an empty ScheduledAction.
+  explicit ScheduledAction(ScriptState*);
+
   void execute(LocalFrame*);
   void execute(WorkerGlobalScope*);
   void createLocalHandlesForArgs(Vector<v8::Local<v8::Value>>* handles);
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8Binding.cpp b/third_party/WebKit/Source/bindings/core/v8/V8Binding.cpp
index 0ccf6f2..fb93c17 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8Binding.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/V8Binding.cpp
@@ -733,13 +733,21 @@
     //
     // TODO(haraken): It's nasty to return a current window from
     // enteredDOMWindow.  All call sites should be updated so that it works even
-    // if it doesn't have an entered window.
+    // if it doesn't have an entered window. Consider using
+    // enteredOrMicrotaskDOMWindow everywhere.
     window = currentDOMWindow(isolate);
     ASSERT(window);
   }
   return window;
 }
 
+LocalDOMWindow* enteredOrMicrotaskDOMWindow(v8::Isolate* isolate) {
+  LocalDOMWindow* window =
+      toLocalDOMWindow(toDOMWindow(isolate->GetEnteredOrMicrotaskContext()));
+  DCHECK(window);
+  return window;
+}
+
 LocalDOMWindow* currentDOMWindow(v8::Isolate* isolate) {
   return toLocalDOMWindow(toDOMWindow(isolate->GetCurrentContext()));
 }
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8Binding.h b/third_party/WebKit/Source/bindings/core/v8/V8Binding.h
index 1df7fae..eccefd0 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8Binding.h
+++ b/third_party/WebKit/Source/bindings/core/v8/V8Binding.h
@@ -997,6 +997,9 @@
 CORE_EXPORT DOMWindow* toDOMWindow(v8::Isolate*, v8::Local<v8::Value>);
 DOMWindow* toDOMWindow(v8::Local<v8::Context>);
 LocalDOMWindow* enteredDOMWindow(v8::Isolate*);
+// Returns the last entered context, or the context of the currently running
+// microtask if no entered context is higher up on the stack.
+LocalDOMWindow* enteredOrMicrotaskDOMWindow(v8::Isolate*);
 CORE_EXPORT LocalDOMWindow* currentDOMWindow(v8::Isolate*);
 CORE_EXPORT ExecutionContext* toExecutionContext(v8::Local<v8::Context>);
 CORE_EXPORT void registerToExecutionContextForModules(
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8MutationCallback.cpp b/third_party/WebKit/Source/bindings/core/v8/V8MutationCallback.cpp
index 61c0d76..ef5563b 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8MutationCallback.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/V8MutationCallback.cpp
@@ -39,10 +39,10 @@
 V8MutationCallback::V8MutationCallback(v8::Local<v8::Function> callback,
                                        v8::Local<v8::Object> owner,
                                        ScriptState* scriptState)
-    : m_callback(scriptState->isolate(), callback), m_scriptState(scriptState) {
+    : m_callback(scriptState->isolate(), this, callback),
+      m_scriptState(scriptState) {
   V8PrivateProperty::getMutationObserverCallback(scriptState->isolate())
       .set(scriptState->context(), owner, callback);
-  m_callback.setPhantom();
 }
 
 V8MutationCallback::~V8MutationCallback() {}
@@ -85,4 +85,9 @@
   MutationCallback::trace(visitor);
 }
 
+DEFINE_TRACE_WRAPPERS(V8MutationCallback) {
+  visitor->traceWrappers(m_callback.cast<v8::Value>());
+  MutationCallback::traceWrappers(visitor);
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8MutationCallback.h b/third_party/WebKit/Source/bindings/core/v8/V8MutationCallback.h
index ebbf26c..8bee001 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8MutationCallback.h
+++ b/third_party/WebKit/Source/bindings/core/v8/V8MutationCallback.h
@@ -28,6 +28,7 @@
 
 #include "bindings/core/v8/ScopedPersistent.h"
 #include "bindings/core/v8/ScriptState.h"
+#include "bindings/core/v8/TraceWrapperV8Reference.h"
 #include "core/dom/MutationCallback.h"
 #include "v8/include/v8.h"
 #include "wtf/RefPtr.h"
@@ -53,13 +54,14 @@
   }
 
   DECLARE_VIRTUAL_TRACE();
+  DECLARE_VIRTUAL_TRACE_WRAPPERS();
 
  private:
   V8MutationCallback(v8::Local<v8::Function>,
                      v8::Local<v8::Object>,
                      ScriptState*);
 
-  ScopedPersistent<v8::Function> m_callback;
+  TraceWrapperV8Reference<v8::Function> m_callback;
   RefPtr<ScriptState> m_scriptState;
 };
 
diff --git a/third_party/WebKit/Source/bindings/core/v8/WindowProxy.cpp b/third_party/WebKit/Source/bindings/core/v8/WindowProxy.cpp
index 4a31146..67d3a44 100644
--- a/third_party/WebKit/Source/bindings/core/v8/WindowProxy.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/WindowProxy.cpp
@@ -33,9 +33,11 @@
 #include <utility>
 
 #include "bindings/core/v8/V8DOMWrapper.h"
+#include "bindings/core/v8/V8Window.h"
 #include "core/frame/Frame.h"
 #include "v8/include/v8.h"
 #include "wtf/Assertions.h"
+#include "wtf/debug/Alias.h"
 
 namespace blink {
 
@@ -130,11 +132,40 @@
 // If there are JS code holds a closure to the old inner window,
 // it won't be able to reach the outer window via its global object.
 void WindowProxy::initializeIfNeeded() {
+  v8::HandleScope handleScope(m_isolate);
+  Lifecycle oldLifecycle = m_lifecycle;
+  DOMWindow* window = m_frame->domWindow();
+  bool isLocal = window->isLocalDOMWindow();
+  // Prevent these locals from getting optimized out, and hopefully, the heap
+  // contents captured into minidumps.
+  WTF::debug::alias(&oldLifecycle);
+  WTF::debug::alias(&window);
+  WTF::debug::alias(&isLocal);
+
   // TODO(haraken): It is wrong to re-initialize an already detached window
   // proxy. This must be 'if(m_lifecycle == Lifecycle::ContextUninitialized)'.
   if (m_lifecycle != Lifecycle::ContextInitialized) {
     initialize();
+    // Note: this set of CHECKs is intentionally duplicated below to distinguish
+    // between initializing the global with null internal fields or returning a
+    // global that claims to be initialized but has null internal fields.
+    v8::Local<v8::Object> globalProxy = m_globalProxy.newLocal(m_isolate);
+    CHECK(!globalProxy.IsEmpty());
+    CHECK(V8Window::hasInstance(globalProxy, m_isolate));
+    CHECK(window);
+    CHECK_EQ(window, V8Window::toImpl(globalProxy));
+  } else {
+    v8::Local<v8::Object> globalProxy = m_globalProxy.newLocal(m_isolate);
+    CHECK(!globalProxy.IsEmpty());
+    CHECK(V8Window::hasInstance(globalProxy, m_isolate));
+    CHECK(window);
+    CHECK_EQ(window, V8Window::toImpl(globalProxy));
   }
+
+  // Sanity check: WindowProxy's frame's window should still be the same
+  DOMWindow* window2 = m_frame->domWindow();
+  WTF::debug::alias(&window2);
+  CHECK_EQ(window, window2);
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/bindings/core/v8/serialization/V8ScriptValueDeserializer.cpp b/third_party/WebKit/Source/bindings/core/v8/serialization/V8ScriptValueDeserializer.cpp
index 726030fe..516ec90 100644
--- a/third_party/WebKit/Source/bindings/core/v8/serialization/V8ScriptValueDeserializer.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/serialization/V8ScriptValueDeserializer.cpp
@@ -54,7 +54,7 @@
   unsigned shift = 0;
   bool hasAnotherByte;
   do {
-    if (i > length)
+    if (i >= length)
       return 0;
     uint8_t byte = rawData[i];
     if (LIKELY(shift < 32)) {
diff --git a/third_party/WebKit/Source/bindings/scripts/v8_types.py b/third_party/WebKit/Source/bindings/scripts/v8_types.py
index a42e270..d3e2114 100644
--- a/third_party/WebKit/Source/bindings/scripts/v8_types.py
+++ b/third_party/WebKit/Source/bindings/scripts/v8_types.py
@@ -96,20 +96,17 @@
 CPP_TYPE_SAME_AS_IDL_TYPE = set([
     'double',
     'float',
-    'long long',
-    'unsigned long long',
 ])
-CPP_INT_TYPES = set([
-    'byte',
-    'long',
-    'short',
-])
-CPP_UNSIGNED_TYPES = set([
-    'octet',
-    'unsigned int',
-    'unsigned long',
-    'unsigned short',
-])
+CPP_INTEGER_CONVERSION_RULES = {
+    'byte': 'int8_t',
+    'octet': 'uint8_t',
+    'short': 'int16_t',
+    'unsigned short': 'uint16_t',
+    'long': 'int32_t',
+    'unsigned long': 'uint32_t',
+    'long long': 'int64_t',
+    'unsigned long long': 'uint64_t',
+}
 CPP_SPECIAL_CONVERSION_RULES = {
     'Date': 'double',
     'Dictionary': 'Dictionary',
@@ -174,10 +171,8 @@
 
     if base_idl_type in CPP_TYPE_SAME_AS_IDL_TYPE:
         return base_idl_type
-    if base_idl_type in CPP_INT_TYPES:
-        return 'int'
-    if base_idl_type in CPP_UNSIGNED_TYPES:
-        return 'unsigned'
+    if base_idl_type in CPP_INTEGER_CONVERSION_RULES:
+        return CPP_INTEGER_CONVERSION_RULES[base_idl_type]
     if base_idl_type in CPP_SPECIAL_CONVERSION_RULES:
         return CPP_SPECIAL_CONVERSION_RULES[base_idl_type]
 
@@ -758,10 +753,8 @@
     # Simple types
     base_idl_type = idl_type.base_type
     # Basic types, without additional includes
-    if base_idl_type in CPP_INT_TYPES:
-        return 'int'
-    if base_idl_type in CPP_UNSIGNED_TYPES:
-        return 'unsigned'
+    if base_idl_type in CPP_INTEGER_CONVERSION_RULES:
+        return CPP_INTEGER_CONVERSION_RULES[base_idl_type]
     if idl_type.is_string_type:
         if idl_type.is_nullable:
             return 'StringOrNull'
@@ -784,13 +777,20 @@
 
 V8_SET_RETURN_VALUE = {
     'boolean': 'v8SetReturnValueBool(info, {cpp_value})',
-    'int': 'v8SetReturnValueInt(info, {cpp_value})',
-    'unsigned': 'v8SetReturnValueUnsigned(info, {cpp_value})',
     'DOMString': 'v8SetReturnValueString(info, {cpp_value}, info.GetIsolate())',
     'ByteString': 'v8SetReturnValueString(info, {cpp_value}, info.GetIsolate())',
     'USVString': 'v8SetReturnValueString(info, {cpp_value}, info.GetIsolate())',
     'StringOrNull': 'v8SetReturnValueStringOrNull(info, {cpp_value}, info.GetIsolate())',
     'void': '',
+    # All the int types below are converted to (u)int32_t in the v8SetReturnValue{Int,Unsigned}() calls.
+    # The 64-bit int types have already been converted to double when V8_SET_RETURN_VALUE is used, so they are not
+    # listed here.
+    'int8_t': 'v8SetReturnValueInt(info, {cpp_value})',
+    'int16_t': 'v8SetReturnValueInt(info, {cpp_value})',
+    'int32_t': 'v8SetReturnValueInt(info, {cpp_value})',
+    'uint8_t': 'v8SetReturnValueUnsigned(info, {cpp_value})',
+    'uint16_t': 'v8SetReturnValueUnsigned(info, {cpp_value})',
+    'uint32_t': 'v8SetReturnValueUnsigned(info, {cpp_value})',
     # No special v8SetReturnValue* function (set value directly)
     'float': 'v8SetReturnValue(info, {cpp_value})',
     'unrestricted float': 'v8SetReturnValue(info, {cpp_value})',
@@ -883,8 +883,15 @@
     'ByteString': 'v8String({isolate}, {cpp_value})',
     'USVString': 'v8String({isolate}, {cpp_value})',
     'boolean': 'v8Boolean({cpp_value}, {isolate})',
-    'int': 'v8::Integer::New({isolate}, {cpp_value})',
-    'unsigned': 'v8::Integer::NewFromUnsigned({isolate}, {cpp_value})',
+    # All the int types below are converted to (u)int32_t in the v8::Integer::New*() calls.
+    # The 64-bit int types have already been converted to double when CPP_VALUE_TO_V8_VALUE is used, so they are not
+    # listed here.
+    'int8_t': 'v8::Integer::New({isolate}, {cpp_value})',
+    'int16_t': 'v8::Integer::New({isolate}, {cpp_value})',
+    'int32_t': 'v8::Integer::New({isolate}, {cpp_value})',
+    'uint8_t': 'v8::Integer::NewFromUnsigned({isolate}, {cpp_value})',
+    'uint16_t': 'v8::Integer::NewFromUnsigned({isolate}, {cpp_value})',
+    'uint32_t': 'v8::Integer::NewFromUnsigned({isolate}, {cpp_value})',
     'float': 'v8::Number::New({isolate}, {cpp_value})',
     'unrestricted float': 'v8::Number::New({isolate}, {cpp_value})',
     'double': 'v8::Number::New({isolate}, {cpp_value})',
@@ -936,7 +943,7 @@
     if idl_type.base_type in ('any', 'object') and idl_literal.is_null:
         return 'ScriptValue()'
     literal_value = str(idl_literal)
-    if idl_type.base_type in CPP_UNSIGNED_TYPES:
+    if idl_type.base_type in ('octet', 'unsigned short', 'unsigned long'):
         return literal_value + 'u'
     return literal_value
 
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/LongCallbackFunction.cpp b/third_party/WebKit/Source/bindings/tests/results/core/LongCallbackFunction.cpp
index fd812d8e..bd4c57b 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/LongCallbackFunction.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/LongCallbackFunction.cpp
@@ -40,7 +40,7 @@
   visitor->traceWrappers(m_callback.cast<v8::Value>());
 }
 
-bool LongCallbackFunction::call(ScriptWrappable* scriptWrappable, int num1, int num2, int& returnValue) {
+bool LongCallbackFunction::call(ScriptWrappable* scriptWrappable, int32_t num1, int32_t num2, int32_t& returnValue) {
   if (!m_scriptState->contextIsValid())
     return false;
 
@@ -69,7 +69,7 @@
   exceptionCatcher.SetVerbose(true);
 
   if (V8ScriptRunner::callFunction(m_callback.newLocal(m_scriptState->isolate()), m_scriptState->getExecutionContext(), thisValue, 2, argv, m_scriptState->isolate()).ToLocal(&v8ReturnValue)) {
-    int cppValue = toInt32(m_scriptState->isolate(), v8ReturnValue, NormalConversion, exceptionState);
+    int32_t cppValue = toInt32(m_scriptState->isolate(), v8ReturnValue, NormalConversion, exceptionState);
         if (exceptionState.hadException())
           return false;
     returnValue = cppValue;
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/LongCallbackFunction.h b/third_party/WebKit/Source/bindings/tests/results/core/LongCallbackFunction.h
index ecf82d08..760c06c 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/LongCallbackFunction.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/LongCallbackFunction.h
@@ -32,7 +32,7 @@
   DECLARE_TRACE();
   DECLARE_TRACE_WRAPPERS();
 
-  bool call(ScriptWrappable* scriptWrappable, int num1, int num2, int& returnValue);
+  bool call(ScriptWrappable* scriptWrappable, int32_t num1, int32_t num2, int32_t& returnValue);
 
   v8::Local<v8::Function> v8Value(v8::Isolate* isolate) {
     return m_callback.newLocal(isolate);
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/LongOrTestDictionary.cpp b/third_party/WebKit/Source/bindings/tests/results/core/LongOrTestDictionary.cpp
index 6b4f11e..49e0108 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/LongOrTestDictionary.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/LongOrTestDictionary.cpp
@@ -19,18 +19,18 @@
 
 LongOrTestDictionary::LongOrTestDictionary() : m_type(SpecificTypeNone) {}
 
-int LongOrTestDictionary::getAsLong() const {
+int32_t LongOrTestDictionary::getAsLong() const {
   DCHECK(isLong());
   return m_long;
 }
 
-void LongOrTestDictionary::setLong(int value) {
+void LongOrTestDictionary::setLong(int32_t value) {
   DCHECK(isNull());
   m_long = value;
   m_type = SpecificTypeLong;
 }
 
-LongOrTestDictionary LongOrTestDictionary::fromLong(int value) {
+LongOrTestDictionary LongOrTestDictionary::fromLong(int32_t value) {
   LongOrTestDictionary container;
   container.setLong(value);
   return container;
@@ -87,7 +87,7 @@
   }
 
   if (v8Value->IsNumber()) {
-    int cppValue = toInt32(isolate, v8Value, NormalConversion, exceptionState);
+    int32_t cppValue = toInt32(isolate, v8Value, NormalConversion, exceptionState);
     if (exceptionState.hadException())
       return;
     impl.setLong(cppValue);
@@ -95,7 +95,7 @@
   }
 
   {
-    int cppValue = toInt32(isolate, v8Value, NormalConversion, exceptionState);
+    int32_t cppValue = toInt32(isolate, v8Value, NormalConversion, exceptionState);
     if (exceptionState.hadException())
       return;
     impl.setLong(cppValue);
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/LongOrTestDictionary.h b/third_party/WebKit/Source/bindings/tests/results/core/LongOrTestDictionary.h
index a479be9..40de8bb 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/LongOrTestDictionary.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/LongOrTestDictionary.h
@@ -28,9 +28,9 @@
   bool isNull() const { return m_type == SpecificTypeNone; }
 
   bool isLong() const { return m_type == SpecificTypeLong; }
-  int getAsLong() const;
-  void setLong(int);
-  static LongOrTestDictionary fromLong(int);
+  int32_t getAsLong() const;
+  void setLong(int32_t);
+  static LongOrTestDictionary fromLong(int32_t);
 
   bool isTestDictionary() const { return m_type == SpecificTypeTestDictionary; }
   const TestDictionary& getAsTestDictionary() const;
@@ -50,7 +50,7 @@
   };
   SpecificTypes m_type;
 
-  int m_long;
+  int32_t m_long;
   TestDictionary m_testDictionary;
 
   friend CORE_EXPORT v8::Local<v8::Value> ToV8(const LongOrTestDictionary&, v8::Local<v8::Object>, v8::Isolate*);
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/StringSequenceCallbackFunctionLongSequenceArg.cpp b/third_party/WebKit/Source/bindings/tests/results/core/StringSequenceCallbackFunctionLongSequenceArg.cpp
index 2d7bcb68..83d3e56b3 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/StringSequenceCallbackFunctionLongSequenceArg.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/StringSequenceCallbackFunctionLongSequenceArg.cpp
@@ -40,7 +40,7 @@
   visitor->traceWrappers(m_callback.cast<v8::Value>());
 }
 
-bool StringSequenceCallbackFunctionLongSequenceArg::call(ScriptWrappable* scriptWrappable, const Vector<int>& arg, Vector<String>& returnValue) {
+bool StringSequenceCallbackFunctionLongSequenceArg::call(ScriptWrappable* scriptWrappable, const Vector<int32_t>& arg, Vector<String>& returnValue) {
   if (!m_scriptState->contextIsValid())
     return false;
 
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/StringSequenceCallbackFunctionLongSequenceArg.h b/third_party/WebKit/Source/bindings/tests/results/core/StringSequenceCallbackFunctionLongSequenceArg.h
index 28ab63f0..9d4fe00 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/StringSequenceCallbackFunctionLongSequenceArg.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/StringSequenceCallbackFunctionLongSequenceArg.h
@@ -32,7 +32,7 @@
   DECLARE_TRACE();
   DECLARE_TRACE_WRAPPERS();
 
-  bool call(ScriptWrappable* scriptWrappable, const Vector<int>& arg, Vector<String>& returnValue);
+  bool call(ScriptWrappable* scriptWrappable, const Vector<int32_t>& arg, Vector<String>& returnValue);
 
   v8::Local<v8::Function> v8Value(v8::Isolate* isolate) {
     return m_callback.newLocal(isolate);
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/TestDictionary.cpp b/third_party/WebKit/Source/bindings/tests/results/core/TestDictionary.cpp
index d43d8761..3ae07758 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/TestDictionary.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/TestDictionary.cpp
@@ -170,11 +170,11 @@
 bool TestDictionary::hasLongMember() const {
   return m_hasLongMember;
 }
-int TestDictionary::longMember() const {
+int32_t TestDictionary::longMember() const {
   DCHECK(m_hasLongMember);
   return m_longMember;
 }
-void TestDictionary::setLongMember(int value) {
+void TestDictionary::setLongMember(int32_t value) {
   m_longMember = value;
   m_hasLongMember = true;
 }
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/TestDictionary.h b/third_party/WebKit/Source/bindings/tests/results/core/TestDictionary.h
index 7b18006..e7a8276 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/TestDictionary.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/TestDictionary.h
@@ -92,8 +92,8 @@
   void setInternalDictionarySequenceMember(const HeapVector<InternalDictionary>&);
 
   bool hasLongMember() const;
-  int longMember() const;
-  void setLongMember(int);
+  int32_t longMember() const;
+  void setLongMember(int32_t);
 
   bool hasObjectMember() const;
   ScriptValue objectMember() const;
@@ -202,7 +202,7 @@
   bool m_hasInternalDictionarySequenceMember = false;
   HeapVector<InternalDictionary> m_internalDictionarySequenceMember;
   bool m_hasLongMember = false;
-  int m_longMember;
+  int32_t m_longMember;
   ScriptValue m_objectMember;
   ScriptValue m_objectOrNullMember;
   DoubleOrString m_otherDoubleOrStringMember;
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/TestDictionaryDerivedImplementedAs.cpp b/third_party/WebKit/Source/bindings/tests/results/core/TestDictionaryDerivedImplementedAs.cpp
index ab3fcf0..927ca163 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/TestDictionaryDerivedImplementedAs.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/TestDictionaryDerivedImplementedAs.cpp
@@ -44,11 +44,11 @@
 bool TestDictionaryDerivedImplementedAs::hasRequiredLongMember() const {
   return m_hasRequiredLongMember;
 }
-int TestDictionaryDerivedImplementedAs::requiredLongMember() const {
+int32_t TestDictionaryDerivedImplementedAs::requiredLongMember() const {
   DCHECK(m_hasRequiredLongMember);
   return m_requiredLongMember;
 }
-void TestDictionaryDerivedImplementedAs::setRequiredLongMember(int value) {
+void TestDictionaryDerivedImplementedAs::setRequiredLongMember(int32_t value) {
   m_requiredLongMember = value;
   m_hasRequiredLongMember = true;
 }
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/TestDictionaryDerivedImplementedAs.h b/third_party/WebKit/Source/bindings/tests/results/core/TestDictionaryDerivedImplementedAs.h
index 5c4ee1ec..7111eb84 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/TestDictionaryDerivedImplementedAs.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/TestDictionaryDerivedImplementedAs.h
@@ -38,8 +38,8 @@
   void setDerivedStringMemberWithDefault(String);
 
   bool hasRequiredLongMember() const;
-  int requiredLongMember() const;
-  void setRequiredLongMember(int);
+  int32_t requiredLongMember() const;
+  void setRequiredLongMember(int32_t);
 
   bool hasStringOrDoubleSequenceMember() const;
   const HeapVector<StringOrDouble>& stringOrDoubleSequenceMember() const;
@@ -52,7 +52,7 @@
   String m_derivedStringMember;
   String m_derivedStringMemberWithDefault;
   bool m_hasRequiredLongMember = false;
-  int m_requiredLongMember;
+  int32_t m_requiredLongMember;
   bool m_hasStringOrDoubleSequenceMember = false;
   HeapVector<StringOrDouble> m_stringOrDoubleSequenceMember;
 
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/TestInterfaceOrLong.cpp b/third_party/WebKit/Source/bindings/tests/results/core/TestInterfaceOrLong.cpp
index 7d3662c..b910fb9 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/TestInterfaceOrLong.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/TestInterfaceOrLong.cpp
@@ -40,18 +40,18 @@
   return container;
 }
 
-int TestInterfaceOrLong::getAsLong() const {
+int32_t TestInterfaceOrLong::getAsLong() const {
   DCHECK(isLong());
   return m_long;
 }
 
-void TestInterfaceOrLong::setLong(int value) {
+void TestInterfaceOrLong::setLong(int32_t value) {
   DCHECK(isNull());
   m_long = value;
   m_type = SpecificTypeLong;
 }
 
-TestInterfaceOrLong TestInterfaceOrLong::fromLong(int value) {
+TestInterfaceOrLong TestInterfaceOrLong::fromLong(int32_t value) {
   TestInterfaceOrLong container;
   container.setLong(value);
   return container;
@@ -79,7 +79,7 @@
   }
 
   if (v8Value->IsNumber()) {
-    int cppValue = toInt32(isolate, v8Value, NormalConversion, exceptionState);
+    int32_t cppValue = toInt32(isolate, v8Value, NormalConversion, exceptionState);
     if (exceptionState.hadException())
       return;
     impl.setLong(cppValue);
@@ -87,7 +87,7 @@
   }
 
   {
-    int cppValue = toInt32(isolate, v8Value, NormalConversion, exceptionState);
+    int32_t cppValue = toInt32(isolate, v8Value, NormalConversion, exceptionState);
     if (exceptionState.hadException())
       return;
     impl.setLong(cppValue);
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/TestInterfaceOrLong.h b/third_party/WebKit/Source/bindings/tests/results/core/TestInterfaceOrLong.h
index 8892088a..0cbd1ed 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/TestInterfaceOrLong.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/TestInterfaceOrLong.h
@@ -34,9 +34,9 @@
   static TestInterfaceOrLong fromTestInterface(TestInterfaceImplementation*);
 
   bool isLong() const { return m_type == SpecificTypeLong; }
-  int getAsLong() const;
-  void setLong(int);
-  static TestInterfaceOrLong fromLong(int);
+  int32_t getAsLong() const;
+  void setLong(int32_t);
+  static TestInterfaceOrLong fromLong(int32_t);
 
   TestInterfaceOrLong(const TestInterfaceOrLong&);
   ~TestInterfaceOrLong();
@@ -52,7 +52,7 @@
   SpecificTypes m_type;
 
   Member<TestInterfaceImplementation> m_testInterface;
-  int m_long;
+  int32_t m_long;
 
   friend CORE_EXPORT v8::Local<v8::Value> ToV8(const TestInterfaceOrLong&, v8::Local<v8::Object>, v8::Isolate*);
 };
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestDictionary.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestDictionary.cpp
index c3503f0..5215c54 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestDictionary.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestDictionary.cpp
@@ -264,7 +264,7 @@
   if (longMemberValue.IsEmpty() || longMemberValue->IsUndefined()) {
     // Do nothing.
   } else {
-    int longMember = toInt32(isolate, longMemberValue, NormalConversion, exceptionState);
+    int32_t longMember = toInt32(isolate, longMemberValue, NormalConversion, exceptionState);
     if (exceptionState.hadException())
       return;
     impl.setLongMember(longMember);
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestDictionaryDerived.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestDictionaryDerived.cpp
index a748698..80309c8 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestDictionaryDerived.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestDictionaryDerived.cpp
@@ -73,7 +73,7 @@
     exceptionState.throwTypeError("required member requiredLongMember is undefined.");
     return;
   } else {
-    int requiredLongMember = toInt32(isolate, requiredLongMemberValue, NormalConversion, exceptionState);
+    int32_t requiredLongMember = toInt32(isolate, requiredLongMemberValue, NormalConversion, exceptionState);
     if (exceptionState.hadException())
       return;
     impl.setRequiredLongMember(requiredLongMember);
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestException.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestException.cpp
index e2090788d..13d5018 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestException.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestException.cpp
@@ -82,7 +82,7 @@
     return;
   }
 
-  unsigned argument;
+  uint16_t argument;
   argument = toUInt16(info.GetIsolate(), info[0], NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestIntegerIndexed.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestIntegerIndexed.cpp
index b700021..6eb9b3c 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestIntegerIndexed.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestIntegerIndexed.cpp
@@ -68,7 +68,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestIntegerIndexed", "length");
 
   // Prepare the value to be set.
-  int cppValue = toInt16(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int16_t cppValue = toInt16(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestIntegerIndexedGlobal.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestIntegerIndexedGlobal.cpp
index 9b4f697d..92da808 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestIntegerIndexedGlobal.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestIntegerIndexedGlobal.cpp
@@ -68,7 +68,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestIntegerIndexedGlobal", "length");
 
   // Prepare the value to be set.
-  unsigned long long cppValue = toUInt64(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  uint64_t cppValue = toUInt64(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestIntegerIndexedPrimaryGlobal.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestIntegerIndexedPrimaryGlobal.cpp
index e792111..55c34418 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestIntegerIndexedPrimaryGlobal.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestIntegerIndexedPrimaryGlobal.cpp
@@ -68,7 +68,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestIntegerIndexedPrimaryGlobal", "length");
 
   // Prepare the value to be set.
-  int cppValue = toInt8(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int8_t cppValue = toInt8(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterface.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterface.cpp
index 48cdd5d..61912cd 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterface.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterface.cpp
@@ -268,7 +268,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestInterface", "conditionalLongAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -370,7 +370,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestInterface", "alwaysExposedAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -392,7 +392,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestInterface", "workerExposedAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -414,7 +414,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestInterface", "windowExposedAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -803,7 +803,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestInterface", "partialLongAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -818,7 +818,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestInterface", "partialStaticLongAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -842,7 +842,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestInterface", "partialCallWithExecutionContextLongAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -900,7 +900,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestInterface", "partialSecureContextLongAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -922,7 +922,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestInterface", "partial2LongAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -937,7 +937,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestInterface", "partial2StaticLongAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -1275,7 +1275,7 @@
 
   TestInterfaceImplementation* impl = V8TestInterface::toImpl(info.Holder());
 
-  int longArg;
+  int32_t longArg;
   longArg = toInt32(info.GetIsolate(), info[0], NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
@@ -1552,7 +1552,7 @@
     return;
   }
 
-  int longArg;
+  int32_t longArg;
   longArg = toInt32(info.GetIsolate(), info[0], NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterface2.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterface2.cpp
index 7872fc9..c0f6cf3 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterface2.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterface2.cpp
@@ -67,7 +67,7 @@
     return;
   }
 
-  unsigned index;
+  uint32_t index;
   index = toUInt32(info.GetIsolate(), info[0], NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
@@ -85,7 +85,7 @@
     return;
   }
 
-  unsigned index;
+  uint32_t index;
   index = toUInt32(info.GetIsolate(), info[0], NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
@@ -107,7 +107,7 @@
     return;
   }
 
-  unsigned index;
+  uint32_t index;
   TestInterfaceEmpty* value;
   index = toUInt32(info.GetIsolate(), info[0], NormalConversion, exceptionState);
   if (exceptionState.hadException())
@@ -137,7 +137,7 @@
     return;
   }
 
-  unsigned index;
+  uint32_t index;
   index = toUInt32(info.GetIsolate(), info[0], NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceCheckSecurity.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceCheckSecurity.cpp
index 1bee41e..7ec4601a 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceCheckSecurity.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceCheckSecurity.cpp
@@ -77,7 +77,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestInterfaceCheckSecurity", "longAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -99,7 +99,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestInterfaceCheckSecurity", "doNotCheckSecurityLongAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -129,7 +129,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestInterfaceCheckSecurity", "doNotCheckSecurityOnSetterLongAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor2.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor2.cpp
index e84207b..76ceaaf 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor2.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceConstructor2.cpp
@@ -103,7 +103,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::ConstructionContext, "TestInterfaceConstructor2");
 
   TestInterfaceEmpty* testInterfaceEmptyArg;
-  int longArg;
+  int32_t longArg;
   V8StringResource<> defaultUndefinedOptionalStringArg;
   V8StringResource<> defaultNullStringOptionalStringArg;
   Dictionary defaultUndefinedOptionalDictionaryArg;
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNamedConstructor.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNamedConstructor.cpp
index a232fae..4d353d8 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNamedConstructor.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceNamedConstructor.cpp
@@ -98,7 +98,7 @@
 
   V8StringResource<> stringArg;
   bool defaultUndefinedOptionalBooleanArg;
-  int defaultUndefinedOptionalLongArg;
+  int32_t defaultUndefinedOptionalLongArg;
   V8StringResource<> defaultUndefinedOptionalStringArg;
   V8StringResource<> defaultNullStringOptionalstringArg;
   V8StringResource<> optionalStringArg;
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceOriginTrialEnabled.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceOriginTrialEnabled.cpp
index 932634f6..c83681c 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceOriginTrialEnabled.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceOriginTrialEnabled.cpp
@@ -89,7 +89,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestInterfaceOriginTrialEnabled", "conditionalLongAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestObject.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestObject.cpp
index b899b6f..c2a0e594 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestObject.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestObject.cpp
@@ -273,7 +273,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestObject", "domTimeStampAttribute");
 
   // Prepare the value to be set.
-  unsigned long long cppValue = toUInt64(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  uint64_t cppValue = toUInt64(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -317,7 +317,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestObject", "byteAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt8(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int8_t cppValue = toInt8(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -383,7 +383,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestObject", "longAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -405,7 +405,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestObject", "longLongAttribute");
 
   // Prepare the value to be set.
-  long long cppValue = toInt64(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int64_t cppValue = toInt64(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -427,7 +427,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestObject", "octetAttribute");
 
   // Prepare the value to be set.
-  unsigned cppValue = toUInt8(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  uint8_t cppValue = toUInt8(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -449,7 +449,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestObject", "shortAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt16(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int16_t cppValue = toInt16(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -515,7 +515,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestObject", "unsignedLongAttribute");
 
   // Prepare the value to be set.
-  unsigned cppValue = toUInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  uint32_t cppValue = toUInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -537,7 +537,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestObject", "unsignedLongLongAttribute");
 
   // Prepare the value to be set.
-  unsigned long long cppValue = toUInt64(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  uint64_t cppValue = toUInt64(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -559,7 +559,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestObject", "unsignedShortAttribute");
 
   // Prepare the value to be set.
-  unsigned cppValue = toUInt16(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  uint16_t cppValue = toUInt16(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -633,7 +633,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestObject", "cssAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -655,7 +655,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestObject", "imeAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -677,7 +677,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestObject", "svgAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -699,7 +699,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestObject", "xmlAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -1227,7 +1227,7 @@
 
   bool isNull = false;
 
-  int cppValue(impl->longOrNullAttribute(isNull));
+  int32_t cppValue(impl->longOrNullAttribute(isNull));
 
   if (isNull) {
     v8SetReturnValueNull(info);
@@ -1244,7 +1244,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestObject", "longOrNullAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -1370,7 +1370,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestObject", "staticLongAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -1568,7 +1568,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestObject", "activityLoggingAccessForAllWorldsLongAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -1590,7 +1590,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestObject", "activityLoggingGetterForAllWorldsLongAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -1612,7 +1612,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestObject", "activityLoggingSetterForAllWorldsLongAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -1830,7 +1830,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestObject", "customGetterLongAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -1860,7 +1860,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestObject", "deprecatedLongAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -1882,7 +1882,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestObject", "enforceRangeLongAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, EnforceRange, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, EnforceRange, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -1904,7 +1904,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestObject", "implementedAsLongAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -1918,7 +1918,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestObject", "customGetterImplementedAsLongAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -1948,7 +1948,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestObject", "measureAsLongAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -1970,7 +1970,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestObject", "notEnumerableLongAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -1992,7 +1992,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestObject", "originTrialEnabledLongAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -2050,7 +2050,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestObject", "activityLoggingAccessPerWorldBindingsLongAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -2072,7 +2072,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestObject", "activityLoggingAccessPerWorldBindingsLongAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -2094,7 +2094,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestObject", "activityLoggingAccessForIsolatedWorldsPerWorldBindingsLongAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -2116,7 +2116,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestObject", "activityLoggingAccessForIsolatedWorldsPerWorldBindingsLongAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -2138,7 +2138,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestObject", "activityLoggingGetterPerWorldBindingsLongAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -2160,7 +2160,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestObject", "activityLoggingGetterPerWorldBindingsLongAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -2182,7 +2182,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestObject", "activityLoggingGetterForIsolatedWorldsPerWorldBindingsLongAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -2204,7 +2204,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestObject", "activityLoggingGetterForIsolatedWorldsPerWorldBindingsLongAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -2424,7 +2424,7 @@
 
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::GetterContext, "TestObject", "raisesExceptionLongAttribute");
 
-  int cppValue(impl->raisesExceptionLongAttribute(exceptionState));
+  int32_t cppValue(impl->raisesExceptionLongAttribute(exceptionState));
 
   if (UNLIKELY(exceptionState.hadException()))
     return;
@@ -2439,7 +2439,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestObject", "raisesExceptionLongAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -2453,7 +2453,7 @@
 
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::GetterContext, "TestObject", "raisesExceptionGetterLongAttribute");
 
-  int cppValue(impl->raisesExceptionGetterLongAttribute(exceptionState));
+  int32_t cppValue(impl->raisesExceptionGetterLongAttribute(exceptionState));
 
   if (UNLIKELY(exceptionState.hadException()))
     return;
@@ -2468,7 +2468,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestObject", "raisesExceptionGetterLongAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -2490,7 +2490,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestObject", "setterRaisesExceptionLongAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -2676,7 +2676,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestObject", "reflectLongAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -2701,7 +2701,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestObject", "reflectUnsignedShortAttribute");
 
   // Prepare the value to be set.
-  unsigned cppValue = toUInt16(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  uint16_t cppValue = toUInt16(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -2726,7 +2726,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestObject", "reflectUnsignedLongAttribute");
 
   // Prepare the value to be set.
-  unsigned cppValue = toUInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  uint32_t cppValue = toUInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -3149,7 +3149,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestObject", "runtimeEnabledLongAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -3357,7 +3357,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestObject", "unforgeableLongAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -3379,7 +3379,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestObject", "measuredLongAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -3455,7 +3455,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestObject", "unscopableLongAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -3477,7 +3477,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestObject", "unscopableOriginTrialEnabledLongAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -3499,7 +3499,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestObject", "unscopableRuntimeEnabledLongAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -3782,7 +3782,7 @@
     return;
   }
 
-  unsigned long long domTimeStampArg;
+  uint64_t domTimeStampArg;
   domTimeStampArg = toUInt64(info.GetIsolate(), info[0], NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
@@ -3818,7 +3818,7 @@
     return;
   }
 
-  int byteArg;
+  int8_t byteArg;
   byteArg = toInt8(info.GetIsolate(), info[0], NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
@@ -3872,7 +3872,7 @@
     return;
   }
 
-  int longArg;
+  int32_t longArg;
   longArg = toInt32(info.GetIsolate(), info[0], NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
@@ -3890,7 +3890,7 @@
     return;
   }
 
-  long long longLongArg;
+  int64_t longLongArg;
   longLongArg = toInt64(info.GetIsolate(), info[0], NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
@@ -3908,7 +3908,7 @@
     return;
   }
 
-  unsigned octetArg;
+  uint8_t octetArg;
   octetArg = toUInt8(info.GetIsolate(), info[0], NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
@@ -3926,7 +3926,7 @@
     return;
   }
 
-  int shortArg;
+  int16_t shortArg;
   shortArg = toInt16(info.GetIsolate(), info[0], NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
@@ -3944,7 +3944,7 @@
     return;
   }
 
-  unsigned unsignedLongArg;
+  uint32_t unsignedLongArg;
   unsignedLongArg = toUInt32(info.GetIsolate(), info[0], NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
@@ -3962,7 +3962,7 @@
     return;
   }
 
-  unsigned long long unsignedLongLongArg;
+  uint64_t unsignedLongLongArg;
   unsignedLongLongArg = toUInt64(info.GetIsolate(), info[0], NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
@@ -3980,7 +3980,7 @@
     return;
   }
 
-  unsigned unsignedShortArg;
+  uint16_t unsignedShortArg;
   unsignedShortArg = toUInt16(info.GetIsolate(), info[0], NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
@@ -4023,7 +4023,7 @@
     return;
   }
 
-  int longArg;
+  int32_t longArg;
   TestInterfaceEmpty* testInterfaceEmptyArg;
   longArg = toInt32(info.GetIsolate(), info[0], NormalConversion, exceptionState);
   if (exceptionState.hadException())
@@ -4383,8 +4383,8 @@
     return;
   }
 
-  Vector<int> arrayLongArg;
-  arrayLongArg = toImplArray<Vector<int>>(info[0], 1, info.GetIsolate(), exceptionState);
+  Vector<int32_t> arrayLongArg;
+  arrayLongArg = toImplArray<Vector<int32_t>>(info[0], 1, info.GetIsolate(), exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -4437,9 +4437,9 @@
     return;
   }
 
-  Nullable<Vector<int>> arrayLongArg;
+  Nullable<Vector<int32_t>> arrayLongArg;
   if (!isUndefinedOrNull(info[0])) {
-    arrayLongArg = toImplArray<Vector<int>>(info[0], 1, info.GetIsolate(), exceptionState);
+    arrayLongArg = toImplArray<Vector<int32_t>>(info[0], 1, info.GetIsolate(), exceptionState);
     if (exceptionState.hadException())
       return;
   }
@@ -4475,8 +4475,8 @@
     return;
   }
 
-  Vector<int> longSequenceArg;
-  longSequenceArg = toImplArray<Vector<int>>(info[0], 1, info.GetIsolate(), exceptionState);
+  Vector<int32_t> longSequenceArg;
+  longSequenceArg = toImplArray<Vector<int32_t>>(info[0], 1, info.GetIsolate(), exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -4547,9 +4547,9 @@
     return;
   }
 
-  Nullable<Vector<int>> longSequenceArg;
+  Nullable<Vector<int32_t>> longSequenceArg;
   if (!isUndefinedOrNull(info[0])) {
-    longSequenceArg = toImplArray<Vector<int>>(info[0], 1, info.GetIsolate(), exceptionState);
+    longSequenceArg = toImplArray<Vector<int32_t>>(info[0], 1, info.GetIsolate(), exceptionState);
     if (exceptionState.hadException())
       return;
   }
@@ -4602,7 +4602,7 @@
 static void nullableLongMethodMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
   TestObject* impl = V8TestObject::toImpl(info.Holder());
 
-  Nullable<int> result = impl->nullableLongMethod();
+  Nullable<int32_t> result = impl->nullableLongMethod();
   if (result.isNull())
     v8SetReturnValueNull(info);
   else
@@ -4624,7 +4624,7 @@
 static void nullableLongSequenceMethodMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
   TestObject* impl = V8TestObject::toImpl(info.Holder());
 
-  Nullable<Vector<int>> result = impl->nullableLongSequenceMethod();
+  Nullable<Vector<int32_t>> result = impl->nullableLongSequenceMethod();
   if (result.isNull())
     v8SetReturnValueNull(info);
   else
@@ -4989,7 +4989,7 @@
     return;
   }
 
-  int arg1;
+  int32_t arg1;
   Dictionary arg2;
   V8StringResource<> arg3;
   Vector<String> variadic;
@@ -5181,7 +5181,7 @@
   }
 
   V8StringResource<> stringArg;
-  int longArg;
+  int32_t longArg;
   stringArg = info[0];
   if (!stringArg.prepare())
     return;
@@ -5243,7 +5243,7 @@
 
   TestObject* impl = V8TestObject::toImpl(info.Holder());
 
-  int optionalLongArg;
+  int32_t optionalLongArg;
   int numArgsPassed = info.Length();
   while (numArgsPassed > 0) {
     if (!info[numArgsPassed - 1]->IsUndefined())
@@ -5266,7 +5266,7 @@
 
   TestObject* impl = V8TestObject::toImpl(info.Holder());
 
-  int optionalLongArg;
+  int32_t optionalLongArg;
   int numArgsPassed = info.Length();
   while (numArgsPassed > 0) {
     if (!info[numArgsPassed - 1]->IsUndefined())
@@ -5289,7 +5289,7 @@
 
   TestObject* impl = V8TestObject::toImpl(info.Holder());
 
-  int optionalLongArg;
+  int32_t optionalLongArg;
   int numArgsPassed = info.Length();
   while (numArgsPassed > 0) {
     if (!info[numArgsPassed - 1]->IsUndefined())
@@ -5312,7 +5312,7 @@
 
   TestObject* impl = V8TestObject::toImpl(info.Holder());
 
-  int optionalLongArg;
+  int32_t optionalLongArg;
   int numArgsPassed = info.Length();
   while (numArgsPassed > 0) {
     if (!info[numArgsPassed - 1]->IsUndefined())
@@ -5340,8 +5340,8 @@
     return;
   }
 
-  int longArg;
-  int optionalLongArg;
+  int32_t longArg;
+  int32_t optionalLongArg;
   int numArgsPassed = info.Length();
   while (numArgsPassed > 0) {
     if (!info[numArgsPassed - 1]->IsUndefined())
@@ -5373,9 +5373,9 @@
     return;
   }
 
-  int longArg;
-  int optionalLongArg1;
-  int optionalLongArg2;
+  int32_t longArg;
+  int32_t optionalLongArg1;
+  int32_t optionalLongArg2;
   int numArgsPassed = info.Length();
   while (numArgsPassed > 0) {
     if (!info[numArgsPassed - 1]->IsUndefined())
@@ -5415,7 +5415,7 @@
     return;
   }
 
-  int longArg;
+  int32_t longArg;
   TestInterfaceEmpty* optionalTestInterfaceEmpty;
   int numArgsPassed = info.Length();
   while (numArgsPassed > 0) {
@@ -5452,7 +5452,7 @@
   }
 
   TestInterfaceEmpty* optionalTestInterfaceEmpty;
-  int longArg;
+  int32_t longArg;
   int numArgsPassed = info.Length();
   while (numArgsPassed > 0) {
     if (!info[numArgsPassed - 1]->IsUndefined())
@@ -5532,9 +5532,9 @@
 
   TestObject* impl = V8TestObject::toImpl(info.Holder());
 
-  int defaultLongArg;
-  long long defaultLongLongArg;
-  unsigned defaultUnsignedArg;
+  int32_t defaultLongArg;
+  int64_t defaultLongLongArg;
+  uint32_t defaultUnsignedArg;
   if (!info[0]->IsUndefined()) {
     defaultLongArg = toInt32(info.GetIsolate(), info[0], NormalConversion, exceptionState);
     if (exceptionState.hadException())
@@ -5819,7 +5819,7 @@
 
   TestObject* impl = V8TestObject::toImpl(info.Holder());
 
-  int longArg;
+  int32_t longArg;
   longArg = toInt32(info.GetIsolate(), info[0], NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
@@ -5832,8 +5832,8 @@
 
   TestObject* impl = V8TestObject::toImpl(info.Holder());
 
-  int longArg1;
-  int longArg2;
+  int32_t longArg1;
+  int32_t longArg2;
   longArg1 = toInt32(info.GetIsolate(), info[0], NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
@@ -5880,7 +5880,7 @@
 
   TestObject* impl = V8TestObject::toImpl(info.Holder());
 
-  int longArg;
+  int32_t longArg;
   longArg = toInt32(info.GetIsolate(), info[0], NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
@@ -5894,7 +5894,7 @@
   TestObject* impl = V8TestObject::toImpl(info.Holder());
 
   V8StringResource<> stringArg;
-  int longArg;
+  int32_t longArg;
   int numArgsPassed = info.Length();
   while (numArgsPassed > 0) {
     if (!info[numArgsPassed - 1]->IsUndefined())
@@ -5959,7 +5959,7 @@
 
   TestObject* impl = V8TestObject::toImpl(info.Holder());
 
-  int longArg;
+  int32_t longArg;
   longArg = toInt32(info.GetIsolate(), info[0], NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
@@ -6014,7 +6014,7 @@
 
   TestObject* impl = V8TestObject::toImpl(info.Holder());
 
-  int longArg;
+  int32_t longArg;
   longArg = toInt32(info.GetIsolate(), info[0], NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
@@ -6027,8 +6027,8 @@
 
   TestObject* impl = V8TestObject::toImpl(info.Holder());
 
-  Vector<int> longArrayArg;
-  longArrayArg = toImplArray<Vector<int>>(info[0], 1, info.GetIsolate(), exceptionState);
+  Vector<int32_t> longArrayArg;
+  longArrayArg = toImplArray<Vector<int32_t>>(info[0], 1, info.GetIsolate(), exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -6068,7 +6068,7 @@
 
   TestObject* impl = V8TestObject::toImpl(info.Holder());
 
-  int longArg;
+  int32_t longArg;
   longArg = toInt32(info.GetIsolate(), info[0], NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
@@ -6199,7 +6199,7 @@
 
   TestObject* impl = V8TestObject::toImpl(info.Holder());
 
-  int longArg;
+  int32_t longArg;
   longArg = toInt32(info.GetIsolate(), info[0], NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
@@ -6490,7 +6490,7 @@
 
   TestObject* impl = V8TestObject::toImpl(info.Holder());
 
-  int longArg;
+  int32_t longArg;
   Vector<ScriptValue> restArgs;
   longArg = toInt32(info.GetIsolate(), info[0], NormalConversion, exceptionState);
   if (exceptionState.hadException())
@@ -6746,7 +6746,7 @@
 
   TestObject* impl = V8TestObject::toImpl(info.Holder());
 
-  int longArg;
+  int32_t longArg;
   longArg = toInt32(info.GetIsolate(), info[0], NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
@@ -6785,7 +6785,7 @@
 
   TestObject* impl = V8TestObject::toImpl(info.Holder());
 
-  int longArg;
+  int32_t longArg;
   longArg = toInt32(info.GetIsolate(), info[0], NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
@@ -6822,7 +6822,7 @@
 static void overloadedStaticMethod1Method(const v8::FunctionCallbackInfo<v8::Value>& info) {
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::ExecutionContext, "TestObject", "overloadedStaticMethod");
 
-  int longArg;
+  int32_t longArg;
   longArg = toInt32(info.GetIsolate(), info[0], NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
@@ -6833,8 +6833,8 @@
 static void overloadedStaticMethod2Method(const v8::FunctionCallbackInfo<v8::Value>& info) {
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::ExecutionContext, "TestObject", "overloadedStaticMethod");
 
-  int longArg1;
-  int longArg2;
+  int32_t longArg1;
+  int32_t longArg2;
   longArg1 = toInt32(info.GetIsolate(), info[0], NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
@@ -6888,7 +6888,7 @@
     return;
   }
 
-  unsigned index;
+  uint32_t index;
   index = toUInt32(info.GetIsolate(), info[0], NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
@@ -6909,7 +6909,7 @@
     return;
   }
 
-  unsigned index;
+  uint32_t index;
   V8StringResource<> value;
   index = toUInt32(info.GetIsolate(), info[0], NormalConversion, exceptionState);
   if (exceptionState.hadException())
@@ -6933,7 +6933,7 @@
     return;
   }
 
-  unsigned clampUnsignedShortArg;
+  uint16_t clampUnsignedShortArg;
   clampUnsignedShortArg = toUInt16(info.GetIsolate(), info[0], Clamp, exceptionState);
   if (exceptionState.hadException())
     return;
@@ -6951,7 +6951,7 @@
     return;
   }
 
-  unsigned clampUnsignedLongArg;
+  uint32_t clampUnsignedLongArg;
   clampUnsignedLongArg = toUInt32(info.GetIsolate(), info[0], Clamp, exceptionState);
   if (exceptionState.hadException())
     return;
@@ -6978,7 +6978,7 @@
 
   TestObject* impl = V8TestObject::toImpl(info.Holder());
 
-  int defaultUndefinedLongArg;
+  int32_t defaultUndefinedLongArg;
   defaultUndefinedLongArg = toInt32(info.GetIsolate(), info[0], NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
@@ -7007,7 +7007,7 @@
     return;
   }
 
-  int enforceRangeLongArg;
+  int32_t enforceRangeLongArg;
   enforceRangeLongArg = toInt32(info.GetIsolate(), info[0], EnforceRange, exceptionState);
   if (exceptionState.hadException())
     return;
@@ -7073,7 +7073,7 @@
 
   ScriptState* scriptState = ScriptState::forReceiverObject(info);
 
-  int result = impl->callWithScriptStateLongMethod(scriptState);
+  int32_t result = impl->callWithScriptStateLongMethod(scriptState);
   v8SetReturnValueInt(info, result);
 }
 
@@ -7203,7 +7203,7 @@
 
   TestObject* impl = V8TestObject::toImpl(info.Holder());
 
-  int arg;
+  int32_t arg;
   arg = toInt32(info.GetIsolate(), info[0], NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
@@ -7250,7 +7250,7 @@
 
   TestObject* impl = V8TestObject::toImpl(info.Holder());
 
-  int arg;
+  int32_t arg;
   arg = toInt32(info.GetIsolate(), info[0], NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
@@ -7297,7 +7297,7 @@
 
   TestObject* impl = V8TestObject::toImpl(info.Holder());
 
-  int arg;
+  int32_t arg;
   arg = toInt32(info.GetIsolate(), info[0], NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
@@ -7344,7 +7344,7 @@
 
   TestObject* impl = V8TestObject::toImpl(info.Holder());
 
-  int arg;
+  int32_t arg;
   arg = toInt32(info.GetIsolate(), info[0], NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
@@ -7391,7 +7391,7 @@
 
   TestObject* impl = V8TestObject::toImpl(info.Holder());
 
-  int arg;
+  int32_t arg;
   arg = toInt32(info.GetIsolate(), info[0], NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
@@ -7438,7 +7438,7 @@
 
   TestObject* impl = V8TestObject::toImpl(info.Holder());
 
-  int arg;
+  int32_t arg;
   arg = toInt32(info.GetIsolate(), info[0], NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
@@ -7487,7 +7487,7 @@
 
   TestObject* impl = V8TestObject::toImpl(info.Holder());
 
-  int arg;
+  int32_t arg;
   arg = toInt32(info.GetIsolate(), info[0], NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
@@ -7536,7 +7536,7 @@
 
   TestObject* impl = V8TestObject::toImpl(info.Holder());
 
-  int arg;
+  int32_t arg;
   arg = toInt32(info.GetIsolate(), info[0], NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
@@ -7753,7 +7753,7 @@
 
   TestObject* impl = V8TestObject::toImpl(info.Holder());
 
-  int optionalLongArg;
+  int32_t optionalLongArg;
   int numArgsPassed = info.Length();
   while (numArgsPassed > 0) {
     if (!info[numArgsPassed - 1]->IsUndefined())
@@ -7858,7 +7858,7 @@
     return;
   }
 
-  int longArg;
+  int32_t longArg;
   longArg = toInt32(info.GetIsolate(), info[0], NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
@@ -7904,7 +7904,7 @@
 
   TestObject* impl = V8TestObject::toImpl(info.Holder());
 
-  int longArg;
+  int32_t longArg;
   longArg = toInt32(info.GetIsolate(), info[0], NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
@@ -7974,7 +7974,7 @@
 
   TestObject* impl = V8TestObject::toImpl(info.Holder());
 
-  int longArg;
+  int32_t longArg;
   V8StringResource<> stringArg;
   longArg = toInt32(info.GetIsolate(), info[0], NormalConversion, exceptionState);
   if (exceptionState.hadException())
@@ -7992,7 +7992,7 @@
 
   TestObject* impl = V8TestObject::toImpl(info.Holder());
 
-  int longArg;
+  int32_t longArg;
   V8StringResource<> stringArg;
   TestInterfaceImplementation* testInterfaceArg;
   longArg = toInt32(info.GetIsolate(), info[0], NormalConversion, exceptionState);
@@ -8354,7 +8354,7 @@
     return;
   }
 
-  int key;
+  int32_t key;
   key = toInt32(info.GetIsolate(), info[0], NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
@@ -8378,7 +8378,7 @@
     return;
   }
 
-  int key;
+  int32_t key;
   key = toInt32(info.GetIsolate(), info[0], NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
@@ -8402,7 +8402,7 @@
     return;
   }
 
-  int key;
+  int32_t key;
   key = toInt32(info.GetIsolate(), info[0], NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
@@ -8426,7 +8426,7 @@
     return;
   }
 
-  int key;
+  int32_t key;
   StringOrDouble value;
   key = toInt32(info.GetIsolate(), info[0], NormalConversion, exceptionState);
   if (exceptionState.hadException())
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/V8TestTypedefs.cpp b/third_party/WebKit/Source/bindings/tests/results/core/V8TestTypedefs.cpp
index 11ffa5a5..c6de14d2b 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/V8TestTypedefs.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/V8TestTypedefs.cpp
@@ -72,7 +72,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestTypedefs", "uLongLongAttribute");
 
   // Prepare the value to be set.
-  unsigned long long cppValue = toUInt64(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  uint64_t cppValue = toUInt64(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -110,7 +110,7 @@
 
   TestTypedefs* impl = V8TestTypedefs::toImpl(info.Holder());
 
-  Vector<int> arrayOfLongsArg;
+  Vector<int32_t> arrayOfLongsArg;
   int numArgsPassed = info.Length();
   while (numArgsPassed > 0) {
     if (!info[numArgsPassed - 1]->IsUndefined())
@@ -121,7 +121,7 @@
     impl->voidMethodArrayOfLongsArg();
     return;
   }
-  arrayOfLongsArg = toImplArray<Vector<int>>(info[0], 1, info.GetIsolate(), exceptionState);
+  arrayOfLongsArg = toImplArray<Vector<int32_t>>(info[0], 1, info.GetIsolate(), exceptionState);
   if (exceptionState.hadException())
     return;
 
diff --git a/third_party/WebKit/Source/bindings/tests/results/modules/V8TestInterface5.cpp b/third_party/WebKit/Source/bindings/tests/results/modules/V8TestInterface5.cpp
index cec4bd9..9c6ea666 100644
--- a/third_party/WebKit/Source/bindings/tests/results/modules/V8TestInterface5.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/modules/V8TestInterface5.cpp
@@ -207,7 +207,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestInterface5", "alwaysExposedAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -229,7 +229,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestInterface5", "workerExposedAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -251,7 +251,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestInterface5", "windowExposedAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
diff --git a/third_party/WebKit/Source/bindings/tests/results/modules/V8TestInterfacePartial.cpp b/third_party/WebKit/Source/bindings/tests/results/modules/V8TestInterfacePartial.cpp
index 98f7a25c..6d3ada6 100644
--- a/third_party/WebKit/Source/bindings/tests/results/modules/V8TestInterfacePartial.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/modules/V8TestInterfacePartial.cpp
@@ -46,7 +46,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestInterface", "partial4LongAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
@@ -61,7 +61,7 @@
   ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext, "TestInterface", "partial4StaticLongAttribute");
 
   // Prepare the value to be set.
-  int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
+  int32_t cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
   if (exceptionState.hadException())
     return;
 
diff --git a/third_party/WebKit/Source/build/scripts/make_css_property_names.py b/third_party/WebKit/Source/build/scripts/make_css_property_names.py
index 87d1d6a3..3a244fa 100755
--- a/third_party/WebKit/Source/build/scripts/make_css_property_names.py
+++ b/third_party/WebKit/Source/build/scripts/make_css_property_names.py
@@ -37,6 +37,7 @@
 const int numCSSProperties = %(properties_count)s;
 const int lastCSSProperty = %(last_property_id)d;
 const int lastUnresolvedCSSProperty = %(last_unresolved_property_id)d;
+const int numCSSPropertyIDs = lastUnresolvedCSSProperty + 1;
 const size_t maxCSSPropertyNameLength = %(max_name_length)d;
 
 const char* getPropertyName(CSSPropertyID);
diff --git a/third_party/WebKit/Source/core/BUILD.gn b/third_party/WebKit/Source/core/BUILD.gn
index eb6c01d..b5b30b4 100644
--- a/third_party/WebKit/Source/core/BUILD.gn
+++ b/third_party/WebKit/Source/core/BUILD.gn
@@ -1302,6 +1302,7 @@
     "layout/compositing/CompositingReasonFinderTest.cpp",
     "layout/line/InlineBoxTest.cpp",
     "layout/line/InlineTextBoxTest.cpp",
+    "layout/ng/geometry/ng_box_strut_test.cc",
     "layout/ng/geometry/ng_logical_offset_test.cc",
     "layout/ng/geometry/ng_physical_rect_test.cc",
     "layout/ng/ng_absolute_utils_test.cc",
@@ -1313,8 +1314,8 @@
     "layout/ng/ng_inline_node_test.cc",
     "layout/ng/ng_layout_inline_items_builder_test.cc",
     "layout/ng/ng_length_utils_test.cc",
+    "layout/ng/ng_min_max_content_size_test.cc",
     "layout/ng/ng_out_of_flow_layout_part_test.cc",
-    "layout/ng/ng_units_test.cc",
     "layout/shapes/BoxShapeTest.cpp",
     "layout/svg/LayoutSVGRootTest.cpp",
     "loader/DocumentLoadTimingTest.cpp",
diff --git a/third_party/WebKit/Source/core/animation/CSSImageInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSImageInterpolationType.cpp
index 08a2428..ae4340c 100644
--- a/third_party/WebKit/Source/core/animation/CSSImageInterpolationType.cpp
+++ b/third_party/WebKit/Source/core/animation/CSSImageInterpolationType.cpp
@@ -25,7 +25,8 @@
 
   bool isSingle() const { return m_isSingle; }
   bool equals(const CSSImageNonInterpolableValue& other) const {
-    return m_start->equals(*other.m_start) && m_end->equals(*other.m_end);
+    return dataEquivalent(m_start, other.m_start) &&
+           dataEquivalent(m_end, other.m_end);
   }
 
   static PassRefPtr<CSSImageNonInterpolableValue> merge(
diff --git a/third_party/WebKit/Source/core/animation/CSSInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSInterpolationType.cpp
index 861d27a5..11a2c54 100644
--- a/third_party/WebKit/Source/core/animation/CSSInterpolationType.cpp
+++ b/third_party/WebKit/Source/core/animation/CSSInterpolationType.cpp
@@ -49,7 +49,7 @@
         CSSVariableResolver::resolveVariableReferences(
             environment.state(), m_property, *m_variableReference,
             omitAnimationTainted);
-    return m_resolvedValue->equals(*resolvedValue);
+    return dataEquivalent(m_resolvedValue.get(), resolvedValue);
   }
 
   CSSPropertyID m_property;
@@ -87,13 +87,7 @@
     if (!inheritedValue) {
       inheritedValue = m_initialValue.get();
     }
-    if (inheritedValue == m_inheritedValue.get()) {
-      return true;
-    }
-    if (!inheritedValue || !m_inheritedValue) {
-      return false;
-    }
-    return m_inheritedValue->equals(*inheritedValue);
+    return dataEquivalent(m_inheritedValue.get(), inheritedValue);
   }
 
   const AtomicString& m_name;
diff --git a/third_party/WebKit/Source/core/animation/animatable/AnimatableImage.cpp b/third_party/WebKit/Source/core/animation/animatable/AnimatableImage.cpp
index eb2a5139..5949017 100644
--- a/third_party/WebKit/Source/core/animation/animatable/AnimatableImage.cpp
+++ b/third_party/WebKit/Source/core/animation/animatable/AnimatableImage.cpp
@@ -60,7 +60,7 @@
 }
 
 bool AnimatableImage::equalTo(const AnimatableValue* value) const {
-  return m_value->equals(*toAnimatableImage(value)->m_value.get());
+  return dataEquivalent(m_value, toAnimatableImage(value)->m_value);
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/animation/animatable/AnimatableUnknown.h b/third_party/WebKit/Source/core/animation/animatable/AnimatableUnknown.h
index 8d5c0b8..af25e09a 100644
--- a/third_party/WebKit/Source/core/animation/animatable/AnimatableUnknown.h
+++ b/third_party/WebKit/Source/core/animation/animatable/AnimatableUnknown.h
@@ -75,13 +75,12 @@
 
 inline bool AnimatableUnknown::equalTo(const AnimatableValue* value) const {
   const AnimatableUnknown* unknown = toAnimatableUnknown(value);
-  return m_value == unknown->m_value || m_value->equals(*unknown->m_value);
+  return dataEquivalent(m_value, unknown->m_value);
 }
 
 inline bool AnimatableUnknown::usesDefaultInterpolationWith(
     const AnimatableValue* value) const {
-  const AnimatableUnknown& unknown = toAnimatableUnknown(*value);
-  return !m_value->equals(*unknown.m_value);
+  return !equalTo(value);
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/animation/css/CSSAnimationUpdate.h b/third_party/WebKit/Source/core/animation/css/CSSAnimationUpdate.h
index 001b805..14e4299 100644
--- a/third_party/WebKit/Source/core/animation/css/CSSAnimationUpdate.h
+++ b/third_party/WebKit/Source/core/animation/css/CSSAnimationUpdate.h
@@ -106,8 +106,10 @@
     m_newTransitions = update.newTransitions();
     m_activeInterpolationsForAnimations =
         update.activeInterpolationsForAnimations();
-    m_activeInterpolationsForTransitions =
-        update.activeInterpolationsForTransitions();
+    m_activeInterpolationsForCustomTransitions =
+        update.activeInterpolationsForCustomTransitions();
+    m_activeInterpolationsForStandardTransitions =
+        update.activeInterpolationsForStandardTransitions();
     m_cancelledAnimationIndices = update.cancelledAnimationIndices();
     m_animationIndicesWithPauseToggled =
         update.animationIndicesWithPauseToggled();
@@ -121,7 +123,8 @@
     m_animationsWithUpdates.clear();
     m_newTransitions.clear();
     m_activeInterpolationsForAnimations.clear();
-    m_activeInterpolationsForTransitions.clear();
+    m_activeInterpolationsForCustomTransitions.clear();
+    m_activeInterpolationsForStandardTransitions.clear();
     m_cancelledAnimationIndices.clear();
     m_animationIndicesWithPauseToggled.clear();
     m_cancelledTransitions.clear();
@@ -234,15 +237,24 @@
   void adoptActiveInterpolationsForAnimations(ActiveInterpolationsMap& newMap) {
     newMap.swap(m_activeInterpolationsForAnimations);
   }
-  void adoptActiveInterpolationsForTransitions(
+  void adoptActiveInterpolationsForCustomTransitions(
       ActiveInterpolationsMap& newMap) {
-    newMap.swap(m_activeInterpolationsForTransitions);
+    newMap.swap(m_activeInterpolationsForCustomTransitions);
+  }
+  void adoptActiveInterpolationsForStandardTransitions(
+      ActiveInterpolationsMap& newMap) {
+    newMap.swap(m_activeInterpolationsForStandardTransitions);
   }
   const ActiveInterpolationsMap& activeInterpolationsForAnimations() const {
     return m_activeInterpolationsForAnimations;
   }
-  const ActiveInterpolationsMap& activeInterpolationsForTransitions() const {
-    return m_activeInterpolationsForTransitions;
+  const ActiveInterpolationsMap& activeInterpolationsForCustomTransitions()
+      const {
+    return m_activeInterpolationsForCustomTransitions;
+  }
+  const ActiveInterpolationsMap& activeInterpolationsForStandardTransitions()
+      const {
+    return m_activeInterpolationsForStandardTransitions;
   }
   ActiveInterpolationsMap& activeInterpolationsForAnimations() {
     return m_activeInterpolationsForAnimations;
@@ -256,7 +268,8 @@
            m_cancelledTransitions.isEmpty() &&
            m_finishedTransitions.isEmpty() &&
            m_activeInterpolationsForAnimations.isEmpty() &&
-           m_activeInterpolationsForTransitions.isEmpty() &&
+           m_activeInterpolationsForCustomTransitions.isEmpty() &&
+           m_activeInterpolationsForStandardTransitions.isEmpty() &&
            m_updatedCompositorKeyframes.isEmpty();
   }
 
@@ -285,7 +298,8 @@
   HashSet<PropertyHandle> m_finishedTransitions;
 
   ActiveInterpolationsMap m_activeInterpolationsForAnimations;
-  ActiveInterpolationsMap m_activeInterpolationsForTransitions;
+  ActiveInterpolationsMap m_activeInterpolationsForCustomTransitions;
+  ActiveInterpolationsMap m_activeInterpolationsForStandardTransitions;
 
   friend class PendingAnimationUpdate;
 };
diff --git a/third_party/WebKit/Source/core/animation/css/CSSAnimations.cpp b/third_party/WebKit/Source/core/animation/css/CSSAnimations.cpp
index 3f8a3c3..67ca8e7a 100644
--- a/third_party/WebKit/Source/core/animation/css/CSSAnimations.cpp
+++ b/third_party/WebKit/Source/core/animation/css/CSSAnimations.cpp
@@ -955,7 +955,7 @@
     for (const auto& entry : update.activeInterpolationsForAnimations())
       activeInterpolationsForTransitions.erase(entry.key);
   }
-  update.adoptActiveInterpolationsForTransitions(
+  update.adoptActiveInterpolationsForStandardTransitions(
       activeInterpolationsForTransitions);
 }
 
diff --git a/third_party/WebKit/Source/core/css/CSSBasicShapeValues.cpp b/third_party/WebKit/Source/core/css/CSSBasicShapeValues.cpp
index 3e78cad..93fa4124 100644
--- a/third_party/WebKit/Source/core/css/CSSBasicShapeValues.cpp
+++ b/third_party/WebKit/Source/core/css/CSSBasicShapeValues.cpp
@@ -130,9 +130,9 @@
 
 bool CSSBasicShapeCircleValue::equals(
     const CSSBasicShapeCircleValue& other) const {
-  return compareCSSValuePtr(m_centerX, other.m_centerX) &&
-         compareCSSValuePtr(m_centerY, other.m_centerY) &&
-         compareCSSValuePtr(m_radius, other.m_radius);
+  return dataEquivalent(m_centerX, other.m_centerX) &&
+         dataEquivalent(m_centerY, other.m_centerY) &&
+         dataEquivalent(m_radius, other.m_radius);
 }
 
 DEFINE_TRACE_AFTER_DISPATCH(CSSBasicShapeCircleValue) {
@@ -208,10 +208,10 @@
 
 bool CSSBasicShapeEllipseValue::equals(
     const CSSBasicShapeEllipseValue& other) const {
-  return compareCSSValuePtr(m_centerX, other.m_centerX) &&
-         compareCSSValuePtr(m_centerY, other.m_centerY) &&
-         compareCSSValuePtr(m_radiusX, other.m_radiusX) &&
-         compareCSSValuePtr(m_radiusY, other.m_radiusY);
+  return dataEquivalent(m_centerX, other.m_centerX) &&
+         dataEquivalent(m_centerY, other.m_centerY) &&
+         dataEquivalent(m_radiusX, other.m_radiusX) &&
+         dataEquivalent(m_radiusY, other.m_radiusY);
 }
 
 DEFINE_TRACE_AFTER_DISPATCH(CSSBasicShapeEllipseValue) {
@@ -411,14 +411,14 @@
 
 bool CSSBasicShapeInsetValue::equals(
     const CSSBasicShapeInsetValue& other) const {
-  return compareCSSValuePtr(m_top, other.m_top) &&
-         compareCSSValuePtr(m_right, other.m_right) &&
-         compareCSSValuePtr(m_bottom, other.m_bottom) &&
-         compareCSSValuePtr(m_left, other.m_left) &&
-         compareCSSValuePtr(m_topLeftRadius, other.m_topLeftRadius) &&
-         compareCSSValuePtr(m_topRightRadius, other.m_topRightRadius) &&
-         compareCSSValuePtr(m_bottomRightRadius, other.m_bottomRightRadius) &&
-         compareCSSValuePtr(m_bottomLeftRadius, other.m_bottomLeftRadius);
+  return dataEquivalent(m_top, other.m_top) &&
+         dataEquivalent(m_right, other.m_right) &&
+         dataEquivalent(m_bottom, other.m_bottom) &&
+         dataEquivalent(m_left, other.m_left) &&
+         dataEquivalent(m_topLeftRadius, other.m_topLeftRadius) &&
+         dataEquivalent(m_topRightRadius, other.m_topRightRadius) &&
+         dataEquivalent(m_bottomRightRadius, other.m_bottomRightRadius) &&
+         dataEquivalent(m_bottomLeftRadius, other.m_bottomLeftRadius);
 }
 
 DEFINE_TRACE_AFTER_DISPATCH(CSSBasicShapeInsetValue) {
diff --git a/third_party/WebKit/Source/core/css/CSSBorderImageSliceValue.cpp b/third_party/WebKit/Source/core/css/CSSBorderImageSliceValue.cpp
index 9d2e959..66cf3120 100644
--- a/third_party/WebKit/Source/core/css/CSSBorderImageSliceValue.cpp
+++ b/third_party/WebKit/Source/core/css/CSSBorderImageSliceValue.cpp
@@ -47,7 +47,7 @@
 
 bool CSSBorderImageSliceValue::equals(
     const CSSBorderImageSliceValue& other) const {
-  return m_fill == other.m_fill && compareCSSValuePtr(m_slices, other.m_slices);
+  return m_fill == other.m_fill && dataEquivalent(m_slices, other.m_slices);
 }
 
 DEFINE_TRACE_AFTER_DISPATCH(CSSBorderImageSliceValue) {
diff --git a/third_party/WebKit/Source/core/css/CSSCalculationValue.cpp b/third_party/WebKit/Source/core/css/CSSCalculationValue.cpp
index b1be505..1a9a382 100644
--- a/third_party/WebKit/Source/core/css/CSSCalculationValue.cpp
+++ b/third_party/WebKit/Source/core/css/CSSCalculationValue.cpp
@@ -143,7 +143,7 @@
 }
 
 bool CSSCalcValue::equals(const CSSCalcValue& other) const {
-  return compareCSSValuePtr(m_expression, other.m_expression);
+  return dataEquivalent(m_expression, other.m_expression);
 }
 
 double CSSCalcValue::clampToPermittedRange(double value) const {
@@ -243,11 +243,11 @@
     m_value->accumulateLengthArray(lengthArray, multiplier);
   }
 
-  bool equals(const CSSCalcExpressionNode& other) const override {
+  bool operator==(const CSSCalcExpressionNode& other) const override {
     if (getType() != other.getType())
       return false;
 
-    return compareCSSValuePtr(
+    return dataEquivalent(
         m_value, static_cast<const CSSCalcPrimitiveValue&>(other).m_value);
   }
 
@@ -556,14 +556,14 @@
                         m_rightSide->customCSSText(), m_operator);
   }
 
-  bool equals(const CSSCalcExpressionNode& exp) const override {
+  bool operator==(const CSSCalcExpressionNode& exp) const override {
     if (getType() != exp.getType())
       return false;
 
     const CSSCalcBinaryOperation& other =
         static_cast<const CSSCalcBinaryOperation&>(exp);
-    return compareCSSValuePtr(m_leftSide, other.m_leftSide) &&
-           compareCSSValuePtr(m_rightSide, other.m_rightSide) &&
+    return dataEquivalent(m_leftSide, other.m_leftSide) &&
+           dataEquivalent(m_rightSide, other.m_rightSide) &&
            m_operator == other.m_operator;
   }
 
diff --git a/third_party/WebKit/Source/core/css/CSSCalculationValue.h b/third_party/WebKit/Source/core/css/CSSCalculationValue.h
index 086aba2..46ce3d7 100644
--- a/third_party/WebKit/Source/core/css/CSSCalculationValue.h
+++ b/third_party/WebKit/Source/core/css/CSSCalculationValue.h
@@ -78,7 +78,7 @@
                                           PixelsAndPercent&,
                                           float multiplier = 1) const = 0;
   virtual String customCSSText() const = 0;
-  virtual bool equals(const CSSCalcExpressionNode& other) const {
+  virtual bool operator==(const CSSCalcExpressionNode& other) const {
     return m_category == other.m_category && m_isInteger == other.m_isInteger;
   }
   virtual Type getType() const = 0;
diff --git a/third_party/WebKit/Source/core/css/CSSComputedStyleDeclaration.cpp b/third_party/WebKit/Source/core/css/CSSComputedStyleDeclaration.cpp
index 93b0508..f140e9e88 100644
--- a/third_party/WebKit/Source/core/css/CSSComputedStyleDeclaration.cpp
+++ b/third_party/WebKit/Source/core/css/CSSComputedStyleDeclaration.cpp
@@ -464,7 +464,7 @@
     }
   }
   const CSSValue* value = getPropertyCSSValue(propertyID);
-  return value && propertyValue && value->equals(*propertyValue);
+  return dataEquivalent(value, propertyValue);
 }
 
 MutableStylePropertySet* CSSComputedStyleDeclaration::copyProperties() const {
diff --git a/third_party/WebKit/Source/core/css/CSSCrossfadeValue.cpp b/third_party/WebKit/Source/core/css/CSSCrossfadeValue.cpp
index 2829755..4aabbb8e 100644
--- a/third_party/WebKit/Source/core/css/CSSCrossfadeValue.cpp
+++ b/third_party/WebKit/Source/core/css/CSSCrossfadeValue.cpp
@@ -286,9 +286,9 @@
 }
 
 bool CSSCrossfadeValue::equals(const CSSCrossfadeValue& other) const {
-  return compareCSSValuePtr(m_fromValue, other.m_fromValue) &&
-         compareCSSValuePtr(m_toValue, other.m_toValue) &&
-         compareCSSValuePtr(m_percentageValue, other.m_percentageValue);
+  return dataEquivalent(m_fromValue, other.m_fromValue) &&
+         dataEquivalent(m_toValue, other.m_toValue) &&
+         dataEquivalent(m_percentageValue, other.m_percentageValue);
 }
 
 DEFINE_TRACE_AFTER_DISPATCH(CSSCrossfadeValue) {
diff --git a/third_party/WebKit/Source/core/css/CSSCursorImageValue.cpp b/third_party/WebKit/Source/core/css/CSSCursorImageValue.cpp
index 9309d823..a3af03c5 100644
--- a/third_party/WebKit/Source/core/css/CSSCursorImageValue.cpp
+++ b/third_party/WebKit/Source/core/css/CSSCursorImageValue.cpp
@@ -54,7 +54,7 @@
   return (m_hotSpotSpecified
               ? other.m_hotSpotSpecified && m_hotSpot == other.m_hotSpot
               : !other.m_hotSpotSpecified) &&
-         compareCSSValuePtr(m_imageValue, other.m_imageValue);
+         dataEquivalent(m_imageValue, other.m_imageValue);
 }
 
 DEFINE_TRACE_AFTER_DISPATCH(CSSCursorImageValue) {
diff --git a/third_party/WebKit/Source/core/css/CSSGradientValue.cpp b/third_party/WebKit/Source/core/css/CSSGradientValue.cpp
index c07244c..7887781 100644
--- a/third_party/WebKit/Source/core/css/CSSGradientValue.cpp
+++ b/third_party/WebKit/Source/core/css/CSSGradientValue.cpp
@@ -892,34 +892,32 @@
 bool CSSLinearGradientValue::equals(const CSSLinearGradientValue& other) const {
   if (m_gradientType == CSSDeprecatedLinearGradient)
     return other.m_gradientType == m_gradientType &&
-           compareCSSValuePtr(m_firstX, other.m_firstX) &&
-           compareCSSValuePtr(m_firstY, other.m_firstY) &&
-           compareCSSValuePtr(m_secondX, other.m_secondX) &&
-           compareCSSValuePtr(m_secondY, other.m_secondY) &&
+           dataEquivalent(m_firstX, other.m_firstX) &&
+           dataEquivalent(m_firstY, other.m_firstY) &&
+           dataEquivalent(m_secondX, other.m_secondX) &&
+           dataEquivalent(m_secondY, other.m_secondY) &&
            m_stops == other.m_stops;
 
   if (m_repeating != other.m_repeating)
     return false;
 
   if (m_angle)
-    return compareCSSValuePtr(m_angle, other.m_angle) &&
-           m_stops == other.m_stops;
+    return dataEquivalent(m_angle, other.m_angle) && m_stops == other.m_stops;
 
   if (other.m_angle)
     return false;
 
   bool equalXandY = false;
-  if (m_firstX && m_firstY)
-    equalXandY = compareCSSValuePtr(m_firstX, other.m_firstX) &&
-                 compareCSSValuePtr(m_firstY, other.m_firstY);
-  else if (m_firstX)
-    equalXandY =
-        compareCSSValuePtr(m_firstX, other.m_firstX) && !other.m_firstY;
-  else if (m_firstY)
-    equalXandY =
-        compareCSSValuePtr(m_firstY, other.m_firstY) && !other.m_firstX;
-  else
+  if (m_firstX && m_firstY) {
+    equalXandY = dataEquivalent(m_firstX, other.m_firstX) &&
+                 dataEquivalent(m_firstY, other.m_firstY);
+  } else if (m_firstX) {
+    equalXandY = dataEquivalent(m_firstX, other.m_firstX) && !other.m_firstY;
+  } else if (m_firstY) {
+    equalXandY = dataEquivalent(m_firstY, other.m_firstY) && !other.m_firstX;
+  } else {
     equalXandY = !other.m_firstX && !other.m_firstY;
+  }
 
   return equalXandY && m_stops == other.m_stops;
 }
@@ -1263,29 +1261,28 @@
 bool CSSRadialGradientValue::equals(const CSSRadialGradientValue& other) const {
   if (m_gradientType == CSSDeprecatedRadialGradient)
     return other.m_gradientType == m_gradientType &&
-           compareCSSValuePtr(m_firstX, other.m_firstX) &&
-           compareCSSValuePtr(m_firstY, other.m_firstY) &&
-           compareCSSValuePtr(m_secondX, other.m_secondX) &&
-           compareCSSValuePtr(m_secondY, other.m_secondY) &&
-           compareCSSValuePtr(m_firstRadius, other.m_firstRadius) &&
-           compareCSSValuePtr(m_secondRadius, other.m_secondRadius) &&
+           dataEquivalent(m_firstX, other.m_firstX) &&
+           dataEquivalent(m_firstY, other.m_firstY) &&
+           dataEquivalent(m_secondX, other.m_secondX) &&
+           dataEquivalent(m_secondY, other.m_secondY) &&
+           dataEquivalent(m_firstRadius, other.m_firstRadius) &&
+           dataEquivalent(m_secondRadius, other.m_secondRadius) &&
            m_stops == other.m_stops;
 
   if (m_repeating != other.m_repeating)
     return false;
 
   bool equalXandY = false;
-  if (m_firstX && m_firstY)
-    equalXandY = compareCSSValuePtr(m_firstX, other.m_firstX) &&
-                 compareCSSValuePtr(m_firstY, other.m_firstY);
-  else if (m_firstX)
-    equalXandY =
-        compareCSSValuePtr(m_firstX, other.m_firstX) && !other.m_firstY;
-  else if (m_firstY)
-    equalXandY =
-        compareCSSValuePtr(m_firstY, other.m_firstY) && !other.m_firstX;
-  else
+  if (m_firstX && m_firstY) {
+    equalXandY = dataEquivalent(m_firstX, other.m_firstX) &&
+                 dataEquivalent(m_firstY, other.m_firstY);
+  } else if (m_firstX) {
+    equalXandY = dataEquivalent(m_firstX, other.m_firstX) && !other.m_firstY;
+  } else if (m_firstY) {
+    equalXandY = dataEquivalent(m_firstY, other.m_firstY) && !other.m_firstX;
+  } else {
     equalXandY = !other.m_firstX && !other.m_firstY;
+  }
 
   if (!equalXandY)
     return false;
@@ -1294,16 +1291,16 @@
   bool equalSizingBehavior = true;
   bool equalHorizontalAndVerticalSize = true;
 
-  if (m_shape)
-    equalShape = compareCSSValuePtr(m_shape, other.m_shape);
-  else if (m_sizingBehavior)
+  if (m_shape) {
+    equalShape = dataEquivalent(m_shape, other.m_shape);
+  } else if (m_sizingBehavior) {
     equalSizingBehavior =
-        compareCSSValuePtr(m_sizingBehavior, other.m_sizingBehavior);
-  else if (m_endHorizontalSize && m_endVerticalSize)
+        dataEquivalent(m_sizingBehavior, other.m_sizingBehavior);
+  } else if (m_endHorizontalSize && m_endVerticalSize) {
     equalHorizontalAndVerticalSize =
-        compareCSSValuePtr(m_endHorizontalSize, other.m_endHorizontalSize) &&
-        compareCSSValuePtr(m_endVerticalSize, other.m_endVerticalSize);
-  else {
+        dataEquivalent(m_endHorizontalSize, other.m_endHorizontalSize) &&
+        dataEquivalent(m_endVerticalSize, other.m_endVerticalSize);
+  } else {
     equalShape = !other.m_shape;
     equalSizingBehavior = !other.m_sizingBehavior;
     equalHorizontalAndVerticalSize =
diff --git a/third_party/WebKit/Source/core/css/CSSGradientValue.h b/third_party/WebKit/Source/core/css/CSSGradientValue.h
index 8aa8553..0fcead9 100644
--- a/third_party/WebKit/Source/core/css/CSSGradientValue.h
+++ b/third_party/WebKit/Source/core/css/CSSGradientValue.h
@@ -64,8 +64,8 @@
   Member<CSSValue> m_color;
   bool m_colorIsDerivedFromElement;
   bool operator==(const CSSGradientColorStop& other) const {
-    return compareCSSValuePtr(m_color, other.m_color) &&
-           compareCSSValuePtr(m_position, other.m_position);
+    return dataEquivalent(m_color, other.m_color) &&
+           dataEquivalent(m_position, other.m_position);
   }
   bool isHint() const {
     ASSERT(m_color || m_position);
diff --git a/third_party/WebKit/Source/core/css/CSSProperties.json5 b/third_party/WebKit/Source/core/css/CSSProperties.json5
index 73271fe7..d7cbdf5 100644
--- a/third_party/WebKit/Source/core/css/CSSProperties.json5
+++ b/third_party/WebKit/Source/core/css/CSSProperties.json5
@@ -2681,6 +2681,11 @@
       runtime_flag: "CSSGridLayout",
     },
     {
+      name: "place-content",
+      longhands: "align-content;justify-content",
+      runtime_flag: "CSSGridLayout",
+    },
+    {
       name: "grid-area",
       longhands: "grid-row-start;grid-column-start;grid-row-end;grid-column-end",
       runtime_flag: "CSSGridLayout",
diff --git a/third_party/WebKit/Source/core/css/CSSProperty.cpp b/third_party/WebKit/Source/core/css/CSSProperty.cpp
index b6740a8..b3adce7 100644
--- a/third_party/WebKit/Source/core/css/CSSProperty.cpp
+++ b/third_party/WebKit/Source/core/css/CSSProperty.cpp
@@ -289,7 +289,7 @@
 }
 
 bool CSSProperty::operator==(const CSSProperty& other) const {
-  return m_value->equals(*other.m_value) &&
+  return dataEquivalent(m_value, other.m_value) &&
          isImportant() == other.isImportant();
 }
 
diff --git a/third_party/WebKit/Source/core/css/CSSPropertyIDTemplates.h b/third_party/WebKit/Source/core/css/CSSPropertyIDTemplates.h
index 7c95cbe..b2e949e6 100644
--- a/third_party/WebKit/Source/core/css/CSSPropertyIDTemplates.h
+++ b/third_party/WebKit/Source/core/css/CSSPropertyIDTemplates.h
@@ -19,11 +19,10 @@
     : GenericHashTraits<blink::CSSPropertyID> {
   static const bool emptyValueIsZero = true;
   static void constructDeletedValue(blink::CSSPropertyID& slot, bool) {
-    slot =
-        static_cast<blink::CSSPropertyID>(blink::lastUnresolvedCSSProperty + 1);
+    slot = static_cast<blink::CSSPropertyID>(blink::numCSSPropertyIDs);
   }
   static bool isDeletedValue(blink::CSSPropertyID value) {
-    return value == (blink::lastUnresolvedCSSProperty + 1);
+    return value == blink::numCSSPropertyIDs;
   }
 };
 }  // namespace WTF
diff --git a/third_party/WebKit/Source/core/css/CSSQuadValue.h b/third_party/WebKit/Source/core/css/CSSQuadValue.h
index 3cfbb66..28ec9d3 100644
--- a/third_party/WebKit/Source/core/css/CSSQuadValue.h
+++ b/third_party/WebKit/Source/core/css/CSSQuadValue.h
@@ -49,10 +49,10 @@
   String customCSSText() const;
 
   bool equals(const CSSQuadValue& other) const {
-    return compareCSSValuePtr(m_top, other.m_top) &&
-           compareCSSValuePtr(m_right, other.m_right) &&
-           compareCSSValuePtr(m_left, other.m_left) &&
-           compareCSSValuePtr(m_bottom, other.m_bottom);
+    return dataEquivalent(m_top, other.m_top) &&
+           dataEquivalent(m_right, other.m_right) &&
+           dataEquivalent(m_left, other.m_left) &&
+           dataEquivalent(m_bottom, other.m_bottom);
   }
 
   DECLARE_TRACE_AFTER_DISPATCH();
diff --git a/third_party/WebKit/Source/core/css/CSSReflectValue.cpp b/third_party/WebKit/Source/core/css/CSSReflectValue.cpp
index 918f99c..7bed6aa 100644
--- a/third_party/WebKit/Source/core/css/CSSReflectValue.cpp
+++ b/third_party/WebKit/Source/core/css/CSSReflectValue.cpp
@@ -39,8 +39,8 @@
 
 bool CSSReflectValue::equals(const CSSReflectValue& other) const {
   return m_direction == other.m_direction &&
-         compareCSSValuePtr(m_offset, other.m_offset) &&
-         compareCSSValuePtr(m_mask, other.m_mask);
+         dataEquivalent(m_offset, other.m_offset) &&
+         dataEquivalent(m_mask, other.m_mask);
 }
 
 DEFINE_TRACE_AFTER_DISPATCH(CSSReflectValue) {
diff --git a/third_party/WebKit/Source/core/css/CSSShadowValue.cpp b/third_party/WebKit/Source/core/css/CSSShadowValue.cpp
index 6ae71871..8bfd1f2 100644
--- a/third_party/WebKit/Source/core/css/CSSShadowValue.cpp
+++ b/third_party/WebKit/Source/core/css/CSSShadowValue.cpp
@@ -76,11 +76,10 @@
 }
 
 bool CSSShadowValue::equals(const CSSShadowValue& other) const {
-  return compareCSSValuePtr(color, other.color) &&
-         compareCSSValuePtr(x, other.x) && compareCSSValuePtr(y, other.y) &&
-         compareCSSValuePtr(blur, other.blur) &&
-         compareCSSValuePtr(spread, other.spread) &&
-         compareCSSValuePtr(style, other.style);
+  return dataEquivalent(color, other.color) && dataEquivalent(x, other.x) &&
+         dataEquivalent(y, other.y) && dataEquivalent(blur, other.blur) &&
+         dataEquivalent(spread, other.spread) &&
+         dataEquivalent(style, other.style);
 }
 
 DEFINE_TRACE_AFTER_DISPATCH(CSSShadowValue) {
diff --git a/third_party/WebKit/Source/core/css/CSSValue.cpp b/third_party/WebKit/Source/core/css/CSSValue.cpp
index 257b780b..3098e4ef 100644
--- a/third_party/WebKit/Source/core/css/CSSValue.cpp
+++ b/third_party/WebKit/Source/core/css/CSSValue.cpp
@@ -141,7 +141,7 @@
       static_cast<const ChildClassType&>(second));
 }
 
-bool CSSValue::equals(const CSSValue& other) const {
+bool CSSValue::operator==(const CSSValue& other) const {
   if (m_classType == other.m_classType) {
     switch (getClassType()) {
       case BasicShapeCircleClass:
diff --git a/third_party/WebKit/Source/core/css/CSSValue.h b/third_party/WebKit/Source/core/css/CSSValue.h
index 23ad709f..8ac3077e 100644
--- a/third_party/WebKit/Source/core/css/CSSValue.h
+++ b/third_party/WebKit/Source/core/css/CSSValue.h
@@ -22,6 +22,7 @@
 #define CSSValue_h
 
 #include "core/CoreExport.h"
+#include "core/style/DataEquivalency.h"
 #include "platform/heap/Handle.h"
 #include "wtf/RefPtr.h"
 
@@ -151,7 +152,7 @@
   bool mayContainUrl() const;
   void reResolveUrl(const Document&) const;
 
-  bool equals(const CSSValue&) const;
+  bool operator==(const CSSValue&) const;
 
   void finalizeGarbageCollectedObject();
   DEFINE_INLINE_TRACE_AFTER_DISPATCH() {}
@@ -261,50 +262,18 @@
     const HeapVector<Member<CSSValueType>, inlineCapacity>& firstVector,
     const HeapVector<Member<CSSValueType>, inlineCapacity>& secondVector) {
   size_t size = firstVector.size();
-  if (size != secondVector.size())
-    return false;
-
-  for (size_t i = 0; i < size; i++) {
-    const Member<CSSValueType>& firstPtr = firstVector[i];
-    const Member<CSSValueType>& secondPtr = secondVector[i];
-    if (firstPtr == secondPtr ||
-        (firstPtr && secondPtr && firstPtr->equals(*secondPtr)))
-      continue;
+  if (size != secondVector.size()) {
     return false;
   }
+
+  for (size_t i = 0; i < size; i++) {
+    if (!dataEquivalent(firstVector[i], secondVector[i])) {
+      return false;
+    }
+  }
   return true;
 }
 
-template <typename CSSValueType>
-inline bool compareCSSValuePtr(const RefPtr<CSSValueType>& first,
-                               const RefPtr<CSSValueType>& second) {
-  if (first == second)
-    return true;
-  if (!first || !second)
-    return false;
-  return first->equals(*second);
-}
-
-template <typename CSSValueType>
-inline bool compareCSSValuePtr(const CSSValueType* first,
-                               const CSSValueType* second) {
-  if (first == second)
-    return true;
-  if (!first || !second)
-    return false;
-  return first->equals(*second);
-}
-
-template <typename CSSValueType>
-inline bool compareCSSValuePtr(const Member<CSSValueType>& first,
-                               const Member<CSSValueType>& second) {
-  if (first == second)
-    return true;
-  if (!first || !second)
-    return false;
-  return first->equals(*second);
-}
-
 #define DEFINE_CSS_VALUE_TYPE_CASTS(thisType, predicate)         \
   DEFINE_TYPE_CASTS(thisType, CSSValue, value, value->predicate, \
                     value.predicate)
diff --git a/third_party/WebKit/Source/core/css/CSSValueList.cpp b/third_party/WebKit/Source/core/css/CSSValueList.cpp
index 2e768e0..fac73e7 100644
--- a/third_party/WebKit/Source/core/css/CSSValueList.cpp
+++ b/third_party/WebKit/Source/core/css/CSSValueList.cpp
@@ -47,7 +47,7 @@
   bool found = false;
   for (int index = m_values.size() - 1; index >= 0; --index) {
     Member<const CSSValue>& value = m_values.at(index);
-    if (value && value->equals(val)) {
+    if (value && *value == val) {
       m_values.remove(index);
       found = true;
     }
@@ -59,8 +59,9 @@
 bool CSSValueList::hasValue(const CSSValue& val) const {
   for (size_t index = 0; index < m_values.size(); index++) {
     const Member<const CSSValue>& value = m_values.at(index);
-    if (value && value->equals(val))
+    if (value && *value == val) {
       return true;
+    }
   }
   return false;
 }
diff --git a/third_party/WebKit/Source/core/css/CSSValuePair.h b/third_party/WebKit/Source/core/css/CSSValuePair.h
index 6e7b9bb..06213db 100644
--- a/third_party/WebKit/Source/core/css/CSSValuePair.h
+++ b/third_party/WebKit/Source/core/css/CSSValuePair.h
@@ -50,8 +50,8 @@
 
   bool equals(const CSSValuePair& other) const {
     ASSERT(m_identicalValuesPolicy == other.m_identicalValuesPolicy);
-    return compareCSSValuePtr(m_first, other.m_first) &&
-           compareCSSValuePtr(m_second, other.m_second);
+    return dataEquivalent(m_first, other.m_first) &&
+           dataEquivalent(m_second, other.m_second);
   }
 
   DECLARE_TRACE_AFTER_DISPATCH();
diff --git a/third_party/WebKit/Source/core/css/CSSValueTestHelper.h b/third_party/WebKit/Source/core/css/CSSValueTestHelper.h
index f418285..70f52715 100644
--- a/third_party/WebKit/Source/core/css/CSSValueTestHelper.h
+++ b/third_party/WebKit/Source/core/css/CSSValueTestHelper.h
@@ -55,10 +55,6 @@
 
 namespace blink {
 
-inline bool operator==(const CSSValue& a, const CSSValue& b) {
-  return a.equals(b);
-}
-
 inline void PrintTo(const CSSValue& cssValue,
                     ::std::ostream* os,
                     const char* typeName = "CSSValue") {
diff --git a/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp b/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp
index f93e329..6c90124 100644
--- a/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp
+++ b/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp
@@ -1341,7 +1341,7 @@
 static const CSSValue& valueForBorderRadiusCorner(LengthSize radius,
                                                   const ComputedStyle& style) {
   CSSValueList& list = *valuesForBorderRadiusCorner(radius, style);
-  if (list.item(0).equals(list.item(1)))
+  if (list.item(0) == list.item(1))
     return list.item(0);
   return list;
 }
@@ -1582,9 +1582,9 @@
   if (!topValue || !rightValue || !bottomValue || !leftValue)
     return nullptr;
 
-  bool showLeft = !compareCSSValuePtr(rightValue, leftValue);
-  bool showBottom = !compareCSSValuePtr(topValue, bottomValue) || showLeft;
-  bool showRight = !compareCSSValuePtr(topValue, rightValue) || showBottom;
+  bool showLeft = !dataEquivalent(rightValue, leftValue);
+  bool showBottom = !dataEquivalent(topValue, bottomValue) || showLeft;
+  bool showRight = !dataEquivalent(topValue, rightValue) || showBottom;
 
   list->append(*topValue);
   if (showRight)
@@ -1850,8 +1850,10 @@
   // this serialization.
   CSSValue* ligaturesValue = valueForFontVariantLigatures(style);
   CSSValue* numericValue = valueForFontVariantNumeric(style);
-  if (!ligaturesValue->equals(*CSSIdentifierValue::create(CSSValueNormal)) ||
-      !numericValue->equals(*CSSIdentifierValue::create(CSSValueNormal)))
+  if (!dataEquivalent<CSSValue>(ligaturesValue,
+                                CSSIdentifierValue::create(CSSValueNormal)) ||
+      !dataEquivalent<CSSValue>(numericValue,
+                                CSSIdentifierValue::create(CSSValueNormal)))
     return nullptr;
 
   CSSIdentifierValue* capsValue = valueForFontVariantCaps(style);
@@ -2314,6 +2316,13 @@
       return CSSIdentifierValue::create(style.display());
     case CSSPropertyEmptyCells:
       return CSSIdentifierValue::create(style.emptyCells());
+    case CSSPropertyPlaceContent: {
+      // TODO (jfernandez): The spec states that we should return the specified
+      // value.
+      return valuesForShorthandProperty(placeContentShorthand(), style,
+                                        layoutObject, styledNode,
+                                        allowVisitedStyle);
+    }
     case CSSPropertyAlignContent:
       return valueForContentPositionAndDistributionWithOverflowAlignment(
           style.alignContent(), CSSValueStretch);
@@ -3258,9 +3267,8 @@
                                           CSSPropertyBorderBottom,
                                           CSSPropertyBorderLeft};
       for (size_t i = 0; i < WTF_ARRAY_LENGTH(properties); ++i) {
-        if (!compareCSSValuePtr<CSSValue>(
-                value, get(properties[i], style, layoutObject, styledNode,
-                           allowVisitedStyle)))
+        if (!dataEquivalent(value, get(properties[i], style, layoutObject,
+                                       styledNode, allowVisitedStyle)))
           return nullptr;
       }
       return value;
diff --git a/third_party/WebKit/Source/core/css/FontFaceSet.cpp b/third_party/WebKit/Source/core/css/FontFaceSet.cpp
index a7e2c3a..00ecea4a 100644
--- a/third_party/WebKit/Source/core/css/FontFaceSet.cpp
+++ b/third_party/WebKit/Source/core/css/FontFaceSet.cpp
@@ -243,6 +243,13 @@
 }
 
 ScriptPromise FontFaceSet::ready(ScriptState* scriptState) {
+  if (m_ready->getState() != ReadyProperty::Pending) {
+    // |m_ready| is already resolved, but there may be pending stylesheet
+    // changes and/or layout operations that may cause another font loads.
+    // So synchronously update style and layout here.
+    // This may trigger font loads, and replace |m_ready| with a new Promise.
+    document()->updateStyleAndLayout();
+  }
   return m_ready->promise(scriptState->world());
 }
 
diff --git a/third_party/WebKit/Source/core/css/RemoteFontFaceSource.cpp b/third_party/WebKit/Source/core/css/RemoteFontFaceSource.cpp
index c9d12e30a..aea3974f 100644
--- a/third_party/WebKit/Source/core/css/RemoteFontFaceSource.cpp
+++ b/third_party/WebKit/Source/core/css/RemoteFontFaceSource.cpp
@@ -65,8 +65,6 @@
                                           : FontLoadHistograms::FromUnknown,
                    m_display),
       m_isInterventionTriggered(false) {
-  m_font->addClient(this);
-
   if (shouldTriggerWebFontsIntervention()) {
     m_isInterventionTriggered = true;
     m_period = SwapPeriod;
@@ -75,6 +73,9 @@
         "Slow network is detected. Fallback font will be used while loading: " +
             m_font->url().elidedString()));
   }
+
+  // Note: this may call notifyFinished() and clear m_font.
+  m_font->addClient(this);
 }
 
 RemoteFontFaceSource::~RemoteFontFaceSource() {}
diff --git a/third_party/WebKit/Source/core/css/StylePropertySerializer.cpp b/third_party/WebKit/Source/core/css/StylePropertySerializer.cpp
index 9314b06a..7ad9a76 100644
--- a/third_party/WebKit/Source/core/css/StylePropertySerializer.cpp
+++ b/third_party/WebKit/Source/core/css/StylePropertySerializer.cpp
@@ -53,7 +53,7 @@
         continue;
       if (static_cast<unsigned>(m_allIndex) >= i)
         continue;
-      if (property.value().equals(allProperty.value()) &&
+      if (property.value() == allProperty.value() &&
           property.isImportant() == allProperty.isImportant())
         continue;
       m_needToExpandAll = true;
@@ -366,7 +366,7 @@
       longhands[0]->isPendingSubstitutionValue()) {
     bool success = true;
     for (int i = 1; i < longhandCount; i++) {
-      if (!longhands[i]->equals(*longhands[0])) {
+      if (!dataEquivalent(longhands[i], longhands[0])) {
         // This should just return emptyString but some shorthands currently
         // allow 'initial' for their longhands.
         success = false;
@@ -454,6 +454,8 @@
       return getShorthandValue(gridAreaShorthand(), " / ");
     case CSSPropertyGridGap:
       return getShorthandValue(gridGapShorthand());
+    case CSSPropertyPlaceContent:
+      return placeContentPropertyValue();
     case CSSPropertyFont:
       return fontValue();
     case CSSPropertyFontVariant:
@@ -663,9 +665,9 @@
       m_propertySet.propertyAt(bottomValueIndex);
   PropertyValueForSerializer left = m_propertySet.propertyAt(leftValueIndex);
 
-  bool showLeft = !right.value()->equals(*left.value());
-  bool showBottom = !top.value()->equals(*bottom.value()) || showLeft;
-  bool showRight = !top.value()->equals(*right.value()) || showBottom;
+  bool showLeft = !dataEquivalent(right.value(), left.value());
+  bool showBottom = !dataEquivalent(top.value(), bottom.value()) || showLeft;
+  bool showRight = !dataEquivalent(top.value(), right.value()) || showBottom;
 
   StringBuilder result;
   result.append(top.value()->cssText());
@@ -848,6 +850,13 @@
   return res;
 }
 
+String StylePropertySerializer::placeContentPropertyValue() const {
+  String value = getCommonValue(placeContentShorthand());
+  if (value.isNull() || value.isEmpty())
+    return getShorthandValue(placeContentShorthand());
+  return value;
+}
+
 String StylePropertySerializer::borderPropertyValue() const {
   const StylePropertyShorthand properties[3] = {
       borderWidthShorthand(), borderStyleShorthand(), borderColorShorthand()};
diff --git a/third_party/WebKit/Source/core/css/StylePropertySerializer.h b/third_party/WebKit/Source/core/css/StylePropertySerializer.h
index d4ecf27..baf4267 100644
--- a/third_party/WebKit/Source/core/css/StylePropertySerializer.h
+++ b/third_party/WebKit/Source/core/css/StylePropertySerializer.h
@@ -44,6 +44,7 @@
 
  private:
   String getCommonValue(const StylePropertyShorthand&) const;
+  String placeContentPropertyValue() const;
   String borderPropertyValue() const;
   String getLayeredShorthandValue(const StylePropertyShorthand&) const;
   String get4Values(const StylePropertyShorthand&) const;
diff --git a/third_party/WebKit/Source/core/css/StylePropertySet.cpp b/third_party/WebKit/Source/core/css/StylePropertySet.cpp
index 3049d035..78a70e9 100644
--- a/third_party/WebKit/Source/core/css/StylePropertySet.cpp
+++ b/third_party/WebKit/Source/core/css/StylePropertySet.cpp
@@ -499,7 +499,7 @@
   int foundPropertyIndex = findPropertyIndex(propertyID);
   if (foundPropertyIndex == -1)
     return false;
-  return propertyAt(foundPropertyIndex).value().equals(propertyValue);
+  return propertyAt(foundPropertyIndex).value() == propertyValue;
 }
 
 void MutableStylePropertySet::removeEquivalentProperties(
diff --git a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
index 1e5b59d5..9f6856f9 100644
--- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
+++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
@@ -3493,6 +3493,53 @@
   return true;
 }
 
+static CSSValue* consumeSimplifiedContentPosition(CSSParserTokenRange& range) {
+  CSSValueID id = range.peek().id();
+  if (identMatches<CSSValueNormal, CSSValueBaseline, CSSValueLastBaseline>(
+          id)) {
+    return CSSContentDistributionValue::create(
+        CSSValueInvalid, range.consumeIncludingWhitespace().id(),
+        CSSValueInvalid);
+  }
+  if (identMatches<CSSValueSpaceBetween, CSSValueSpaceAround,
+                   CSSValueSpaceEvenly, CSSValueStretch>(id)) {
+    return CSSContentDistributionValue::create(
+        range.consumeIncludingWhitespace().id(), CSSValueInvalid,
+        CSSValueInvalid);
+  }
+  if (identMatches<CSSValueStart, CSSValueEnd, CSSValueCenter,
+                   CSSValueFlexStart, CSSValueFlexEnd, CSSValueLeft,
+                   CSSValueRight>(id)) {
+    return CSSContentDistributionValue::create(
+        CSSValueInvalid, range.consumeIncludingWhitespace().id(),
+        CSSValueInvalid);
+  }
+  return nullptr;
+}
+
+bool CSSPropertyParser::consumePlaceContentShorthand(bool important) {
+  DCHECK(RuntimeEnabledFeatures::cssGridLayoutEnabled());
+  DCHECK_EQ(shorthandForProperty(CSSPropertyPlaceContent).length(),
+            static_cast<unsigned>(2));
+
+  CSSValue* alignContentValue = consumeSimplifiedContentPosition(m_range);
+  if (!alignContentValue)
+    return false;
+  CSSValue* justifyContentValue =
+      m_range.atEnd() ? alignContentValue
+                      : consumeSimplifiedContentPosition(m_range);
+  if (!justifyContentValue)
+    return false;
+  if (!m_range.atEnd())
+    return false;
+
+  addProperty(CSSPropertyAlignContent, CSSPropertyPlaceContent,
+              *alignContentValue, important);
+  addProperty(CSSPropertyJustifyContent, CSSPropertyPlaceContent,
+              *justifyContentValue, important);
+  return true;
+}
+
 bool CSSPropertyParser::parseShorthand(CSSPropertyID unresolvedProperty,
                                        bool important) {
   CSSPropertyID property = resolveCSSPropertyID(unresolvedProperty);
@@ -3752,6 +3799,8 @@
       return consumeGridTemplateShorthand(CSSPropertyGridTemplate, important);
     case CSSPropertyGrid:
       return consumeGridShorthand(important);
+    case CSSPropertyPlaceContent:
+      return consumePlaceContentShorthand(important);
     default:
       return false;
   }
diff --git a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.h b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.h
index 4f291e7..89f2abf 100644
--- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.h
+++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.h
@@ -101,6 +101,8 @@
   bool consumeGridShorthand(bool important);
   bool consumeGridAreaShorthand(bool important);
 
+  bool consumePlaceContentShorthand(bool important);
+
   bool consumeFont(bool important);
   bool consumeFontVariantShorthand(bool important);
   bool consumeSystemFont(bool important);
diff --git a/third_party/WebKit/Source/core/css/resolver/SharedStyleFinder.cpp b/third_party/WebKit/Source/core/css/resolver/SharedStyleFinder.cpp
index 6c0529d..02f4f52 100644
--- a/third_party/WebKit/Source/core/css/resolver/SharedStyleFinder.cpp
+++ b/third_party/WebKit/Source/core/css/resolver/SharedStyleFinder.cpp
@@ -59,6 +59,16 @@
 
 using namespace HTMLNames;
 
+inline ComputedStyle* getElementStyle(Element& element) {
+  if (element.needsReattachLayoutTree()) {
+    StyleReattachData styleReattachData =
+        element.document().getStyleReattachData(element);
+    if (styleReattachData.computedStyle)
+      return styleReattachData.computedStyle.get();
+  }
+  return element.mutableComputedStyle();
+}
+
 bool SharedStyleFinder::canShareStyleWithControl(Element& candidate) const {
   if (!isHTMLInputElement(candidate) || !isHTMLInputElement(element()))
     return false;
@@ -228,21 +238,21 @@
   if (element() == candidate)
     return false;
   Element* parent = candidate.parentOrShadowHostElement();
-  const ComputedStyle* style = candidate.computedStyle();
+  const ComputedStyle* style = getElementStyle(candidate);
   if (!style)
     return false;
   if (!style->isSharable())
     return false;
   if (!parent)
     return false;
-  if (element().parentOrShadowHostElement()->computedStyle() !=
-      parent->computedStyle())
+  if (getElementStyle(*element().parentOrShadowHostElement()) !=
+      getElementStyle(*parent))
     return false;
   if (candidate.tagQName() != element().tagQName())
     return false;
   if (candidate.inlineStyle())
     return false;
-  if (candidate.needsStyleRecalc())
+  if (candidate.needsStyleRecalc() && !candidate.needsReattachLayoutTree())
     return false;
   if (candidate.isSVGElement() &&
       toSVGElement(candidate).animatedSMILStyleProperties())
@@ -407,7 +417,7 @@
     return nullptr;
   }
 
-  return shareElement->mutableComputedStyle();
+  return getElementStyle(*shareElement);
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/css/resolver/StyleResolver.cpp b/third_party/WebKit/Source/core/css/resolver/StyleResolver.cpp
index b8f65d26..1dd8cab 100644
--- a/third_party/WebKit/Source/core/css/resolver/StyleResolver.cpp
+++ b/third_party/WebKit/Source/core/css/resolver/StyleResolver.cpp
@@ -1130,20 +1130,20 @@
 
   const ActiveInterpolationsMap& activeInterpolationsMapForAnimations =
       state.animationUpdate().activeInterpolationsForAnimations();
-  const ActiveInterpolationsMap& activeInterpolationsMapForTransitions =
-      state.animationUpdate().activeInterpolationsForTransitions();
+  const ActiveInterpolationsMap& activeInterpolationsMapForStandardTransitions =
+      state.animationUpdate().activeInterpolationsForStandardTransitions();
   // TODO(crbug.com/644148): Apply animations on custom properties.
   applyAnimatedProperties<HighPropertyPriority>(
       state, activeInterpolationsMapForAnimations);
   applyAnimatedProperties<HighPropertyPriority>(
-      state, activeInterpolationsMapForTransitions);
+      state, activeInterpolationsMapForStandardTransitions);
 
   updateFont(state);
 
   applyAnimatedProperties<LowPropertyPriority>(
       state, activeInterpolationsMapForAnimations);
   applyAnimatedProperties<LowPropertyPriority>(
-      state, activeInterpolationsMapForTransitions);
+      state, activeInterpolationsMapForStandardTransitions);
 
   // Start loading resources used by animations.
   loadPendingResources(state);
diff --git a/third_party/WebKit/Source/core/dom/ContainerNode.cpp b/third_party/WebKit/Source/core/dom/ContainerNode.cpp
index cfe0428..1be048ee 100644
--- a/third_party/WebKit/Source/core/dom/ContainerNode.cpp
+++ b/third_party/WebKit/Source/core/dom/ContainerNode.cpp
@@ -788,6 +788,7 @@
     child->detachLayoutTree(childrenContext);
 
   setChildNeedsStyleRecalc();
+  setChildNeedsReattachLayoutTree();
   Node::detachLayoutTree(context);
 }
 
@@ -795,9 +796,15 @@
   document().incDOMTreeVersion();
   document().notifyChangeChildren(*this);
   invalidateNodeListCachesInAncestors();
-  if (change.isChildInsertion() && !childNeedsStyleRecalc()) {
-    setChildNeedsStyleRecalc();
-    markAncestorsWithChildNeedsStyleRecalc();
+  if (change.isChildInsertion()) {
+    if (!childNeedsStyleRecalc()) {
+      setChildNeedsStyleRecalc();
+      markAncestorsWithChildNeedsStyleRecalc();
+    }
+    if (!childNeedsReattachLayoutTree()) {
+      setChildNeedsReattachLayoutTree();
+      markAncestorsWithChildNeedsReattachLayoutTree();
+    }
   }
 }
 
@@ -1305,6 +1312,24 @@
   }
 }
 
+void ContainerNode::rebuildChildrenLayoutTrees() {
+  DCHECK(!needsReattachLayoutTree());
+
+  for (Node* child = lastChild(); child; child = child->previousSibling()) {
+    if (child->needsReattachLayoutTree() ||
+        child->childNeedsReattachLayoutTree()) {
+      if (child->isTextNode())
+        toText(child)->rebuildTextLayoutTree();
+      else if (child->isElementNode())
+        toElement(child)->rebuildLayoutTree();
+    }
+  }
+  // This is done in ContainerNode::attachLayoutTree but will never be cleared
+  // if we don't enter ContainerNode::attachLayoutTree so we do it here.
+  clearChildNeedsStyleRecalc();
+  clearChildNeedsReattachLayoutTree();
+}
+
 void ContainerNode::checkForSiblingStyleChanges(SiblingCheckType changeType,
                                                 Element* changedElement,
                                                 Node* nodeBeforeChange,
diff --git a/third_party/WebKit/Source/core/dom/ContainerNode.h b/third_party/WebKit/Source/core/dom/ContainerNode.h
index 1855eed9..26f5e92 100644
--- a/third_party/WebKit/Source/core/dom/ContainerNode.h
+++ b/third_party/WebKit/Source/core/dom/ContainerNode.h
@@ -240,6 +240,7 @@
                                    Node* nodeBeforeChange,
                                    Node* nodeAfterChange);
   void recalcDescendantStyles(StyleRecalcChange);
+  void rebuildChildrenLayoutTrees();
 
   bool childrenSupportStyleSharing() const { return !hasRestyleFlags(); }
 
diff --git a/third_party/WebKit/Source/core/dom/Document.cpp b/third_party/WebKit/Source/core/dom/Document.cpp
index 58de534..5ad6519 100644
--- a/third_party/WebKit/Source/core/dom/Document.cpp
+++ b/third_party/WebKit/Source/core/dom/Document.cpp
@@ -2098,6 +2098,9 @@
     inheritHtmlAndBodyElementStyles(change);
     if (documentElement->shouldCallRecalcStyle(change))
       documentElement->recalcStyle(change);
+    if (documentElement->needsReattachLayoutTree() ||
+        documentElement->childNeedsReattachLayoutTree())
+      documentElement->rebuildLayoutTree();
   }
 
   view()->recalcOverflowAfterStyleChange();
@@ -5642,6 +5645,11 @@
   return true;
 }
 
+bool Document::isRenderingReady() const {
+  return m_styleEngine->ignoringPendingStylesheets() ||
+         (haveImportsLoaded() && haveRenderBlockingStylesheetsLoaded());
+}
+
 bool Document::allowInlineEventHandler(Node* node,
                                        EventListener* listener,
                                        const String& contextURL,
diff --git a/third_party/WebKit/Source/core/dom/Document.h b/third_party/WebKit/Source/core/dom/Document.h
index 31b930a..88b124a 100644
--- a/third_party/WebKit/Source/core/dom/Document.h
+++ b/third_party/WebKit/Source/core/dom/Document.h
@@ -445,9 +445,7 @@
   }
 
   bool canExecuteScripts(ReasonForCallingCanExecuteScripts) override;
-  bool isRenderingReady() const {
-    return haveImportsLoaded() && haveRenderBlockingStylesheetsLoaded();
-  }
+  bool isRenderingReady() const;
   bool isScriptExecutionReady() const {
     return haveImportsLoaded() && haveScriptBlockingStylesheetsLoaded();
   }
diff --git a/third_party/WebKit/Source/core/dom/Element.cpp b/third_party/WebKit/Source/core/dom/Element.cpp
index 945e0dc..f33de88 100644
--- a/third_party/WebKit/Source/core/dom/Element.cpp
+++ b/third_party/WebKit/Source/core/dom/Element.cpp
@@ -1808,30 +1808,32 @@
   DCHECK(needsAttach());
 }
 
-bool Element::pseudoStyleCacheIsInvalid(const ComputedStyle* currentStyle,
+void Element::pseudoStyleCacheIsInvalid(const ComputedStyle* currentStyle,
                                         ComputedStyle* newStyle) {
+  // TODO(rune@opera.com): This method does not take into account pseudo style
+  // which is only present for the newStyle. Also the first-line part should
+  // probably be moved to where we handle visual invalidation diff for setStyle.
+  // setHasPseudoStyle() calls are probably unnecessary.
   DCHECK_EQ(currentStyle, computedStyle());
   DCHECK(layoutObject());
 
   if (!currentStyle)
-    return false;
+    return;
 
   const PseudoStyleCache* pseudoStyleCache = currentStyle->cachedPseudoStyles();
   if (!pseudoStyleCache)
-    return false;
+    return;
 
   size_t cacheSize = pseudoStyleCache->size();
   for (size_t i = 0; i < cacheSize; ++i) {
     RefPtr<ComputedStyle> newPseudoStyle;
     RefPtr<ComputedStyle> oldPseudoStyle = pseudoStyleCache->at(i);
     PseudoId pseudoId = oldPseudoStyle->styleType();
-    if (pseudoId == PseudoIdFirstLine || pseudoId == PseudoIdFirstLineInherited)
-      newPseudoStyle = layoutObject()->uncachedFirstLineStyle(newStyle);
-    else
-      newPseudoStyle = layoutObject()->getUncachedPseudoStyle(
-          PseudoStyleRequest(pseudoId), newStyle, newStyle);
+    if (pseudoId != PseudoIdFirstLine && pseudoId != PseudoIdFirstLineInherited)
+      continue;
+    newPseudoStyle = layoutObject()->uncachedFirstLineStyle(newStyle);
     if (!newPseudoStyle)
-      return true;
+      continue;
     if (*oldPseudoStyle != *newPseudoStyle ||
         oldPseudoStyle->font().loadingCustomFonts() !=
             newPseudoStyle->font().loadingCustomFonts()) {
@@ -1839,13 +1841,12 @@
         newStyle->setHasPseudoStyle(pseudoId);
       newStyle->addCachedPseudoStyle(newPseudoStyle);
       if (pseudoId == PseudoIdFirstLine ||
-          pseudoId == PseudoIdFirstLineInherited)
+          pseudoId == PseudoIdFirstLineInherited) {
         layoutObject()->firstLineStyleDidChange(*oldPseudoStyle,
                                                 *newPseudoStyle);
-      return true;
+      }
     }
   }
-  return false;
 }
 
 PassRefPtr<ComputedStyle> Element::styleForLayoutObject() {
@@ -1930,14 +1931,17 @@
     }
     if (parentComputedStyle())
       change = recalcOwnStyle(change, nextTextSibling);
-    clearNeedsStyleRecalc();
-    clearNeedsReattachLayoutTree();
+    // Needed because the rebuildLayoutTree code needs to see what the
+    // styleChangeType() was on reattach roots. See Node::reattachLayoutTree()
+    // for an example.
+    if (change != Reattach)
+      clearNeedsStyleRecalc();
   }
 
-  // If we reattached we don't need to recalc the style of our descendants
-  // anymore.
-  if ((change >= UpdatePseudoElements && change < Reattach) ||
-      childNeedsStyleRecalc()) {
+  // If we are going to reattach we don't need to recalc the style of
+  // our descendants anymore.
+  if (change < Reattach &&
+      (change >= UpdatePseudoElements || childNeedsStyleRecalc())) {
     SelectorFilterParentScope filterScope(*this);
     StyleSharingDepthScope sharingScope(*this);
 
@@ -1963,7 +1967,6 @@
                         childNeedsStyleRecalc() ? Force : change);
 
     clearChildNeedsStyleRecalc();
-    clearChildNeedsReattachLayoutTree();
   }
 
   if (hasCustomStyleCallbacks())
@@ -2023,7 +2026,7 @@
     styleReattachData.nextTextSibling = nextTextSibling;
     document().addStyleReattachData(*this, styleReattachData);
     setNeedsReattachLayoutTree();
-    return rebuildLayoutTree();
+    return Reattach;
   }
 
   DCHECK(oldStyle);
@@ -2032,8 +2035,8 @@
     updateCallbackSelectors(oldStyle.get(), newStyle.get());
 
   if (LayoutObject* layoutObject = this->layoutObject()) {
-    if (localChange != NoChange ||
-        pseudoStyleCacheIsInvalid(oldStyle.get(), newStyle.get())) {
+    if (localChange != NoChange) {
+      pseudoStyleCacheIsInvalid(oldStyle.get(), newStyle.get());
       layoutObject->setStyle(newStyle.get());
     } else {
       // Although no change occurred, we use the new style so that the cousin
@@ -2067,34 +2070,57 @@
   return localChange;
 }
 
-StyleRecalcChange Element::rebuildLayoutTree() {
+void Element::rebuildLayoutTree() {
   DCHECK(inActiveDocument());
-  StyleReattachData styleReattachData = document().getStyleReattachData(*this);
-  AttachContext reattachContext;
-  reattachContext.resolvedStyle = styleReattachData.computedStyle.get();
-  bool layoutObjectWillChange = needsAttach() || layoutObject();
-
-  // We are calling Element::rebuildLayoutTree() from inside
-  // Element::recalcOwnStyle where we set the NeedsReattachLayoutTree
-  // flag - so needsReattachLayoutTree() should always be true.
   DCHECK(parentNode());
-  DCHECK(parentNode()->childNeedsReattachLayoutTree());
-  DCHECK(needsReattachLayoutTree());
-  reattachLayoutTree(reattachContext);
-  // Since needsReattachLayoutTree() is always true we go into
-  // reattachLayoutTree() which reattaches all the descendant
-  // sub-trees. At this point no child should need reattaching.
-  DCHECK(!childNeedsReattachLayoutTree());
 
-  if (layoutObjectWillChange || layoutObject()) {
-    // nextTextSibling is passed on to recalcStyle from recalcDescendantStyles
-    // we can either traverse the current subtree from this node onwards
-    // or store it.
-    // The choice is between increased time and increased memory complexity.
-    reattachWhitespaceSiblingsIfNeeded(styleReattachData.nextTextSibling);
-    return Reattach;
+  if (needsReattachLayoutTree()) {
+    StyleReattachData styleReattachData =
+        document().getStyleReattachData(*this);
+    AttachContext reattachContext;
+    reattachContext.resolvedStyle = styleReattachData.computedStyle.get();
+    bool layoutObjectWillChange = needsAttach() || layoutObject();
+    reattachLayoutTree(reattachContext);
+    if (layoutObjectWillChange || layoutObject()) {
+      // nextTextSibling is passed on to recalcStyle from recalcDescendantStyles
+      // we can either traverse the current subtree from this node onwards
+      // or store it.
+      // The choice is between increased time and increased memory complexity.
+      reattachWhitespaceSiblingsIfNeeded(styleReattachData.nextTextSibling);
+    }
+  } else if (childNeedsReattachLayoutTree()) {
+    DCHECK(!needsReattachLayoutTree());
+    SelectorFilterParentScope filterScope(*this);
+    StyleSharingDepthScope sharingScope(*this);
+    reattachPseudoElementLayoutTree(PseudoIdBefore);
+    rebuildShadowRootLayoutTree();
+    rebuildChildrenLayoutTrees();
+    reattachPseudoElementLayoutTree(PseudoIdAfter);
+    reattachPseudoElementLayoutTree(PseudoIdBackdrop);
+    reattachPseudoElementLayoutTree(PseudoIdFirstLetter);
   }
-  return ReattachNoLayoutObject;
+  DCHECK(!needsStyleRecalc());
+  DCHECK(!childNeedsStyleRecalc());
+  DCHECK(!needsReattachLayoutTree());
+  DCHECK(!childNeedsReattachLayoutTree());
+}
+
+void Element::rebuildShadowRootLayoutTree() {
+  for (ShadowRoot* root = youngestShadowRoot(); root;
+       root = root->olderShadowRoot()) {
+    if (root->needsReattachLayoutTree() || root->childNeedsReattachLayoutTree())
+      root->rebuildLayoutTree();
+  }
+}
+
+void Element::reattachPseudoElementLayoutTree(PseudoId pseudoId) {
+  if (PseudoElement* element = pseudoElement(pseudoId)) {
+    if (element->needsReattachLayoutTree() ||
+        element->childNeedsReattachLayoutTree())
+      element->rebuildLayoutTree();
+  } else {
+    createPseudoElementIfNeeded(pseudoId);
+  }
 }
 
 void Element::updateCallbackSelectors(const ComputedStyle* oldStyle,
diff --git a/third_party/WebKit/Source/core/dom/Element.h b/third_party/WebKit/Source/core/dom/Element.h
index 4df08b26..21a3f70 100644
--- a/third_party/WebKit/Source/core/dom/Element.h
+++ b/third_party/WebKit/Source/core/dom/Element.h
@@ -417,7 +417,7 @@
   virtual LayoutObject* createLayoutObject(const ComputedStyle&);
   virtual bool layoutObjectIsNeeded(const ComputedStyle&);
   void recalcStyle(StyleRecalcChange, Text* nextTextSibling = nullptr);
-  StyleRecalcChange rebuildLayoutTree();
+  void rebuildLayoutTree();
   void pseudoStateChanged(CSSSelector::PseudoType);
   void setAnimationStyleChange(bool);
   void clearAnimationStyleChange();
@@ -847,6 +847,8 @@
   PassRefPtr<ComputedStyle> propagateInheritedProperties(StyleRecalcChange);
 
   StyleRecalcChange recalcOwnStyle(StyleRecalcChange, Text*);
+  void reattachPseudoElementLayoutTree(PseudoId);
+  void rebuildShadowRootLayoutTree();
   inline void checkForEmptyStyleChange();
 
   void updatePseudoElement(PseudoId, StyleRecalcChange);
@@ -901,7 +903,7 @@
                                              const AtomicString&,
                                              AttributeModificationReason);
 
-  bool pseudoStyleCacheIsInvalid(const ComputedStyle* currentStyle,
+  void pseudoStyleCacheIsInvalid(const ComputedStyle* currentStyle,
                                  ComputedStyle* newStyle);
 
   void cancelFocusAppearanceUpdate();
diff --git a/third_party/WebKit/Source/core/dom/MutationCallback.h b/third_party/WebKit/Source/core/dom/MutationCallback.h
index 4a17f1a..469435b 100644
--- a/third_party/WebKit/Source/core/dom/MutationCallback.h
+++ b/third_party/WebKit/Source/core/dom/MutationCallback.h
@@ -40,7 +40,8 @@
 class MutationRecord;
 class MutationObserver;
 
-class MutationCallback : public GarbageCollectedFinalized<MutationCallback> {
+class MutationCallback : public GarbageCollectedFinalized<MutationCallback>,
+                         public TraceWrapperBase {
  public:
   virtual ~MutationCallback() {}
 
diff --git a/third_party/WebKit/Source/core/dom/MutationObserver.cpp b/third_party/WebKit/Source/core/dom/MutationObserver.cpp
index 6d06700..93fa739 100644
--- a/third_party/WebKit/Source/core/dom/MutationObserver.cpp
+++ b/third_party/WebKit/Source/core/dom/MutationObserver.cpp
@@ -58,7 +58,7 @@
 }
 
 MutationObserver::MutationObserver(MutationCallback* callback)
-    : m_callback(callback), m_priority(s_observerPriority++) {}
+    : m_callback(this, callback), m_priority(s_observerPriority++) {}
 
 MutationObserver::~MutationObserver() {
   cancelInspectorAsyncTasks();
@@ -137,7 +137,7 @@
 MutationRecordVector MutationObserver::takeRecords() {
   MutationRecordVector records;
   cancelInspectorAsyncTasks();
-  records.swap(m_records);
+  swap(m_records, records, this);
   return records;
 }
 
@@ -216,7 +216,7 @@
 
 void MutationObserver::enqueueMutationRecord(MutationRecord* mutation) {
   DCHECK(isMainThread());
-  m_records.push_back(mutation);
+  m_records.push_back(TraceWrapperMember<MutationRecord>(this, mutation));
   activateObserver(this);
   probe::asyncTaskScheduled(m_callback->getExecutionContext(), mutation->type(),
                             mutation);
@@ -262,7 +262,7 @@
     return;
 
   MutationRecordVector records;
-  records.swap(m_records);
+  swap(m_records, records, this);
 
   // Report the first (earliest) stack as the async cause.
   probe::AsyncTask asyncTask(m_callback->getExecutionContext(),
@@ -310,10 +310,21 @@
     slot->dispatchSlotChangeEvent();
 }
 
+ExecutionContext* MutationObserver::getExecutionContext() const {
+  return m_callback->getExecutionContext();
+}
+
 DEFINE_TRACE(MutationObserver) {
   visitor->trace(m_callback);
   visitor->trace(m_records);
   visitor->trace(m_registrations);
+  visitor->trace(m_callback);
+}
+
+DEFINE_TRACE_WRAPPERS(MutationObserver) {
+  visitor->traceWrappers(m_callback);
+  for (auto record : m_records)
+    visitor->traceWrappers(record);
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/dom/MutationObserver.h b/third_party/WebKit/Source/core/dom/MutationObserver.h
index 7c7e8c2..7e11de2 100644
--- a/third_party/WebKit/Source/core/dom/MutationObserver.h
+++ b/third_party/WebKit/Source/core/dom/MutationObserver.h
@@ -33,7 +33,9 @@
 
 #include "base/gtest_prod_util.h"
 #include "bindings/core/v8/ScriptWrappable.h"
+#include "bindings/core/v8/TraceWrapperMember.h"
 #include "core/CoreExport.h"
+#include "core/dom/ExecutionContext.h"
 #include "platform/heap/Handle.h"
 #include "wtf/HashSet.h"
 #include "wtf/Vector.h"
@@ -61,8 +63,10 @@
 
 class CORE_EXPORT MutationObserver final
     : public GarbageCollectedFinalized<MutationObserver>,
+      public ActiveScriptWrappable<MutationObserver>,
       public ScriptWrappable {
   DEFINE_WRAPPERTYPEINFO();
+  USING_GARBAGE_COLLECTED_MIXIN(MutationObserver);
 
  public:
   enum MutationType {
@@ -98,10 +102,15 @@
 
   HeapHashSet<Member<Node>> getObservedNodes() const;
 
+  bool hasPendingActivity() const override { return !m_records.isEmpty(); }
+  ExecutionContext* getExecutionContext() const;
+
   // Eagerly finalized as destructor accesses heap object members.
   EAGERLY_FINALIZE();
   DECLARE_TRACE();
 
+  DECLARE_VIRTUAL_TRACE_WRAPPERS();
+
  private:
   struct ObserverLessThan;
 
@@ -110,8 +119,8 @@
   bool shouldBeSuspended() const;
   void cancelInspectorAsyncTasks();
 
-  Member<MutationCallback> m_callback;
-  MutationRecordVector m_records;
+  TraceWrapperMember<MutationCallback> m_callback;
+  HeapVector<TraceWrapperMember<MutationRecord>> m_records;
   MutationObserverRegistrationSet m_registrations;
   unsigned m_priority;
 
diff --git a/third_party/WebKit/Source/core/dom/MutationObserver.idl b/third_party/WebKit/Source/core/dom/MutationObserver.idl
index 53231f7..b199a17 100644
--- a/third_party/WebKit/Source/core/dom/MutationObserver.idl
+++ b/third_party/WebKit/Source/core/dom/MutationObserver.idl
@@ -32,6 +32,7 @@
 
 [
     CustomConstructor(MutationCallback callback),
+    ActiveScriptWrappable,
     DependentLifetime,
 ] interface MutationObserver {
     [RaisesException] void observe(Node target, optional MutationObserverInit options);
diff --git a/third_party/WebKit/Source/core/dom/MutationRecord.cpp b/third_party/WebKit/Source/core/dom/MutationRecord.cpp
index 37eeb31..2c52bede 100644
--- a/third_party/WebKit/Source/core/dom/MutationRecord.cpp
+++ b/third_party/WebKit/Source/core/dom/MutationRecord.cpp
@@ -47,9 +47,9 @@
                   StaticNodeList* removed,
                   Node* previousSibling,
                   Node* nextSibling)
-      : m_target(target),
-        m_addedNodes(added),
-        m_removedNodes(removed),
+      : m_target(this, target),
+        m_addedNodes(this, added),
+        m_removedNodes(this, removed),
         m_previousSibling(previousSibling),
         m_nextSibling(nextSibling) {}
 
@@ -62,6 +62,13 @@
     MutationRecord::trace(visitor);
   }
 
+  DEFINE_INLINE_VIRTUAL_TRACE_WRAPPERS() {
+    visitor->traceWrappers(m_target);
+    visitor->traceWrappers(m_addedNodes);
+    visitor->traceWrappers(m_removedNodes);
+    MutationRecord::traceWrappers(visitor);
+  }
+
  private:
   const AtomicString& type() override;
   Node* target() override { return m_target.get(); }
@@ -70,9 +77,9 @@
   Node* previousSibling() override { return m_previousSibling.get(); }
   Node* nextSibling() override { return m_nextSibling.get(); }
 
-  Member<Node> m_target;
-  Member<StaticNodeList> m_addedNodes;
-  Member<StaticNodeList> m_removedNodes;
+  TraceWrapperMember<Node> m_target;
+  TraceWrapperMember<StaticNodeList> m_addedNodes;
+  TraceWrapperMember<StaticNodeList> m_removedNodes;
   Member<Node> m_previousSibling;
   Member<Node> m_nextSibling;
 };
@@ -80,7 +87,10 @@
 class RecordWithEmptyNodeLists : public MutationRecord {
  public:
   RecordWithEmptyNodeLists(Node* target, const String& oldValue)
-      : m_target(target), m_oldValue(oldValue) {}
+      : m_target(this, target),
+        m_oldValue(oldValue),
+        m_addedNodes(this, nullptr),
+        m_removedNodes(this, nullptr) {}
 
   DEFINE_INLINE_VIRTUAL_TRACE() {
     visitor->trace(m_target);
@@ -89,6 +99,13 @@
     MutationRecord::trace(visitor);
   }
 
+  DEFINE_INLINE_VIRTUAL_TRACE_WRAPPERS() {
+    visitor->traceWrappers(m_target);
+    visitor->traceWrappers(m_addedNodes);
+    visitor->traceWrappers(m_removedNodes);
+    MutationRecord::traceWrappers(visitor);
+  }
+
  private:
   Node* target() override { return m_target.get(); }
   String oldValue() override { return m_oldValue; }
@@ -106,10 +123,10 @@
     return nodeList.get();
   }
 
-  Member<Node> m_target;
+  TraceWrapperMember<Node> m_target;
   String m_oldValue;
-  Member<StaticNodeList> m_addedNodes;
-  Member<StaticNodeList> m_removedNodes;
+  TraceWrapperMember<StaticNodeList> m_addedNodes;
+  TraceWrapperMember<StaticNodeList> m_removedNodes;
 };
 
 class AttributesRecord : public RecordWithEmptyNodeLists {
@@ -143,13 +160,19 @@
 
 class MutationRecordWithNullOldValue : public MutationRecord {
  public:
-  MutationRecordWithNullOldValue(MutationRecord* record) : m_record(record) {}
+  MutationRecordWithNullOldValue(MutationRecord* record)
+      : m_record(this, record) {}
 
   DEFINE_INLINE_VIRTUAL_TRACE() {
     visitor->trace(m_record);
     MutationRecord::trace(visitor);
   }
 
+  DEFINE_INLINE_VIRTUAL_TRACE_WRAPPERS() {
+    visitor->traceWrappers(m_record);
+    MutationRecord::traceWrappers(visitor);
+  }
+
  private:
   const AtomicString& type() override { return m_record->type(); }
   Node* target() override { return m_record->target(); }
@@ -166,7 +189,7 @@
 
   String oldValue() override { return String(); }
 
-  Member<MutationRecord> m_record;
+  TraceWrapperMember<MutationRecord> m_record;
 };
 
 const AtomicString& ChildListRecord::type() {
diff --git a/third_party/WebKit/Source/core/dom/Node.cpp b/third_party/WebKit/Source/core/dom/Node.cpp
index 9136af0..94a3878 100644
--- a/third_party/WebKit/Source/core/dom/Node.cpp
+++ b/third_party/WebKit/Source/core/dom/Node.cpp
@@ -931,6 +931,7 @@
     layoutObject()->destroyAndCleanupAnonymousWrappers();
   setLayoutObject(nullptr);
   setStyleChange(NeedsReattachStyleChange);
+  setFlag(NeedsReattachLayoutTree);
   clearChildNeedsStyleInvalidation();
 }
 
diff --git a/third_party/WebKit/Source/core/dom/Node.h b/third_party/WebKit/Source/core/dom/Node.h
index 63b03b0..198c0ae 100644
--- a/third_party/WebKit/Source/core/dom/Node.h
+++ b/third_party/WebKit/Source/core/dom/Node.h
@@ -421,8 +421,10 @@
   void setNeedsStyleRecalc(StyleChangeType, const StyleChangeReasonForTracing&);
   void clearNeedsStyleRecalc();
 
-  bool needsReattachLayoutTree() { return getFlag(NeedsReattachLayoutTree); }
-  bool childNeedsReattachLayoutTree() {
+  bool needsReattachLayoutTree() const {
+    return getFlag(NeedsReattachLayoutTree);
+  }
+  bool childNeedsReattachLayoutTree() const {
     return getFlag(ChildNeedsReattachLayoutTree);
   }
 
@@ -830,7 +832,9 @@
     NeedsReattachLayoutTree = 1 << 26,
     ChildNeedsReattachLayoutTree = 1 << 27,
 
-    DefaultNodeFlags = IsFinishedParsingChildrenFlag | NeedsReattachStyleChange
+    DefaultNodeFlags = IsFinishedParsingChildrenFlag |
+                       NeedsReattachStyleChange |
+                       NeedsReattachLayoutTree
   };
 
   // 4 bits remaining.
@@ -853,8 +857,9 @@
   enum ConstructionType {
     CreateOther = DefaultNodeFlags,
     CreateText = DefaultNodeFlags | IsTextFlag,
-    CreateContainer =
-        DefaultNodeFlags | ChildNeedsStyleRecalcFlag | IsContainerFlag,
+    CreateContainer = DefaultNodeFlags | ChildNeedsStyleRecalcFlag |
+                      ChildNeedsReattachLayoutTree |
+                      IsContainerFlag,
     CreateElement = CreateContainer | IsElementFlag,
     CreateShadowRoot =
         CreateContainer | IsDocumentFragmentFlag | IsInShadowTreeFlag,
@@ -974,6 +979,7 @@
 
   detachLayoutTree(context);
   markAncestorsWithChildNeedsStyleRecalc();
+  markAncestorsWithChildNeedsReattachLayoutTree();
 }
 
 inline bool Node::shouldCallRecalcStyle(StyleRecalcChange change) {
diff --git a/third_party/WebKit/Source/core/dom/StaticNodeList.h b/third_party/WebKit/Source/core/dom/StaticNodeList.h
index 7df9827..c03504b 100644
--- a/third_party/WebKit/Source/core/dom/StaticNodeList.h
+++ b/third_party/WebKit/Source/core/dom/StaticNodeList.h
@@ -29,6 +29,7 @@
 #ifndef StaticNodeList_h
 #define StaticNodeList_h
 
+#include "bindings/core/v8/TraceWrapperMember.h"
 #include "core/dom/NodeList.h"
 #include "wtf/Vector.h"
 
@@ -49,9 +50,14 @@
   NodeType* item(unsigned index) const override;
 
   DECLARE_VIRTUAL_TRACE();
+  DEFINE_INLINE_VIRTUAL_TRACE_WRAPPERS() {
+    for (unsigned i = 0; i < length(); i++)
+      visitor->traceWrappers(m_nodes[i]);
+    NodeList::traceWrappers(visitor);
+  }
 
  private:
-  HeapVector<Member<NodeType>> m_nodes;
+  HeapVector<TraceWrapperMember<NodeType>> m_nodes;
 };
 
 using StaticNodeList = StaticNodeTypeList<Node>;
@@ -60,7 +66,7 @@
 StaticNodeTypeList<NodeType>* StaticNodeTypeList<NodeType>::adopt(
     HeapVector<Member<NodeType>>& nodes) {
   StaticNodeTypeList<NodeType>* nodeList = new StaticNodeTypeList<NodeType>;
-  nodeList->m_nodes.swap(nodes);
+  swap(nodeList->m_nodes, nodes, nodeList);
   return nodeList;
 }
 
diff --git a/third_party/WebKit/Source/core/dom/Text.cpp b/third_party/WebKit/Source/core/dom/Text.cpp
index c77bf86..f69b855 100644
--- a/third_party/WebKit/Source/core/dom/Text.cpp
+++ b/third_party/WebKit/Source/core/dom/Text.cpp
@@ -400,14 +400,23 @@
       layoutItem.setText(dataImpl());
     clearNeedsStyleRecalc();
   } else if (needsStyleRecalc() || needsWhitespaceLayoutObject()) {
-    rebuildTextLayoutTree(nextTextSibling);
+    StyleReattachData styleReattachData;
+    styleReattachData.nextTextSibling = nextTextSibling;
+    document().addStyleReattachData(*this, styleReattachData);
+    setNeedsReattachLayoutTree();
   }
 }
 
-void Text::rebuildTextLayoutTree(Text* nextTextSibling) {
+void Text::rebuildTextLayoutTree() {
+  DCHECK(!childNeedsStyleRecalc());
+  DCHECK(needsReattachLayoutTree());
+  DCHECK(parentNode());
+
   reattachLayoutTree();
-  if (layoutObject())
-    reattachWhitespaceSiblingsIfNeeded(nextTextSibling);
+  if (layoutObject()) {
+    reattachWhitespaceSiblingsIfNeeded(
+        document().getStyleReattachData(*this).nextTextSibling);
+  }
   clearNeedsReattachLayoutTree();
 }
 
diff --git a/third_party/WebKit/Source/core/dom/Text.h b/third_party/WebKit/Source/core/dom/Text.h
index 7c865df3..96111466 100644
--- a/third_party/WebKit/Source/core/dom/Text.h
+++ b/third_party/WebKit/Source/core/dom/Text.h
@@ -54,7 +54,7 @@
   Text* replaceWholeText(const String&);
 
   void recalcTextStyle(StyleRecalcChange, Text* nextTextSibling);
-  void rebuildTextLayoutTree(Text* nextTextSibling);
+  void rebuildTextLayoutTree();
   bool textLayoutObjectIsNeeded(const ComputedStyle&,
                                 const LayoutObject& parent) const;
   LayoutText* createTextLayoutObject(const ComputedStyle&);
diff --git a/third_party/WebKit/Source/core/dom/shadow/ElementShadow.cpp b/third_party/WebKit/Source/core/dom/shadow/ElementShadow.cpp
index 8e5eec44..c0c743f 100644
--- a/third_party/WebKit/Source/core/dom/shadow/ElementShadow.cpp
+++ b/third_party/WebKit/Source/core/dom/shadow/ElementShadow.cpp
@@ -86,6 +86,7 @@
   shadowHost.setNeedsStyleRecalc(
       SubtreeStyleChange,
       StyleChangeReasonForTracing::create(StyleChangeReason::Shadow));
+  shadowRoot->setNeedsReattachLayoutTree();
 
   probe::didPushShadowRoot(&shadowHost, shadowRoot);
 
diff --git a/third_party/WebKit/Source/core/dom/shadow/ShadowRoot.cpp b/third_party/WebKit/Source/core/dom/shadow/ShadowRoot.cpp
index c72f2a0..3d99595 100644
--- a/third_party/WebKit/Source/core/dom/shadow/ShadowRoot.cpp
+++ b/third_party/WebKit/Source/core/dom/shadow/ShadowRoot.cpp
@@ -147,10 +147,19 @@
 
   // There's no style to update so just calling recalcStyle means we're updated.
   clearNeedsStyleRecalc();
-  clearNeedsReattachLayoutTree();
 
   recalcDescendantStyles(change);
   clearChildNeedsStyleRecalc();
+}
+
+void ShadowRoot::rebuildLayoutTree() {
+  // ShadowRoot doesn't support custom callbacks.
+  DCHECK(!hasCustomStyleCallbacks());
+
+  StyleSharingDepthScope sharingScope(*this);
+
+  clearNeedsReattachLayoutTree();
+  rebuildChildrenLayoutTrees();
   clearChildNeedsReattachLayoutTree();
 }
 
diff --git a/third_party/WebKit/Source/core/dom/shadow/ShadowRoot.h b/third_party/WebKit/Source/core/dom/shadow/ShadowRoot.h
index c8bcbda..a009760 100644
--- a/third_party/WebKit/Source/core/dom/shadow/ShadowRoot.h
+++ b/third_party/WebKit/Source/core/dom/shadow/ShadowRoot.h
@@ -119,6 +119,7 @@
   unsigned childShadowRootCount() const { return m_childShadowRootCount; }
 
   void recalcStyle(StyleRecalcChange);
+  void rebuildLayoutTree();
 
   void registerScopedHTMLStyleChild();
   void unregisterScopedHTMLStyleChild();
diff --git a/third_party/WebKit/Source/core/dom/stylerecalc.md b/third_party/WebKit/Source/core/dom/stylerecalc.md
index aacc22f..468713f 100644
--- a/third_party/WebKit/Source/core/dom/stylerecalc.md
+++ b/third_party/WebKit/Source/core/dom/stylerecalc.md
@@ -12,5 +12,4 @@
 4. IndependentInherit -> Same as Inherit except style recalc stops early if only independent properties were changed. We still visit every descendant, but we apply the styles directly instead of doing selector matching to compute a new style. Independent properties are those which do not depend on and do not affect any other properties on ComputedStyle (e.g. visibility and Pointer Events).
 5. Inherit -> Do a full style recalc of children.
 6. Force -> Fallback that causes us to do a full style recalc. This is as we don't know what changes. The primary reason for it is SubtreeStyleChange.
-7. Reattach -> reattachLayoutTree() has been completed.
-8. ReattachNoLayoutObject -> reattachLayoutTree() has been completed and now dont have a layoutObject.
\ No newline at end of file
+7. Reattach -> reattachLayoutTree() needs to be performed.
diff --git a/third_party/WebKit/Source/core/editing/EditingStyle.cpp b/third_party/WebKit/Source/core/editing/EditingStyle.cpp
index 68759778..b9f9a18 100644
--- a/third_party/WebKit/Source/core/editing/EditingStyle.cpp
+++ b/third_party/WebKit/Source/core/editing/EditingStyle.cpp
@@ -311,7 +311,7 @@
   const CSSValue* value = attributeValueAsCSSValue(element);
   const CSSValue* styleValue = style->getPropertyCSSValue(m_propertyID);
 
-  return compareCSSValuePtr(value, styleValue);
+  return dataEquivalent(value, styleValue);
 }
 
 void HTMLAttributeEquivalent::addToStyle(Element* element,
diff --git a/third_party/WebKit/Source/core/editing/FrameSelection.cpp b/third_party/WebKit/Source/core/editing/FrameSelection.cpp
index 9247096..04b7419d 100644
--- a/third_party/WebKit/Source/core/editing/FrameSelection.cpp
+++ b/third_party/WebKit/Source/core/editing/FrameSelection.cpp
@@ -325,19 +325,6 @@
   setSelection(newSelection.asSelection(), options);
 }
 
-void FrameSelection::setSelection(
-    const VisibleSelectionInFlatTree& newSelection,
-    HandleVisibility handleVisibility,
-    SetSelectionOptions options,
-    CursorAlignOnScroll align,
-    TextGranularity granularity) {
-  setSelection(
-      SelectionInFlatTree::Builder(newSelection.asSelection())
-          .setIsHandleVisible(handleVisibility == HandleVisibility::Visible)
-          .build(),
-      options, align, granularity);
-}
-
 void FrameSelection::nodeChildrenWillBeRemoved(ContainerNode& container) {
   if (!container.inActiveDocument())
     return;
@@ -687,11 +674,6 @@
                                       SetSelectionOptions options) {
   if (range.isNull())
     return false;
-  m_selectionEditor->resetLogicalRange();
-  // Since |FrameSeleciton::setSelection()| dispatches events and DOM tree
-  // can be modified by event handlers, we should create |Range| object before
-  // calling it.
-  Range* logicalRange = createRange(range);
   setSelection(SelectionInDOMTree::Builder()
                    .setBaseAndExtent(range)
                    .setAffinity(affinity)
@@ -699,7 +681,6 @@
                                      SelectionDirectionalMode::Directional)
                    .build(),
                options);
-  m_selectionEditor->setLogicalRange(logicalRange);
   return true;
 }
 
diff --git a/third_party/WebKit/Source/core/editing/FrameSelection.h b/third_party/WebKit/Source/core/editing/FrameSelection.h
index 7be6e9d5..1cee348a 100644
--- a/third_party/WebKit/Source/core/editing/FrameSelection.h
+++ b/third_party/WebKit/Source/core/editing/FrameSelection.h
@@ -132,13 +132,6 @@
                     CursorAlignOnScroll = CursorAlignOnScroll::IfNeeded,
                     TextGranularity = CharacterGranularity);
   void setSelection(const VisibleSelection&, SetSelectionOptions);
-  // TODO(yosin): We should use |SelectionInFlatTree| version instead of
-  // |VisibleSelectionInFlatTree| version.
-  void setSelection(const VisibleSelectionInFlatTree&,
-                    HandleVisibility = HandleVisibility::NotVisible,
-                    SetSelectionOptions = CloseTyping | ClearTypingStyle,
-                    CursorAlignOnScroll = CursorAlignOnScroll::IfNeeded,
-                    TextGranularity = CharacterGranularity);
   bool setSelectedRange(
       const EphemeralRange&,
       TextAffinity,
diff --git a/third_party/WebKit/Source/core/editing/FrameSelectionTest.cpp b/third_party/WebKit/Source/core/editing/FrameSelectionTest.cpp
index 403316ed..d124ac4 100644
--- a/third_party/WebKit/Source/core/editing/FrameSelectionTest.cpp
+++ b/third_party/WebKit/Source/core/editing/FrameSelectionTest.cpp
@@ -56,6 +56,22 @@
   return text;
 }
 
+TEST_F(FrameSelectionTest, FirstRange) {
+  setBodyContent("<div id=sample>0123456789</div>abc");
+  Element* const sample = document().getElementById("sample");
+  Node* const text = sample->firstChild();
+  selection().setSelectedRange(
+      EphemeralRange(Position(text, 3), Position(text, 6)), VP_DEFAULT_AFFINITY,
+      SelectionDirectionalMode::NonDirectional, 0);
+  sample->setAttribute(HTMLNames::styleAttr, "display:none");
+  // Move |VisibleSelection| before "abc".
+  updateAllLifecyclePhases();
+  Range* const range = selection().firstRange();
+  EXPECT_EQ(Position(sample->nextSibling(), 0), range->startPosition())
+      << "firstRagne() should return current selection value";
+  EXPECT_EQ(Position(sample->nextSibling(), 0), range->endPosition());
+}
+
 TEST_F(FrameSelectionTest, SetValidSelection) {
   Text* text = appendTextNode("Hello, World!");
   document().view()->updateAllLifecyclePhases();
diff --git a/third_party/WebKit/Source/core/editing/SelectionEditor.cpp b/third_party/WebKit/Source/core/editing/SelectionEditor.cpp
index a06bc771..14f7509 100644
--- a/third_party/WebKit/Source/core/editing/SelectionEditor.cpp
+++ b/third_party/WebKit/Source/core/editing/SelectionEditor.cpp
@@ -61,7 +61,6 @@
 }
 
 void SelectionEditor::dispose() {
-  resetLogicalRange();
   clearDocumentCachedRange();
   clearVisibleSelection();
 }
@@ -122,7 +121,6 @@
   newSelection.assertValidFor(document());
   if (m_selection == newSelection)
     return;
-  resetLogicalRange();
   clearDocumentCachedRange();
   markCacheDirty();
   m_selection = newSelection;
@@ -350,24 +348,7 @@
   didFinishTextChange(newBase, newExtent);
 }
 
-void SelectionEditor::resetLogicalRange() {
-  // Non-collapsed ranges are not allowed to start at the end of a line that
-  // is wrapped, they start at the beginning of the next line instead
-  if (!m_logicalRange)
-    return;
-  m_logicalRange->dispose();
-  m_logicalRange = nullptr;
-}
-
-void SelectionEditor::setLogicalRange(Range* range) {
-  DCHECK_EQ(range->ownerDocument(), document());
-  DCHECK(!m_logicalRange) << "A logical range should be one.";
-  m_logicalRange = range;
-}
-
 Range* SelectionEditor::firstRange() const {
-  if (m_logicalRange)
-    return m_logicalRange->cloneRange();
   return createRange(firstEphemeralRangeOf(computeVisibleSelectionInDOMTree()));
 }
 
@@ -420,7 +401,6 @@
   visitor->trace(m_selection);
   visitor->trace(m_cachedVisibleSelectionInDOMTree);
   visitor->trace(m_cachedVisibleSelectionInFlatTree);
-  visitor->trace(m_logicalRange);
   visitor->trace(m_cachedRange);
   SynchronousMutationObserver::trace(visitor);
 }
diff --git a/third_party/WebKit/Source/core/editing/SelectionEditor.h b/third_party/WebKit/Source/core/editing/SelectionEditor.h
index e853cfe..322b3b4 100644
--- a/third_party/WebKit/Source/core/editing/SelectionEditor.h
+++ b/third_party/WebKit/Source/core/editing/SelectionEditor.h
@@ -67,9 +67,6 @@
   Range* firstRange() const;
 
   // There functions are exposed for |FrameSelection|.
-  void resetLogicalRange();
-  void setLogicalRange(Range*);
-
   void cacheRangeOfDocument(Range*);
   Range* documentCachedRange() const;
   void clearDocumentCachedRange();
@@ -112,13 +109,6 @@
 
   SelectionInDOMTree m_selection;
 
-  // TODO(editing-dev): Removing |m_logicalRange|
-  // The range specified by the user, which may not be visually canonicalized
-  // (hence "logical"). This will be invalidated if the underlying
-  // |VisibleSelection| changes. If that happens, this variable will
-  // become |nullptr|, in which case logical positions == visible positions.
-  Member<Range> m_logicalRange;
-
   // If document is root, document.getSelection().addRange(range) is cached on
   // this.
   Member<Range> m_cachedRange;
diff --git a/third_party/WebKit/Source/core/editing/VisibleUnits.cpp b/third_party/WebKit/Source/core/editing/VisibleUnits.cpp
index 32c5d1c..6a27a1a 100644
--- a/third_party/WebKit/Source/core/editing/VisibleUnits.cpp
+++ b/third_party/WebKit/Source/core/editing/VisibleUnits.cpp
@@ -810,14 +810,14 @@
                                            bool& needMoreContext);
 
 template <typename Strategy>
-static VisiblePositionTemplate<Strategy> previousBoundary(
+static PositionTemplate<Strategy> previousBoundary(
     const VisiblePositionTemplate<Strategy>& c,
     BoundarySearchFunction searchFunction) {
   DCHECK(c.isValid()) << c;
   const PositionTemplate<Strategy> pos = c.deepEquivalent();
   Node* boundary = parentEditingBoundary(pos);
   if (!boundary)
-    return VisiblePositionTemplate<Strategy>();
+    return PositionTemplate<Strategy>();
 
   const PositionTemplate<Strategy> start =
       PositionTemplate<Strategy>::editingPositionOf(boundary, 0)
@@ -888,14 +888,13 @@
   }
 
   if (!next)
-    return createVisiblePosition(it.atEnd() ? it.startPosition() : pos);
+    return it.atEnd() ? it.startPosition() : pos;
 
   Node* node = it.startContainer();
   int boundaryOffset = remainingLength + next;
   if (node->isTextNode() && boundaryOffset <= node->maxCharacterOffset()) {
     // The next variable contains a usable index into a text node
-    return createVisiblePosition(
-        PositionTemplate<Strategy>(node, boundaryOffset));
+    return PositionTemplate<Strategy>(node, boundaryOffset);
   }
 
   // Use the character iterator to translate the next value into a DOM
@@ -903,7 +902,7 @@
   BackwardsCharacterIteratorAlgorithm<Strategy> charIt(start, end);
   charIt.advance(string.size() - suffixLength - next);
   // TODO(yosin) charIt can get out of shadow host.
-  return createVisiblePosition(charIt.endPosition());
+  return charIt.endPosition();
 }
 
 template <typename Strategy>
@@ -1060,7 +1059,7 @@
     if (p.isNull())
       return c;
   }
-  return previousBoundary(p, startWordBoundary);
+  return createVisiblePosition(previousBoundary(p, startWordBoundary));
 }
 
 VisiblePosition startOfWord(const VisiblePosition& c, EWordSide side) {
@@ -1090,33 +1089,43 @@
 }
 
 template <typename Strategy>
-static VisiblePositionTemplate<Strategy> endOfWordAlgorithm(
+static PositionTemplate<Strategy> endOfWordAlgorithm(
     const VisiblePositionTemplate<Strategy>& c,
     EWordSide side) {
   DCHECK(c.isValid()) << c;
   VisiblePositionTemplate<Strategy> p = c;
   if (side == LeftWordIfOnBoundary) {
     if (isStartOfParagraph(c))
-      return c;
+      return c.deepEquivalent();
 
     p = previousPositionOf(c);
     if (p.isNull())
-      return c;
+      return c.deepEquivalent();
   } else if (isEndOfParagraph(c)) {
-    return c;
+    return c.deepEquivalent();
   }
 
-  return createVisiblePosition(nextBoundary(p, endWordBoundary),
+  return nextBoundary(p, endWordBoundary);
+}
+
+Position endOfWordPosition(const VisiblePosition& position, EWordSide side) {
+  return endOfWordAlgorithm<EditingStrategy>(position, side);
+}
+
+VisiblePosition endOfWord(const VisiblePosition& position, EWordSide side) {
+  return createVisiblePosition(endOfWordPosition(position, side),
                                VP_UPSTREAM_IF_POSSIBLE);
 }
 
-VisiblePosition endOfWord(const VisiblePosition& c, EWordSide side) {
-  return endOfWordAlgorithm<EditingStrategy>(c, side);
+PositionInFlatTree endOfWordPosition(const VisiblePositionInFlatTree& position,
+                                     EWordSide side) {
+  return endOfWordAlgorithm<EditingInFlatTreeStrategy>(position, side);
 }
 
-VisiblePositionInFlatTree endOfWord(const VisiblePositionInFlatTree& c,
+VisiblePositionInFlatTree endOfWord(const VisiblePositionInFlatTree& position,
                                     EWordSide side) {
-  return endOfWordAlgorithm<EditingInFlatTreeStrategy>(c, side);
+  return createVisiblePosition(endOfWordPosition(position, side),
+                               VP_UPSTREAM_IF_POSSIBLE);
 }
 
 static unsigned previousWordPositionBoundary(
@@ -1136,7 +1145,8 @@
 
 VisiblePosition previousWordPosition(const VisiblePosition& c) {
   DCHECK(c.isValid()) << c;
-  VisiblePosition prev = previousBoundary(c, previousWordPositionBoundary);
+  VisiblePosition prev =
+      createVisiblePosition(previousBoundary(c, previousWordPositionBoundary));
   return honorEditingBoundaryAtOrBefore(prev, c.deepEquivalent());
 }
 
@@ -1675,7 +1685,7 @@
 static VisiblePositionTemplate<Strategy> startOfSentenceAlgorithm(
     const VisiblePositionTemplate<Strategy>& c) {
   DCHECK(c.isValid()) << c;
-  return previousBoundary(c, startSentenceBoundary);
+  return createVisiblePosition(previousBoundary(c, startSentenceBoundary));
 }
 
 VisiblePosition startOfSentence(const VisiblePosition& c) {
@@ -1728,7 +1738,8 @@
 
 VisiblePosition previousSentencePosition(const VisiblePosition& c) {
   DCHECK(c.isValid()) << c;
-  VisiblePosition prev = previousBoundary(c, previousSentencePositionBoundary);
+  VisiblePosition prev = createVisiblePosition(
+      previousBoundary(c, previousSentencePositionBoundary));
   return honorEditingBoundaryAtOrBefore(prev, c.deepEquivalent());
 }
 
diff --git a/third_party/WebKit/Source/core/editing/VisibleUnits.h b/third_party/WebKit/Source/core/editing/VisibleUnits.h
index d53d38b..154a9845 100644
--- a/third_party/WebKit/Source/core/editing/VisibleUnits.h
+++ b/third_party/WebKit/Source/core/editing/VisibleUnits.h
@@ -161,8 +161,15 @@
 CORE_EXPORT VisiblePositionInFlatTree
 startOfWord(const VisiblePositionInFlatTree&,
             EWordSide = RightWordIfOnBoundary);
+// TODO(yoichio): Replace |endOfWord| to |endOfWordPosition| because returned
+// Position should be canonicalized with |nextBoundary()| by TextItetator.
+CORE_EXPORT Position endOfWordPosition(const VisiblePosition&,
+                                       EWordSide = RightWordIfOnBoundary);
 CORE_EXPORT VisiblePosition endOfWord(const VisiblePosition&,
                                       EWordSide = RightWordIfOnBoundary);
+CORE_EXPORT PositionInFlatTree
+endOfWordPosition(const VisiblePositionInFlatTree&,
+                  EWordSide = RightWordIfOnBoundary);
 CORE_EXPORT VisiblePositionInFlatTree
 endOfWord(const VisiblePositionInFlatTree&, EWordSide = RightWordIfOnBoundary);
 VisiblePosition previousWordPosition(const VisiblePosition&);
diff --git a/third_party/WebKit/Source/core/editing/spellcheck/IdleSpellCheckCallback.cpp b/third_party/WebKit/Source/core/editing/spellcheck/IdleSpellCheckCallback.cpp
index b9fa99b6..b07bdaa 100644
--- a/third_party/WebKit/Source/core/editing/spellcheck/IdleSpellCheckCallback.cpp
+++ b/third_party/WebKit/Source/core/editing/spellcheck/IdleSpellCheckCallback.cpp
@@ -190,9 +190,9 @@
   if (!isSpellCheckingEnabled())
     return;
 
-  IdleDeadline* deadline =
-      IdleDeadline::create(kForcedInvocationDeadlineSeconds,
-                           IdleDeadline::CallbackType::CalledWhenIdle);
+  IdleDeadline* deadline = IdleDeadline::create(
+      kForcedInvocationDeadlineSeconds + monotonicallyIncreasingTime(),
+      IdleDeadline::CallbackType::CalledWhenIdle);
 
   switch (m_state) {
     case State::kColdModeTimerStarted:
diff --git a/third_party/WebKit/Source/core/frame/Deprecation.cpp b/third_party/WebKit/Source/core/frame/Deprecation.cpp
index 3fbd1a4..e8ab30e 100644
--- a/third_party/WebKit/Source/core/frame/Deprecation.cpp
+++ b/third_party/WebKit/Source/core/frame/Deprecation.cpp
@@ -72,7 +72,7 @@
 namespace blink {
 
 Deprecation::Deprecation() : m_muteCount(0) {
-  m_cssPropertyDeprecationBits.ensureSize(lastUnresolvedCSSProperty + 1);
+  m_cssPropertyDeprecationBits.ensureSize(numCSSPropertyIDs);
 }
 
 Deprecation::~Deprecation() {}
diff --git a/third_party/WebKit/Source/core/frame/FrameHost.cpp b/third_party/WebKit/Source/core/frame/FrameHost.cpp
index b9b1ea2d..c8393af9 100644
--- a/third_party/WebKit/Source/core/frame/FrameHost.cpp
+++ b/third_party/WebKit/Source/core/frame/FrameHost.cpp
@@ -33,7 +33,6 @@
 #include "core/frame/BrowserControls.h"
 #include "core/frame/EventHandlerRegistry.h"
 #include "core/frame/FrameView.h"
-#include "core/frame/PageScaleConstraints.h"
 #include "core/frame/VisualViewport.h"
 #include "core/inspector/ConsoleMessageStorage.h"
 #include "core/page/Page.h"
@@ -154,13 +153,4 @@
   return m_subframeCount;
 }
 
-void FrameHost::setDefaultPageScaleLimits(float minScale, float maxScale) {
-  page().setDefaultPageScaleLimits(minScale, maxScale);
-}
-
-void FrameHost::setUserAgentPageScaleConstraints(
-    const PageScaleConstraints& newConstraints) {
-  page().setUserAgentPageScaleConstraints(newConstraints);
-}
-
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/frame/FrameHost.h b/third_party/WebKit/Source/core/frame/FrameHost.h
index 9b3bc06..a21b44e6 100644
--- a/third_party/WebKit/Source/core/frame/FrameHost.h
+++ b/third_party/WebKit/Source/core/frame/FrameHost.h
@@ -45,7 +45,6 @@
 class EventHandlerRegistry;
 class OverscrollController;
 class Page;
-struct PageScaleConstraints;
 class PageScaleConstraintsSet;
 class TopDocumentRootScrollerController;
 class VisualViewport;
@@ -105,10 +104,6 @@
   }
   int subframeCount() const;
 
-  void setDefaultPageScaleLimits(float minScale, float maxScale);
-  void setUserAgentPageScaleConstraints(
-      const PageScaleConstraints& newConstraints);
-
  private:
   explicit FrameHost(Page&);
 
diff --git a/third_party/WebKit/Source/core/frame/FrameView.cpp b/third_party/WebKit/Source/core/frame/FrameView.cpp
index 5c8e3d3..e3c6e83 100644
--- a/third_party/WebKit/Source/core/frame/FrameView.cpp
+++ b/third_party/WebKit/Source/core/frame/FrameView.cpp
@@ -3556,7 +3556,8 @@
   return roundedIntPoint(layoutItem.absoluteToLocal(point, UseTransforms));
 }
 
-IntRect FrameView::convertToContainingWidget(const IntRect& localRect) const {
+IntRect FrameView::convertToContainingFrameViewBase(
+    const IntRect& localRect) const {
   if (const FrameView* parentView = toFrameView(parent())) {
     // Get our layoutObject in the parent view
     LayoutPartItem layoutItem = m_frame->ownerLayoutItem();
@@ -3573,7 +3574,7 @@
   return localRect;
 }
 
-IntRect FrameView::convertFromContainingWidget(
+IntRect FrameView::convertFromContainingFrameViewBase(
     const IntRect& parentRect) const {
   if (const FrameView* parentView = toFrameView(parent())) {
     // Get our layoutObject in the parent view
@@ -3591,7 +3592,7 @@
   return parentRect;
 }
 
-IntPoint FrameView::convertToContainingWidget(
+IntPoint FrameView::convertToContainingFrameViewBase(
     const IntPoint& localPoint) const {
   if (const FrameView* parentView = toFrameView(parent())) {
     // Get our layoutObject in the parent view
@@ -3610,7 +3611,7 @@
   return localPoint;
 }
 
-IntPoint FrameView::convertFromContainingWidget(
+IntPoint FrameView::convertFromContainingFrameViewBase(
     const IntPoint& parentPoint) const {
   if (const FrameView* parentView = toFrameView(parent())) {
     // Get our layoutObject in the parent view
@@ -4477,7 +4478,7 @@
   return false;
 }
 
-FrameViewBase* FrameView::getWidget() {
+FrameViewBase* FrameView::getFrameViewBase() {
   return this;
 }
 
@@ -4593,7 +4594,7 @@
          (verticalScrollbar() && height() - verticalScrollbar()->height() > 0);
 }
 
-IntRect FrameView::convertFromScrollbarToContainingWidget(
+IntRect FrameView::convertFromScrollbarToContainingFrameViewBase(
     const Scrollbar& scrollbar,
     const IntRect& localRect) const {
   // Scrollbars won't be transformed within us
@@ -4602,7 +4603,7 @@
   return newRect;
 }
 
-IntRect FrameView::convertFromContainingWidgetToScrollbar(
+IntRect FrameView::convertFromContainingFrameViewBaseToScrollbar(
     const Scrollbar& scrollbar,
     const IntRect& parentRect) const {
   IntRect newRect = parentRect;
@@ -4612,7 +4613,7 @@
 }
 
 // FIXME: test these on windows
-IntPoint FrameView::convertFromScrollbarToContainingWidget(
+IntPoint FrameView::convertFromScrollbarToContainingFrameViewBase(
     const Scrollbar& scrollbar,
     const IntPoint& localPoint) const {
   // Scrollbars won't be transformed within us
@@ -4621,7 +4622,7 @@
   return newPoint;
 }
 
-IntPoint FrameView::convertFromContainingWidgetToScrollbar(
+IntPoint FrameView::convertFromContainingFrameViewBaseToScrollbar(
     const Scrollbar& scrollbar,
     const IntPoint& parentPoint) const {
   IntPoint newPoint = parentPoint;
diff --git a/third_party/WebKit/Source/core/frame/FrameView.h b/third_party/WebKit/Source/core/frame/FrameView.h
index e02bffd3..778f2a3f 100644
--- a/third_party/WebKit/Source/core/frame/FrameView.h
+++ b/third_party/WebKit/Source/core/frame/FrameView.h
@@ -442,7 +442,7 @@
   bool isScrollCornerVisible() const override;
   bool userInputScrollable(ScrollbarOrientation) const override;
   bool shouldPlaceVerticalScrollbarOnLeft() const override;
-  FrameViewBase* getWidget() override;
+  FrameViewBase* getFrameViewBase() override;
   CompositorAnimationHost* compositorAnimationHost() const override;
   CompositorAnimationTimeline* compositorAnimationTimeline() const override;
   LayoutBox* layoutBox() const override;
@@ -646,14 +646,16 @@
   bool scrollbarCornerPresent() const;
   IntRect scrollCornerRect() const override;
 
-  IntRect convertFromScrollbarToContainingWidget(const Scrollbar&,
-                                                 const IntRect&) const override;
-  IntRect convertFromContainingWidgetToScrollbar(const Scrollbar&,
-                                                 const IntRect&) const override;
-  IntPoint convertFromScrollbarToContainingWidget(
+  IntRect convertFromScrollbarToContainingFrameViewBase(
+      const Scrollbar&,
+      const IntRect&) const override;
+  IntRect convertFromContainingFrameViewBaseToScrollbar(
+      const Scrollbar&,
+      const IntRect&) const override;
+  IntPoint convertFromScrollbarToContainingFrameViewBase(
       const Scrollbar&,
       const IntPoint&) const override;
-  IntPoint convertFromContainingWidgetToScrollbar(
+  IntPoint convertFromContainingFrameViewBaseToScrollbar(
       const Scrollbar&,
       const IntPoint&) const override;
 
@@ -954,10 +956,10 @@
 
   // Override FrameViewBase methods to do point conversion via layoutObjects, in
   // order to take transforms into account.
-  IntRect convertToContainingWidget(const IntRect&) const override;
-  IntRect convertFromContainingWidget(const IntRect&) const override;
-  IntPoint convertToContainingWidget(const IntPoint&) const override;
-  IntPoint convertFromContainingWidget(const IntPoint&) const override;
+  IntRect convertToContainingFrameViewBase(const IntRect&) const override;
+  IntRect convertFromContainingFrameViewBase(const IntRect&) const override;
+  IntPoint convertToContainingFrameViewBase(const IntPoint&) const override;
+  IntPoint convertFromContainingFrameViewBase(const IntPoint&) const override;
 
   void didChangeGlobalRootScroller() override;
 
diff --git a/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp b/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp
index 78e95e3..5cf10db2 100644
--- a/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp
+++ b/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp
@@ -1119,6 +1119,10 @@
   page->chromeClient().setStatusbarText(m_defaultStatus);
 }
 
+String LocalDOMWindow::origin() const {
+  return getExecutionContext()->getSecurityOrigin()->toString();
+}
+
 Document* LocalDOMWindow::document() const {
   return m_document.get();
 }
diff --git a/third_party/WebKit/Source/core/frame/LocalDOMWindow.h b/third_party/WebKit/Source/core/frame/LocalDOMWindow.h
index 49e7718..d8bd0b0 100644
--- a/third_party/WebKit/Source/core/frame/LocalDOMWindow.h
+++ b/third_party/WebKit/Source/core/frame/LocalDOMWindow.h
@@ -152,6 +152,7 @@
   void setStatus(const String&);
   String defaultStatus() const;
   void setDefaultStatus(const String&);
+  String origin() const;
 
   // DOM Level 2 AbstractView Interface
   Document* document() const;
diff --git a/third_party/WebKit/Source/core/frame/RootFrameViewport.cpp b/third_party/WebKit/Source/core/frame/RootFrameViewport.cpp
index 558bc5e9..c54b6e21 100644
--- a/third_party/WebKit/Source/core/frame/RootFrameViewport.cpp
+++ b/third_party/WebKit/Source/core/frame/RootFrameViewport.cpp
@@ -448,8 +448,8 @@
   visualViewport().cancelProgrammaticScrollAnimation();
 }
 
-FrameViewBase* RootFrameViewport::getWidget() {
-  return visualViewport().getWidget();
+FrameViewBase* RootFrameViewport::getFrameViewBase() {
+  return visualViewport().getFrameViewBase();
 }
 
 void RootFrameViewport::clearScrollableArea() {
diff --git a/third_party/WebKit/Source/core/frame/RootFrameViewport.h b/third_party/WebKit/Source/core/frame/RootFrameViewport.h
index 7cbadcc..33ccd98 100644
--- a/third_party/WebKit/Source/core/frame/RootFrameViewport.h
+++ b/third_party/WebKit/Source/core/frame/RootFrameViewport.h
@@ -96,7 +96,7 @@
   void updateCompositorScrollAnimations() override;
   void cancelProgrammaticScrollAnimation() override;
   ScrollBehavior scrollBehaviorStyle() const override;
-  FrameViewBase* getWidget() override;
+  FrameViewBase* getFrameViewBase() override;
   void clearScrollableArea() override;
   LayoutBox* layoutBox() const override;
   FloatQuad localToVisibleContentQuad(const FloatQuad&,
diff --git a/third_party/WebKit/Source/core/frame/Settings.json5 b/third_party/WebKit/Source/core/frame/Settings.json5
index c32d7ef..ea068413 100644
--- a/third_party/WebKit/Source/core/frame/Settings.json5
+++ b/third_party/WebKit/Source/core/frame/Settings.json5
@@ -216,10 +216,6 @@
     },
 
     {
-      name: "mediaControlsOverlayPlayButtonEnabled",
-      initial: false,
-    },
-    {
       name: "mediaPlaybackRequiresUserGesture",
       initial: false,
     },
diff --git a/third_party/WebKit/Source/core/frame/UseCounter.cpp b/third_party/WebKit/Source/core/frame/UseCounter.cpp
index e7361a7..b6219c0 100644
--- a/third_party/WebKit/Source/core/frame/UseCounter.cpp
+++ b/third_party/WebKit/Source/core/frame/UseCounter.cpp
@@ -46,7 +46,7 @@
 }
 
 // Make sure update_use_counter_css.py was run which updates histograms.xml.
-constexpr int kMaximumCSSSampleId = 556;
+constexpr int kMaximumCSSSampleId = 557;
 
 }  // namespace
 
@@ -1081,6 +1081,8 @@
       return 555;
     case CSSPropertyAliasLineBreak:
       return 556;
+    case CSSPropertyPlaceContent:
+      return 557;
     // 1. Add new features above this line (don't change the assigned numbers of
     // the existing items).
     // 2. Update kMaximumCSSSampleId with the new maximum value.
@@ -1101,7 +1103,7 @@
       m_disableReporting(false),
       m_context(context),
       m_featuresRecorded(NumberOfFeatures),
-      m_CSSRecorded(lastUnresolvedCSSProperty + 1) {}
+      m_CSSRecorded(numCSSPropertyIDs) {}
 
 void UseCounter::muteForInspector() {
   m_muteCount++;
@@ -1308,8 +1310,7 @@
 }
 
 UseCounter::LegacyCounter::LegacyCounter()
-    : m_featureBits(NumberOfFeatures),
-      m_CSSBits(lastUnresolvedCSSProperty + 1) {}
+    : m_featureBits(NumberOfFeatures), m_CSSBits(numCSSPropertyIDs) {}
 
 UseCounter::LegacyCounter::~LegacyCounter() {
   // PageDestruction was intended to be used as a scale, but it's broken (due to
@@ -1343,7 +1344,7 @@
       EnumerationHistogram, cssPropertiesHistogram,
       ("WebCore.FeatureObserver.CSSProperties", kMaximumCSSSampleId));
   bool needsPagesMeasuredUpdate = false;
-  for (size_t i = firstCSSProperty; i <= lastUnresolvedCSSProperty; ++i) {
+  for (size_t i = firstCSSProperty; i < numCSSPropertyIDs; ++i) {
     if (m_CSSBits.quickGet(i)) {
       int cssSampleId = mapCSSPropertyIdToCSSSampleIdForHistogram(
           static_cast<CSSPropertyID>(i));
diff --git a/third_party/WebKit/Source/core/frame/UseCounter.h b/third_party/WebKit/Source/core/frame/UseCounter.h
index d00df541..97f324bb 100644
--- a/third_party/WebKit/Source/core/frame/UseCounter.h
+++ b/third_party/WebKit/Source/core/frame/UseCounter.h
@@ -1476,6 +1476,7 @@
     ScrollByKeyboardSpacebarKey = 1846,
     ScrollByTouch = 1847,
     ScrollByWheel = 1848,
+    ScheduledActionIgnored = 1849,
 
     // Add new features immediately above this line. Don't change assigned
     // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/WebKit/Source/core/frame/VisualViewport.cpp b/third_party/WebKit/Source/core/frame/VisualViewport.cpp
index 6c854a6..577f983 100644
--- a/third_party/WebKit/Source/core/frame/VisualViewport.cpp
+++ b/third_party/WebKit/Source/core/frame/VisualViewport.cpp
@@ -681,7 +681,7 @@
              : 0;
 }
 
-FrameViewBase* VisualViewport::getWidget() {
+FrameViewBase* VisualViewport::getFrameViewBase() {
   return mainFrame()->view();
 }
 
diff --git a/third_party/WebKit/Source/core/frame/VisualViewport.h b/third_party/WebKit/Source/core/frame/VisualViewport.h
index 0e8ee55..3a0afe6 100644
--- a/third_party/WebKit/Source/core/frame/VisualViewport.h
+++ b/third_party/WebKit/Source/core/frame/VisualViewport.h
@@ -191,7 +191,7 @@
   GraphicsLayer* layerForScrolling() const override;
   GraphicsLayer* layerForHorizontalScrollbar() const override;
   GraphicsLayer* layerForVerticalScrollbar() const override;
-  FrameViewBase* getWidget() override;
+  FrameViewBase* getFrameViewBase() override;
   CompositorAnimationHost* compositorAnimationHost() const override;
   CompositorAnimationTimeline* compositorAnimationTimeline() const override;
   IntRect visibleContentRect(
diff --git a/third_party/WebKit/Source/core/frame/Window.idl b/third_party/WebKit/Source/core/frame/Window.idl
index 95949b9..c86c8b2 100644
--- a/third_party/WebKit/Source/core/frame/Window.idl
+++ b/third_party/WebKit/Source/core/frame/Window.idl
@@ -37,6 +37,7 @@
     [Unforgeable, CrossOrigin] readonly attribute Window window;
     [Replaceable, CrossOrigin] readonly attribute Window self;
     [Unforgeable, CachedAccessor] readonly attribute Document document;
+    [Replaceable] readonly attribute DOMString origin;
     attribute DOMString name;
     [PutForwards=href, Unforgeable, CrossOrigin=(Getter,Setter), Custom=Getter] readonly attribute Location location;
     readonly attribute History history;
diff --git a/third_party/WebKit/Source/core/html/HTMLFrameSetElement.cpp b/third_party/WebKit/Source/core/html/HTMLFrameSetElement.cpp
index f3f5b17..581d619 100644
--- a/third_party/WebKit/Source/core/html/HTMLFrameSetElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLFrameSetElement.cpp
@@ -275,7 +275,6 @@
     layoutObject()->setNeedsLayoutAndFullPaintInvalidation(
         LayoutInvalidationReason::StyleChange);
     clearNeedsStyleRecalc();
-    clearNeedsReattachLayoutTree();
   }
 }
 
diff --git a/third_party/WebKit/Source/core/html/HTMLTextAreaElement.cpp b/third_party/WebKit/Source/core/html/HTMLTextAreaElement.cpp
index c85a2a35..14546b5 100644
--- a/third_party/WebKit/Source/core/html/HTMLTextAreaElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLTextAreaElement.cpp
@@ -383,34 +383,24 @@
 }
 
 void HTMLTextAreaElement::setNonDirtyValue(const String& value) {
-  setValueCommon(value, DispatchNoEvent, SetSeletion);
+  setValueCommon(value, DispatchNoEvent);
   m_isDirty = false;
 }
 
 void HTMLTextAreaElement::setValueCommon(const String& newValue,
-                                         TextFieldEventBehavior eventBehavior,
-                                         SetValueCommonOption setValueOption) {
+                                         TextFieldEventBehavior eventBehavior) {
   // Code elsewhere normalizes line endings added by the user via the keyboard
   // or pasting.  We normalize line endings coming from JavaScript here.
   String normalizedValue = newValue.isNull() ? "" : newValue;
   normalizedValue.replace("\r\n", "\n");
   normalizedValue.replace('\r', '\n');
 
-  // Return early because we don't want to trigger other side effects
-  // when the value isn't changing.
-  // FIXME: Simple early return doesn't match the Firefox ever.
-  // Remove these lines.
-  if (normalizedValue == value()) {
-    if (setValueOption == SetSeletion) {
-      setNeedsValidityCheck();
-      if (isFinishedParsingChildren()) {
-        // Set the caret to the end of the text value except for initialize.
-        unsigned endOfString = m_value.length();
-        setSelectionRange(endOfString, endOfString);
-      }
-    }
+  // Return early because we don't want to trigger other side effects when the
+  // value isn't changing. This is interoperable though the specification
+  // doesn't define so.
+  // https://github.com/whatwg/html/issues/2412
+  if (normalizedValue == value())
     return;
-  }
 
   m_value = normalizedValue;
   setInnerEditorValue(m_value);
@@ -642,7 +632,7 @@
     const Element& source) {
   const HTMLTextAreaElement& sourceElement =
       static_cast<const HTMLTextAreaElement&>(source);
-  setValueCommon(sourceElement.value(), DispatchNoEvent, SetSeletion);
+  setValueCommon(sourceElement.value(), DispatchNoEvent);
   m_isDirty = sourceElement.m_isDirty;
   TextControlElement::copyNonAttributePropertiesFromElement(source);
 }
diff --git a/third_party/WebKit/Source/core/html/HTMLTextAreaElement.h b/third_party/WebKit/Source/core/html/HTMLTextAreaElement.h
index 3bdb7c68..9fd8c0602 100644
--- a/third_party/WebKit/Source/core/html/HTMLTextAreaElement.h
+++ b/third_party/WebKit/Source/core/html/HTMLTextAreaElement.h
@@ -68,7 +68,6 @@
   explicit HTMLTextAreaElement(Document&);
 
   enum WrapMethod { NoWrap, SoftWrap, HardWrap };
-  enum SetValueCommonOption { NotSetSelection, SetSeletion };
 
   void didAddUserAgentShadowRoot(ShadowRoot&) override;
   // FIXME: Author shadows should be allowed
@@ -80,9 +79,7 @@
   void updateValue() const;
   void setInnerEditorValue(const String&) override;
   void setNonDirtyValue(const String&);
-  void setValueCommon(const String&,
-                      TextFieldEventBehavior,
-                      SetValueCommonOption = NotSetSelection);
+  void setValueCommon(const String&, TextFieldEventBehavior);
 
   bool isPlaceholderVisible() const override { return m_isPlaceholderVisible; }
   void setPlaceholderVisibility(bool) override;
diff --git a/third_party/WebKit/Source/core/html/forms/RadioInputType.cpp b/third_party/WebKit/Source/core/html/forms/RadioInputType.cpp
index ed9afd7b..24c798e 100644
--- a/third_party/WebKit/Source/core/html/forms/RadioInputType.cpp
+++ b/third_party/WebKit/Source/core/html/forms/RadioInputType.cpp
@@ -112,13 +112,13 @@
 
   // We can only stay within the form's children if the form hasn't been demoted
   // to a leaf because of malformed HTML.
-  HTMLInputElement* inputElement = findNextFocusableRadioButtonInGroup(
-      toHTMLInputElement(&element()), forward);
+  HTMLInputElement* inputElement =
+      findNextFocusableRadioButtonInGroup(&element(), forward);
   if (!inputElement) {
     // Traverse in reverse direction till last or first radio button
     forward = !(forward);
-    HTMLInputElement* nextInputElement = findNextFocusableRadioButtonInGroup(
-        toHTMLInputElement(&element()), forward);
+    HTMLInputElement* nextInputElement =
+        findNextFocusableRadioButtonInGroup(&element(), forward);
     while (nextInputElement) {
       inputElement = nextInputElement;
       nextInputElement =
diff --git a/third_party/WebKit/Source/core/html/shadow/MediaControls.cpp b/third_party/WebKit/Source/core/html/shadow/MediaControls.cpp
index 087b101..be254c1 100644
--- a/third_party/WebKit/Source/core/html/shadow/MediaControls.cpp
+++ b/third_party/WebKit/Source/core/html/shadow/MediaControls.cpp
@@ -222,8 +222,7 @@
   MediaControlOverlayEnclosureElement* overlayEnclosure =
       MediaControlOverlayEnclosureElement::create(*this);
 
-  if (document().settings() &&
-      document().settings()->getMediaControlsOverlayPlayButtonEnabled()) {
+  if (RuntimeEnabledFeatures::mediaControlsOverlayPlayButtonEnabled()) {
     MediaControlOverlayPlayButtonElement* overlayPlayButton =
         MediaControlOverlayPlayButtonElement::create(*this);
     m_overlayPlayButton = overlayPlayButton;
@@ -338,6 +337,35 @@
           *this, MediaControlToggleClosedCaptionsButtonElement::create(*this)));
 }
 
+Node::InsertionNotificationRequest MediaControls::insertedInto(
+    ContainerNode* root) {
+  if (!mediaElement().isConnected())
+    return HTMLDivElement::insertedInto(root);
+
+  // TODO(mlamouri): we should show the controls instead of having
+  // HTMLMediaElement do it.
+
+  // m_windowEventListener doesn't need to be re-attached as it's only needed
+  // when a menu is visible.
+  m_mediaEventListener->attach();
+  if (m_orientationLockDelegate)
+    m_orientationLockDelegate->attach();
+
+  return HTMLDivElement::insertedInto(root);
+}
+
+void MediaControls::removedFrom(ContainerNode*) {
+  DCHECK(!mediaElement().isConnected());
+
+  // TODO(mlamouri): we hide show the controls instead of having
+  // HTMLMediaElement do it.
+
+  m_windowEventListener->stop();
+  m_mediaEventListener->detach();
+  if (m_orientationLockDelegate)
+    m_orientationLockDelegate->detach();
+}
+
 void MediaControls::reset() {
   EventDispatchForbiddenScope::AllowUserAgentEvents allowEventsInShadow;
   BatchedControlUpdate batch(this);
@@ -688,27 +716,6 @@
   return contains(relatedTarget->toNode());
 }
 
-void MediaControls::onInsertedIntoDocument() {
-  // TODO(mlamouri): we should show the controls instead of having
-  // HTMLMediaElement do it.
-
-  // m_windowEventListener doesn't need to be re-attached as it's only needed
-  // when a menu is visible.
-  m_mediaEventListener->attach();
-  if (m_orientationLockDelegate)
-    m_orientationLockDelegate->attach();
-}
-
-void MediaControls::onRemovedFromDocument() {
-  // TODO(mlamouri): we hide show the controls instead of having
-  // HTMLMediaElement do it.
-
-  m_windowEventListener->stop();
-  m_mediaEventListener->detach();
-  if (m_orientationLockDelegate)
-    m_orientationLockDelegate->detach();
-}
-
 void MediaControls::onVolumeChange() {
   m_muteButton->updateDisplayType();
   m_volumeSlider->setVolume(mediaElement().muted() ? 0
diff --git a/third_party/WebKit/Source/core/html/shadow/MediaControls.h b/third_party/WebKit/Source/core/html/shadow/MediaControls.h
index c38bf9d..5ced7c1 100644
--- a/third_party/WebKit/Source/core/html/shadow/MediaControls.h
+++ b/third_party/WebKit/Source/core/html/shadow/MediaControls.h
@@ -44,6 +44,10 @@
 
   HTMLMediaElement& mediaElement() const { return *m_mediaElement; }
 
+  // Node override.
+  Node::InsertionNotificationRequest insertedInto(ContainerNode*) override;
+  void removedFrom(ContainerNode*) override;
+
   void reset();
 
   void show();
@@ -166,8 +170,6 @@
   bool containsRelatedTarget(Event*);
 
   // Methods called by MediaControlsMediaEventListener.
-  void onInsertedIntoDocument();
-  void onRemovedFromDocument();
   void onVolumeChange();
   void onFocusIn();
   void onTimeUpdate();
diff --git a/third_party/WebKit/Source/core/html/shadow/MediaControlsMediaEventListener.cpp b/third_party/WebKit/Source/core/html/shadow/MediaControlsMediaEventListener.cpp
index 76d680d..070f17b 100644
--- a/third_party/WebKit/Source/core/html/shadow/MediaControlsMediaEventListener.cpp
+++ b/third_party/WebKit/Source/core/html/shadow/MediaControlsMediaEventListener.cpp
@@ -14,18 +14,13 @@
 MediaControlsMediaEventListener::MediaControlsMediaEventListener(
     MediaControls* mediaControls)
     : EventListener(CPPEventListenerType), m_mediaControls(mediaControls) {
-  // These events are always active because they are needed in order to attach
-  // or detach the whole controls.
-  mediaElement().addEventListener(EventTypeNames::DOMNodeInsertedIntoDocument,
-                                  this, false);
-  mediaElement().addEventListener(EventTypeNames::DOMNodeRemovedFromDocument,
-                                  this, false);
-
   if (mediaElement().isConnected())
     attach();
 }
 
 void MediaControlsMediaEventListener::attach() {
+  DCHECK(mediaElement().isConnected());
+
   mediaElement().addEventListener(EventTypeNames::volumechange, this, false);
   mediaElement().addEventListener(EventTypeNames::focusin, this, false);
   mediaElement().addEventListener(EventTypeNames::timeupdate, this, false);
@@ -50,6 +45,8 @@
 }
 
 void MediaControlsMediaEventListener::detach() {
+  DCHECK(!mediaElement().isConnected());
+
   m_mediaControls->document().removeEventListener(
       EventTypeNames::fullscreenchange, this, false);
 
@@ -71,14 +68,6 @@
 void MediaControlsMediaEventListener::handleEvent(
     ExecutionContext* executionContext,
     Event* event) {
-  if (event->type() == EventTypeNames::DOMNodeInsertedIntoDocument) {
-    m_mediaControls->onInsertedIntoDocument();
-    return;
-  }
-  if (event->type() == EventTypeNames::DOMNodeRemovedFromDocument) {
-    m_mediaControls->onRemovedFromDocument();
-    return;
-  }
   if (event->type() == EventTypeNames::volumechange) {
     m_mediaControls->onVolumeChange();
     return;
diff --git a/third_party/WebKit/Source/core/html/shadow/MediaControlsOrientationLockDelegate.cpp b/third_party/WebKit/Source/core/html/shadow/MediaControlsOrientationLockDelegate.cpp
index f29c4c5e..71d89b3 100644
--- a/third_party/WebKit/Source/core/html/shadow/MediaControlsOrientationLockDelegate.cpp
+++ b/third_party/WebKit/Source/core/html/shadow/MediaControlsOrientationLockDelegate.cpp
@@ -69,6 +69,8 @@
 }
 
 void MediaControlsOrientationLockDelegate::attach() {
+  DCHECK(videoElement().isConnected());
+
   document().addEventListener(EventTypeNames::fullscreenchange, this, true);
   videoElement().addEventListener(EventTypeNames::webkitfullscreenchange, this,
                                   true);
@@ -76,6 +78,8 @@
 }
 
 void MediaControlsOrientationLockDelegate::detach() {
+  DCHECK(!videoElement().isConnected());
+
   document().removeEventListener(EventTypeNames::fullscreenchange, this, true);
   videoElement().removeEventListener(EventTypeNames::webkitfullscreenchange,
                                      this, true);
diff --git a/third_party/WebKit/Source/core/layout/BUILD.gn b/third_party/WebKit/Source/core/layout/BUILD.gn
index cea809c..acd5a62 100644
--- a/third_party/WebKit/Source/core/layout/BUILD.gn
+++ b/third_party/WebKit/Source/core/layout/BUILD.gn
@@ -280,10 +280,17 @@
     "line/RootInlineBox.cpp",
     "line/TrailingObjects.cpp",
     "line/TrailingObjects.h",
+    "ng/geometry/ng_box_strut.cc",
+    "ng/geometry/ng_box_strut.h",
+    "ng/geometry/ng_edge.h",
     "ng/geometry/ng_logical_offset.cc",
     "ng/geometry/ng_logical_offset.h",
+    "ng/geometry/ng_logical_rect.cc",
+    "ng/geometry/ng_logical_rect.h",
     "ng/geometry/ng_logical_size.cc",
     "ng/geometry/ng_logical_size.h",
+    "ng/geometry/ng_margin_strut.cc",
+    "ng/geometry/ng_margin_strut.h",
     "ng/geometry/ng_physical_location.cc",
     "ng/geometry/ng_physical_location.h",
     "ng/geometry/ng_physical_offset.cc",
@@ -292,6 +299,8 @@
     "ng/geometry/ng_physical_rect.h",
     "ng/geometry/ng_physical_size.cc",
     "ng/geometry/ng_physical_size.h",
+    "ng/geometry/ng_static_position.cc",
+    "ng/geometry/ng_static_position.h",
     "ng/layout_ng_block_flow.cc",
     "ng/layout_ng_block_flow.h",
     "ng/ng_absolute_utils.cc",
@@ -313,6 +322,8 @@
     "ng/ng_constraint_space.h",
     "ng/ng_constraint_space_builder.cc",
     "ng/ng_constraint_space_builder.h",
+    "ng/ng_exclusion.cc",
+    "ng/ng_exclusion.h",
     "ng/ng_floating_object.h",
     "ng/ng_fragment.cc",
     "ng/ng_fragment.h",
@@ -335,6 +346,8 @@
     "ng/ng_line_builder.cc",
     "ng/ng_line_builder.h",
     "ng/ng_macros.h",
+    "ng/ng_min_max_content_size.cc",
+    "ng/ng_min_max_content_size.h",
     "ng/ng_out_of_flow_layout_part.cc",
     "ng/ng_out_of_flow_layout_part.h",
     "ng/ng_physical_box_fragment.cc",
@@ -346,8 +359,6 @@
     "ng/ng_text_fragment.h",
     "ng/ng_text_layout_algorithm.cc",
     "ng/ng_text_layout_algorithm.h",
-    "ng/ng_units.cc",
-    "ng/ng_units.h",
     "ng/ng_writing_mode.cc",
     "ng/ng_writing_mode.h",
     "shapes/BoxShape.cpp",
diff --git a/third_party/WebKit/Source/core/layout/LayoutBox.h b/third_party/WebKit/Source/core/layout/LayoutBox.h
index 37084cfc..d80be21e 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBox.h
+++ b/third_party/WebKit/Source/core/layout/LayoutBox.h
@@ -1387,8 +1387,7 @@
 
   virtual ItemPosition selfAlignmentNormalBehavior(
       const LayoutBox* child = nullptr) const {
-    DCHECK(!child);
-    return ItemPositionStretch;
+    return ItemPositionStart;
   }
 
   // Returns false if it could not cheaply compute the extent (e.g. fixed
diff --git a/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.h b/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.h
index 38f2c5f0..76092ca4 100644
--- a/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.h
+++ b/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.h
@@ -91,6 +91,10 @@
 
   void styleDidChange(StyleDifference, const ComputedStyle* oldStyle) override;
   void removeChild(LayoutObject*) override;
+  ItemPosition selfAlignmentNormalBehavior(
+      const LayoutBox* child = nullptr) const override {
+    return ItemPositionStretch;
+  }
 
  private:
   enum FlexSign {
diff --git a/third_party/WebKit/Source/core/layout/LayoutFullScreen.h b/third_party/WebKit/Source/core/layout/LayoutFullScreen.h
index db7d3e6..00de48c5 100644
--- a/third_party/WebKit/Source/core/layout/LayoutFullScreen.h
+++ b/third_party/WebKit/Source/core/layout/LayoutFullScreen.h
@@ -69,7 +69,6 @@
   LayoutBlockFlow* m_placeholder;
   ItemPosition selfAlignmentNormalBehavior(
       const LayoutBox* child = nullptr) const override {
-    DCHECK(!child);
     return ItemPositionCenter;
   }
 };
diff --git a/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.cpp b/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.cpp
index 488e4ac..d3bba0a 100644
--- a/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.cpp
@@ -612,9 +612,16 @@
 }
 
 FragmentationContext*
-LayoutMultiColumnFlowThread::enclosingFragmentationContext() const {
-  if (LayoutMultiColumnFlowThread* enclosingFlowThread =
-          this->enclosingFlowThread())
+LayoutMultiColumnFlowThread::enclosingFragmentationContext(
+    AncestorSearchConstraint constraint) const {
+  // If this multicol container is strictly unbreakable (due to having
+  // scrollbars, for instance), it's also strictly unbreakable in any outer
+  // fragmentation context. As such, what kind of fragmentation that goes on
+  // inside this multicol container is completely opaque to the ancestors.
+  if (constraint == IsolateUnbreakableContainers &&
+      multiColumnBlockFlow()->getPaginationBreakability() == ForbidBreaks)
+    return nullptr;
+  if (auto* enclosingFlowThread = this->enclosingFlowThread())
     return enclosingFlowThread;
   return view()->fragmentationContext();
 }
diff --git a/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.h b/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.h
index 8264eb4..91fb0d7 100644
--- a/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.h
+++ b/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.h
@@ -260,10 +260,25 @@
   bool removeSpannerPlaceholderIfNoLongerValid(
       LayoutBox* spannerObjectInFlowThread);
 
+  // Search mode when looking for an enclosing fragmentation context.
+  enum AncestorSearchConstraint {
+    // No constraints. Sometimes we just want to find all enclosing
+    // fragmentation contexts, e.g. to calculate the accumulated visual
+    // translation.
+    AnyAncestor,
+
+    // Consider fragmentation contexts that are strictly unbreakable (seen from
+    // the outside) to be isolated from the rest, so that such fragmentation
+    // contexts don't participate in fragmentation of enclosing fragmentation
+    // contexts, apart from taking up space and otherwise being completely
+    // unbreakable. This is typically what we want to do during layout.
+    IsolateUnbreakableContainers,
+  };
   LayoutMultiColumnFlowThread* enclosingFlowThread() const;
-  FragmentationContext* enclosingFragmentationContext() const;
+  FragmentationContext* enclosingFragmentationContext(
+      AncestorSearchConstraint = IsolateUnbreakableContainers) const;
   LayoutUnit blockOffsetInEnclosingFragmentationContext() const {
-    ASSERT(enclosingFragmentationContext());
+    DCHECK(enclosingFragmentationContext(AnyAncestor));
     return m_blockOffsetInEnclosingFragmentationContext;
   }
 
diff --git a/third_party/WebKit/Source/core/layout/LayoutTable.cpp b/third_party/WebKit/Source/core/layout/LayoutTable.cpp
index ea658b4..c2ce30f 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTable.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutTable.cpp
@@ -297,17 +297,21 @@
       availableContentLogicalWidth = shrinkLogicalWidthToAvoidFloats(
           marginStart, marginEnd, toLayoutBlockFlow(cb));
 
-    // Ensure we aren't bigger than our available width.
-    LayoutUnit maxWidth = maxPreferredLogicalWidth();
-    // scaledWidthFromPercentColumns depends on m_layoutStruct in
-    // TableLayoutAlgorithmAuto, which maxPreferredLogicalWidth fills in. So
-    // scaledWidthFromPercentColumns has to be called after
-    // maxPreferredLogicalWidth.
-    LayoutUnit scaledWidth = m_tableLayout->scaledWidthFromPercentColumns() +
-                             bordersPaddingAndSpacingInRowDirection();
-    maxWidth = std::max(scaledWidth, maxWidth);
-    setLogicalWidth(
-        LayoutUnit(std::min(availableContentLogicalWidth, maxWidth).floor()));
+    if (hasStretchedLogicalWidth()) {
+      setLogicalWidth(availableContentLogicalWidth);
+    } else {
+      // Ensure we aren't bigger than our available width.
+      LayoutUnit maxWidth = maxPreferredLogicalWidth();
+      // scaledWidthFromPercentColumns depends on m_layoutStruct in
+      // TableLayoutAlgorithmAuto, which maxPreferredLogicalWidth fills in. So
+      // scaledWidthFromPercentColumns has to be called after
+      // maxPreferredLogicalWidth.
+      LayoutUnit scaledWidth = m_tableLayout->scaledWidthFromPercentColumns() +
+                               bordersPaddingAndSpacingInRowDirection();
+      maxWidth = std::max(scaledWidth, maxWidth);
+      setLogicalWidth(
+          LayoutUnit(std::min(availableContentLogicalWidth, maxWidth).floor()));
+    }
   }
 
   // Ensure we aren't bigger than our max-width style.
@@ -465,11 +469,16 @@
 
 LayoutUnit LayoutTable::logicalHeightFromStyle() const {
   LayoutUnit computedLogicalHeight;
-  Length logicalHeightLength = style()->logicalHeight();
-  if (logicalHeightLength.isIntrinsic() ||
-      (logicalHeightLength.isSpecified() && logicalHeightLength.isPositive())) {
-    computedLogicalHeight =
-        convertStyleLogicalHeightToComputedHeight(logicalHeightLength);
+  if (hasOverrideLogicalContentHeight()) {
+    computedLogicalHeight = overrideLogicalContentHeight();
+  } else {
+    Length logicalHeightLength = style()->logicalHeight();
+    if (logicalHeightLength.isIntrinsic() ||
+        (logicalHeightLength.isSpecified() &&
+         logicalHeightLength.isPositive())) {
+      computedLogicalHeight =
+          convertStyleLogicalHeightToComputedHeight(logicalHeightLength);
+    }
   }
 
   Length logicalMaxHeightLength = style()->logicalMaxHeight();
diff --git a/third_party/WebKit/Source/core/layout/ng/geometry/ng_box_strut.cc b/third_party/WebKit/Source/core/layout/ng/geometry/ng_box_strut.cc
new file mode 100644
index 0000000..2fa7228
--- /dev/null
+++ b/third_party/WebKit/Source/core/layout/ng/geometry/ng_box_strut.cc
@@ -0,0 +1,56 @@
+// 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/layout/ng/geometry/ng_box_strut.h"
+
+#include "wtf/text/WTFString.h"
+
+namespace blink {
+
+bool NGBoxStrut::IsEmpty() const {
+  return *this == NGBoxStrut();
+}
+
+bool NGBoxStrut::operator==(const NGBoxStrut& other) const {
+  return std::tie(other.inline_start, other.inline_end, other.block_start,
+                  other.block_end) ==
+         std::tie(inline_start, inline_end, block_start, block_end);
+}
+
+// Converts physical dimensions to logical ones per
+// https://drafts.csswg.org/css-writing-modes-3/#logical-to-physical
+NGBoxStrut NGPhysicalBoxStrut::ConvertToLogical(NGWritingMode writing_mode,
+                                                TextDirection direction) const {
+  NGBoxStrut strut;
+  switch (writing_mode) {
+    case kHorizontalTopBottom:
+      strut = {left, right, top, bottom};
+      break;
+    case kVerticalRightLeft:
+    case kSidewaysRightLeft:
+      strut = {top, bottom, right, left};
+      break;
+    case kVerticalLeftRight:
+      strut = {top, bottom, left, right};
+      break;
+    case kSidewaysLeftRight:
+      strut = {bottom, top, left, right};
+      break;
+  }
+  if (direction == TextDirection::kRtl)
+    std::swap(strut.inline_start, strut.inline_end);
+  return strut;
+}
+
+String NGBoxStrut::ToString() const {
+  return String::format("Inline: (%d %d) Block: (%d %d)", inline_start.toInt(),
+                        inline_end.toInt(), block_start.toInt(),
+                        block_end.toInt());
+}
+
+std::ostream& operator<<(std::ostream& stream, const NGBoxStrut& value) {
+  return stream << value.ToString();
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/geometry/ng_box_strut.h b/third_party/WebKit/Source/core/layout/ng/geometry/ng_box_strut.h
new file mode 100644
index 0000000..2e14309b
--- /dev/null
+++ b/third_party/WebKit/Source/core/layout/ng/geometry/ng_box_strut.h
@@ -0,0 +1,74 @@
+// 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 NGBoxStrut_h
+#define NGBoxStrut_h
+
+#include "core/CoreExport.h"
+#include "core/layout/ng/ng_writing_mode.h"
+#include "platform/LayoutUnit.h"
+#include "platform/text/TextDirection.h"
+
+namespace blink {
+
+// This struct is used for storing margins, borders or padding of a box on all
+// four edges.
+struct CORE_EXPORT NGBoxStrut {
+  NGBoxStrut() {}
+  NGBoxStrut(LayoutUnit inline_start,
+             LayoutUnit inline_end,
+             LayoutUnit block_start,
+             LayoutUnit block_end)
+      : inline_start(inline_start),
+        inline_end(inline_end),
+        block_start(block_start),
+        block_end(block_end) {}
+
+  LayoutUnit InlineSum() const { return inline_start + inline_end; }
+  LayoutUnit BlockSum() const { return block_start + block_end; }
+
+  bool IsEmpty() const;
+
+  // The following two operators exist primarily to have an easy way to access
+  // the sum of border and padding.
+  NGBoxStrut& operator+=(const NGBoxStrut& other) {
+    inline_start += other.inline_start;
+    inline_end += other.inline_end;
+    block_start += other.block_start;
+    block_end += other.block_end;
+    return *this;
+  }
+
+  NGBoxStrut operator+(const NGBoxStrut& other) {
+    NGBoxStrut result(*this);
+    result += other;
+    return result;
+  }
+
+  bool operator==(const NGBoxStrut& other) const;
+
+  String ToString() const;
+
+  LayoutUnit inline_start;
+  LayoutUnit inline_end;
+  LayoutUnit block_start;
+  LayoutUnit block_end;
+};
+
+CORE_EXPORT std::ostream& operator<<(std::ostream&, const NGBoxStrut&);
+
+// Struct to store physical dimensions, independent of writing mode and
+// direction.
+// See https://drafts.csswg.org/css-writing-modes-3/#abstract-box
+struct CORE_EXPORT NGPhysicalBoxStrut {
+  LayoutUnit left;
+  LayoutUnit right;
+  LayoutUnit top;
+  LayoutUnit bottom;
+  NGBoxStrut ConvertToLogical(NGWritingMode, TextDirection) const;
+};
+
+}  // namespace blink
+
+#endif  // NGBoxStrut_h
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_units_test.cc b/third_party/WebKit/Source/core/layout/ng/geometry/ng_box_strut_test.cc
similarity index 71%
rename from third_party/WebKit/Source/core/layout/ng/ng_units_test.cc
rename to third_party/WebKit/Source/core/layout/ng/geometry/ng_box_strut_test.cc
index cd9b9318..7beacbd 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_units_test.cc
+++ b/third_party/WebKit/Source/core/layout/ng/geometry/ng_box_strut_test.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "core/layout/ng/ng_units.h"
+#include "core/layout/ng/geometry/ng_box_strut.h"
 
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -12,7 +12,7 @@
 
 // Ideally, this would be tested by NGBoxStrut::ConvertToPhysical, but
 // this has not been implemented yet.
-TEST(NGUnitsTest, ConvertPhysicalStrutToLogical) {
+TEST(NGGeometryUnitsTest, ConvertPhysicalStrutToLogical) {
   LayoutUnit left{5}, right{10}, top{15}, bottom{20};
   NGPhysicalBoxStrut physical{left, right, top, bottom};
 
@@ -43,22 +43,6 @@
   EXPECT_EQ(right, logical.block_start);
 }
 
-TEST(NGUnitsTest, ShrinkToFit) {
-  MinAndMaxContentSizes sizes;
-
-  sizes.min_content = LayoutUnit(100);
-  sizes.max_content = LayoutUnit(200);
-  EXPECT_EQ(LayoutUnit(200), sizes.ShrinkToFit(LayoutUnit(300)));
-
-  sizes.min_content = LayoutUnit(100);
-  sizes.max_content = LayoutUnit(300);
-  EXPECT_EQ(LayoutUnit(200), sizes.ShrinkToFit(LayoutUnit(200)));
-
-  sizes.min_content = LayoutUnit(200);
-  sizes.max_content = LayoutUnit(300);
-  EXPECT_EQ(LayoutUnit(200), sizes.ShrinkToFit(LayoutUnit(100)));
-}
-
 }  // namespace
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/geometry/ng_edge.h b/third_party/WebKit/Source/core/layout/ng/geometry/ng_edge.h
new file mode 100644
index 0000000..062bc74
--- /dev/null
+++ b/third_party/WebKit/Source/core/layout/ng/geometry/ng_edge.h
@@ -0,0 +1,21 @@
+// 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 NGEdge_h
+#define NGEdge_h
+
+#include "core/CoreExport.h"
+#include "platform/LayoutUnit.h"
+
+namespace blink {
+
+// Struct to represent a simple edge that has start and end.
+struct CORE_EXPORT NGEdge {
+  LayoutUnit start;
+  LayoutUnit end;
+};
+
+}  // namespace blink
+
+#endif  // NGEdge_h
diff --git a/third_party/WebKit/Source/core/layout/ng/geometry/ng_logical_rect.cc b/third_party/WebKit/Source/core/layout/ng/geometry/ng_logical_rect.cc
new file mode 100644
index 0000000..90a5672f2
--- /dev/null
+++ b/third_party/WebKit/Source/core/layout/ng/geometry/ng_logical_rect.cc
@@ -0,0 +1,39 @@
+// 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/layout/ng/geometry/ng_logical_rect.h"
+
+#include "wtf/text/WTFString.h"
+
+namespace blink {
+
+bool NGLogicalRect::IsEmpty() const {
+  return size.IsEmpty() && offset.inline_offset == LayoutUnit() &&
+         offset.block_offset == LayoutUnit();
+}
+
+bool NGLogicalRect::IsContained(const NGLogicalRect& other) const {
+  return !(InlineEndOffset() <= other.InlineStartOffset() ||
+           BlockEndOffset() <= other.BlockStartOffset() ||
+           InlineStartOffset() >= other.InlineEndOffset() ||
+           BlockStartOffset() >= other.BlockEndOffset());
+}
+
+bool NGLogicalRect::operator==(const NGLogicalRect& other) const {
+  return std::tie(other.offset, other.size) == std::tie(offset, size);
+}
+
+String NGLogicalRect::ToString() const {
+  return String::format("%s,%s %sx%s",
+                        offset.inline_offset.toString().ascii().data(),
+                        offset.block_offset.toString().ascii().data(),
+                        size.inline_size.toString().ascii().data(),
+                        size.block_size.toString().ascii().data());
+}
+
+std::ostream& operator<<(std::ostream& os, const NGLogicalRect& value) {
+  return os << value.ToString();
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/geometry/ng_logical_rect.h b/third_party/WebKit/Source/core/layout/ng/geometry/ng_logical_rect.h
new file mode 100644
index 0000000..1256793
--- /dev/null
+++ b/third_party/WebKit/Source/core/layout/ng/geometry/ng_logical_rect.h
@@ -0,0 +1,55 @@
+// 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 NGLogicalRect_h
+#define NGLogicalRect_h
+
+#include "core/CoreExport.h"
+#include "core/layout/ng/geometry/ng_logical_offset.h"
+#include "core/layout/ng/geometry/ng_logical_size.h"
+#include "platform/LayoutUnit.h"
+
+namespace blink {
+
+// NGLogicalRect is the position and size of a rect (typically a fragment)
+// relative to its parent rect in the logical coordinate system.
+struct CORE_EXPORT NGLogicalRect {
+  NGLogicalRect() {}
+  NGLogicalRect(const NGLogicalOffset& offset, const NGLogicalSize& size)
+      : offset(offset), size(size) {}
+  NGLogicalRect(LayoutUnit inline_offset,
+                LayoutUnit block_offset,
+                LayoutUnit inline_size,
+                LayoutUnit block_size)
+      : offset(inline_offset, block_offset), size(inline_size, block_size) {}
+
+  bool IsEmpty() const;
+
+  // Whether this rectangle is contained by the provided rectangle.
+  bool IsContained(const NGLogicalRect& other) const;
+
+  LayoutUnit InlineStartOffset() const { return offset.inline_offset; }
+  LayoutUnit InlineEndOffset() const {
+    return offset.inline_offset + size.inline_size;
+  }
+  LayoutUnit BlockStartOffset() const { return offset.block_offset; }
+  LayoutUnit BlockEndOffset() const {
+    return offset.block_offset + size.block_size;
+  }
+
+  LayoutUnit BlockSize() const { return size.block_size; }
+  LayoutUnit InlineSize() const { return size.inline_size; }
+
+  String ToString() const;
+  bool operator==(const NGLogicalRect& other) const;
+
+  NGLogicalOffset offset;
+  NGLogicalSize size;
+};
+
+CORE_EXPORT std::ostream& operator<<(std::ostream&, const NGLogicalRect&);
+
+}  // namespace blink
+
+#endif  // NGLogicalRect_h
diff --git a/third_party/WebKit/Source/core/layout/ng/geometry/ng_logical_size.h b/third_party/WebKit/Source/core/layout/ng/geometry/ng_logical_size.h
index 2102165..448cd9d0 100644
--- a/third_party/WebKit/Source/core/layout/ng/geometry/ng_logical_size.h
+++ b/third_party/WebKit/Source/core/layout/ng/geometry/ng_logical_size.h
@@ -12,6 +12,7 @@
 namespace blink {
 
 struct NGPhysicalSize;
+#define NGSizeIndefinite LayoutUnit(-1)
 
 // NGLogicalSize is the size of rect (typically a fragment) in the logical
 // coordinate system.
diff --git a/third_party/WebKit/Source/core/layout/ng/geometry/ng_margin_strut.cc b/third_party/WebKit/Source/core/layout/ng/geometry/ng_margin_strut.cc
new file mode 100644
index 0000000..eabab22
--- /dev/null
+++ b/third_party/WebKit/Source/core/layout/ng/geometry/ng_margin_strut.cc
@@ -0,0 +1,35 @@
+// 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/layout/ng/geometry/ng_margin_strut.h"
+
+#include "wtf/text/WTFString.h"
+
+namespace blink {
+
+LayoutUnit NGMarginStrut::Sum() const {
+  return margin + negative_margin;
+}
+
+bool NGMarginStrut::operator==(const NGMarginStrut& other) const {
+  return margin == other.margin && negative_margin == other.negative_margin;
+}
+
+void NGMarginStrut::Append(const LayoutUnit& value) {
+  if (value < 0) {
+    negative_margin = std::min(value, negative_margin);
+  } else {
+    margin = std::max(value, margin);
+  }
+}
+
+String NGMarginStrut::ToString() const {
+  return String::format("%d %d", margin.toInt(), negative_margin.toInt());
+}
+
+std::ostream& operator<<(std::ostream& stream, const NGMarginStrut& value) {
+  return stream << value.ToString();
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/geometry/ng_margin_strut.h b/third_party/WebKit/Source/core/layout/ng/geometry/ng_margin_strut.h
new file mode 100644
index 0000000..d67239d1
--- /dev/null
+++ b/third_party/WebKit/Source/core/layout/ng/geometry/ng_margin_strut.h
@@ -0,0 +1,33 @@
+// 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 NGMarginStrut_h
+#define NGMarginStrut_h
+
+#include "core/CoreExport.h"
+#include "platform/LayoutUnit.h"
+
+namespace blink {
+
+// This struct is used for the margin collapsing calculation.
+struct CORE_EXPORT NGMarginStrut {
+  LayoutUnit margin;
+  LayoutUnit negative_margin;
+
+  // Appends negative or positive value to the current margin strut.
+  void Append(const LayoutUnit& value);
+
+  // Sum up negative and positive margins of this strut.
+  LayoutUnit Sum() const;
+
+  bool operator==(const NGMarginStrut& other) const;
+
+  String ToString() const;
+};
+
+CORE_EXPORT std::ostream& operator<<(std::ostream&, const NGMarginStrut&);
+
+}  // namespace blink
+
+#endif  // NGMarginStrut_h
diff --git a/third_party/WebKit/Source/core/layout/ng/geometry/ng_static_position.cc b/third_party/WebKit/Source/core/layout/ng/geometry/ng_static_position.cc
new file mode 100644
index 0000000..43e3d04d
--- /dev/null
+++ b/third_party/WebKit/Source/core/layout/ng/geometry/ng_static_position.cc
@@ -0,0 +1,35 @@
+// 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/layout/ng/geometry/ng_static_position.h"
+
+namespace blink {
+
+NGStaticPosition NGStaticPosition::Create(NGWritingMode writing_mode,
+                                          TextDirection direction,
+                                          NGPhysicalOffset offset) {
+  NGStaticPosition position;
+  position.offset = offset;
+  switch (writing_mode) {
+    case kHorizontalTopBottom:
+      position.type = (direction == TextDirection::kLtr) ? kTopLeft : kTopRight;
+      break;
+    case kVerticalRightLeft:
+    case kSidewaysRightLeft:
+      position.type =
+          (direction == TextDirection::kLtr) ? kTopRight : kBottomRight;
+      break;
+    case kVerticalLeftRight:
+      position.type =
+          (direction == TextDirection::kLtr) ? kTopLeft : kBottomLeft;
+      break;
+    case kSidewaysLeftRight:
+      position.type =
+          (direction == TextDirection::kLtr) ? kBottomLeft : kTopLeft;
+      break;
+  }
+  return position;
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/geometry/ng_static_position.h b/third_party/WebKit/Source/core/layout/ng/geometry/ng_static_position.h
new file mode 100644
index 0000000..6e39b08
--- /dev/null
+++ b/third_party/WebKit/Source/core/layout/ng/geometry/ng_static_position.h
@@ -0,0 +1,73 @@
+// 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 NGStaticPosition_h
+#define NGStaticPosition_h
+
+#include "core/CoreExport.h"
+#include "core/layout/ng/geometry/ng_physical_offset.h"
+#include "core/layout/ng/ng_writing_mode.h"
+#include "platform/LayoutUnit.h"
+#include "platform/text/TextDirection.h"
+
+namespace blink {
+
+// Represents static position of an out of flow descendant.
+struct CORE_EXPORT NGStaticPosition {
+  enum Type { kTopLeft, kTopRight, kBottomLeft, kBottomRight };
+
+  Type type;  // Logical corner that corresponds to physical top left.
+  NGPhysicalOffset offset;
+
+  // Creates a position with proper type wrt writing mode and direction.
+  static NGStaticPosition Create(NGWritingMode,
+                                 TextDirection,
+                                 NGPhysicalOffset);
+  // Left/Right/TopPosition functions map static position to
+  // left/right/top edge wrt container space.
+  // The function arguments are required to solve the equation:
+  // contaner_size = left + margin_left + width + margin_right + right
+  LayoutUnit LeftPosition(LayoutUnit container_size,
+                          LayoutUnit width,
+                          LayoutUnit margin_left,
+                          LayoutUnit margin_right) const {
+    return GenericPosition(HasLeft(), offset.left, container_size, width,
+                           margin_left, margin_right);
+  }
+  LayoutUnit RightPosition(LayoutUnit container_size,
+                           LayoutUnit width,
+                           LayoutUnit margin_left,
+                           LayoutUnit margin_right) const {
+    return GenericPosition(!HasLeft(), offset.left, container_size, width,
+                           margin_left, margin_right);
+  }
+  LayoutUnit TopPosition(LayoutUnit container_size,
+                         LayoutUnit height,
+                         LayoutUnit margin_top,
+                         LayoutUnit margin_bottom) const {
+    return GenericPosition(HasTop(), offset.top, container_size, height,
+                           margin_top, margin_bottom);
+  }
+
+ private:
+  bool HasTop() const { return type == kTopLeft || type == kTopRight; }
+  bool HasLeft() const { return type == kTopLeft || type == kBottomLeft; }
+  LayoutUnit GenericPosition(bool position_matches,
+                             LayoutUnit position,
+                             LayoutUnit container_size,
+                             LayoutUnit length,
+                             LayoutUnit margin_start,
+                             LayoutUnit margin_end) const {
+    DCHECK_GE(container_size, LayoutUnit());
+    DCHECK_GE(length, LayoutUnit());
+    if (position_matches)
+      return position;
+    else
+      return container_size - position - length - margin_start - margin_end;
+  }
+};
+
+}  // namespace blink
+
+#endif  // NGStaticPosition_h
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_absolute_utils.cc b/third_party/WebKit/Source/core/layout/ng/ng_absolute_utils.cc
index 56ce36f..5347de18 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_absolute_utils.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_absolute_utils.cc
@@ -28,7 +28,7 @@
 LayoutUnit ResolveWidth(const Length& width,
                         const NGConstraintSpace& space,
                         const ComputedStyle& style,
-                        const Optional<MinAndMaxContentSizes>& child_minmax,
+                        const Optional<MinMaxContentSize>& child_minmax,
                         LengthResolveType resolve_type) {
   if (space.WritingMode() == kHorizontalTopBottom)
     return ResolveInlineLength(space, style, child_minmax, width, resolve_type);
@@ -41,7 +41,7 @@
 LayoutUnit ResolveHeight(const Length& height,
                          const NGConstraintSpace& space,
                          const ComputedStyle& style,
-                         const Optional<MinAndMaxContentSizes>& child_minmax,
+                         const Optional<MinMaxContentSize>& child_minmax,
                          LengthResolveType resolve_type) {
   if (space.WritingMode() != kHorizontalTopBottom)
     return ResolveInlineLength(space, style, child_minmax, height,
@@ -54,13 +54,12 @@
 
 // Implement absolute horizontal size resolution algorithm.
 // https://www.w3.org/TR/css-position-3/#abs-non-replaced-width
-void ComputeAbsoluteHorizontal(
-    const NGConstraintSpace& space,
-    const ComputedStyle& style,
-    const Optional<LayoutUnit>& incoming_width,
-    const NGStaticPosition& static_position,
-    const Optional<MinAndMaxContentSizes>& child_minmax,
-    NGAbsolutePhysicalPosition* position) {
+void ComputeAbsoluteHorizontal(const NGConstraintSpace& space,
+                               const ComputedStyle& style,
+                               const Optional<LayoutUnit>& incoming_width,
+                               const NGStaticPosition& static_position,
+                               const Optional<MinMaxContentSize>& child_minmax,
+                               NGAbsolutePhysicalPosition* position) {
   NGLogicalSize percentage_logical = space.PercentageResolutionSize();
   NGPhysicalSize percentage_physical =
       percentage_logical.ConvertToPhysical(space.WritingMode());
@@ -215,13 +214,12 @@
 
 // Implements absolute vertical size resolution algorithm.
 // https://www.w3.org/TR/css-position-3/#abs-non-replaced-height
-void ComputeAbsoluteVertical(
-    const NGConstraintSpace& space,
-    const ComputedStyle& style,
-    const Optional<LayoutUnit>& incoming_height,
-    const NGStaticPosition& static_position,
-    const Optional<MinAndMaxContentSizes>& child_minmax,
-    NGAbsolutePhysicalPosition* position) {
+void ComputeAbsoluteVertical(const NGConstraintSpace& space,
+                             const ComputedStyle& style,
+                             const Optional<LayoutUnit>& incoming_height,
+                             const NGStaticPosition& static_position,
+                             const Optional<MinMaxContentSize>& child_minmax,
+                             NGAbsolutePhysicalPosition* position) {
   NGLogicalSize percentage_logical = space.PercentageResolutionSize();
   NGPhysicalSize percentage_physical =
       percentage_logical.ConvertToPhysical(space.WritingMode());
@@ -383,7 +381,7 @@
     const NGConstraintSpace& space,
     const ComputedStyle& style,
     const NGStaticPosition& static_position,
-    const Optional<MinAndMaxContentSizes>& child_minmax) {
+    const Optional<MinMaxContentSize>& child_minmax) {
   NGAbsolutePhysicalPosition position;
   if (style.isHorizontalWritingMode()) {
     Optional<LayoutUnit> width;
@@ -415,9 +413,9 @@
   // unknown, or fully computed, there is no minmax.
   // To express this, a 'fixed' minmax is created where
   // min and max are the same.
-  Optional<MinAndMaxContentSizes> child_minmax;
+  Optional<MinMaxContentSize> child_minmax;
   if (child_block_size.has_value()) {
-    child_minmax = MinAndMaxContentSizes{*child_block_size, *child_block_size};
+    child_minmax = MinMaxContentSize{*child_block_size, *child_block_size};
   }
   if (style.isHorizontalWritingMode()) {
     Optional<LayoutUnit> height;
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_absolute_utils.h b/third_party/WebKit/Source/core/layout/ng/ng_absolute_utils.h
index 1513af4..4c9bec4 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_absolute_utils.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_absolute_utils.h
@@ -6,7 +6,10 @@
 #define NGAbsoluteUtils_h
 
 #include "core/CoreExport.h"
-#include "core/layout/ng/ng_units.h"
+#include "core/layout/ng/geometry/ng_box_strut.h"
+#include "core/layout/ng/geometry/ng_physical_size.h"
+#include "core/layout/ng/geometry/ng_static_position.h"
+#include "core/layout/ng/ng_min_max_content_size.h"
 #include "platform/LayoutUnit.h"
 #include "wtf/Optional.h"
 
@@ -27,7 +30,7 @@
 // The size is computed as NGAbsolutePhysicalPosition.
 // It needs to be computed in 4 stages:
 // 1. If AbsoluteNeedsChildInlineSize compute estimated inline_size using
-//    MinAndMaxContentSizes.ShrinkToFit.
+//    MinMaxContentSize.ShrinkToFit.
 // 2. Compute part of PhysicalPosition that depends upon child inline size
 //    with ComputePartialAbsoluteWithChildInlineSize.
 // 3. If AbsoluteNeedsChildBlockSize compute estimated block_size by
@@ -50,7 +53,7 @@
     const NGConstraintSpace& space,
     const ComputedStyle& style,
     const NGStaticPosition&,
-    const Optional<MinAndMaxContentSizes>& child_minmax);
+    const Optional<MinMaxContentSize>& child_minmax);
 
 // Compute rest of NGPhysicalRect that depends on child's block_size.
 CORE_EXPORT void ComputeFullAbsoluteWithChildBlockSize(
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_absolute_utils_test.cc b/third_party/WebKit/Source/core/layout/ng/ng_absolute_utils_test.cc
index acdfb59f8..930b314 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_absolute_utils_test.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_absolute_utils_test.cc
@@ -107,8 +107,8 @@
   LayoutUnit width =
       container_size_.inline_size - left - margin_left - right - margin_right;
 
-  Optional<MinAndMaxContentSizes> estimated_inline;
-  MinAndMaxContentSizes minmax_60{LayoutUnit(60), LayoutUnit(60)};
+  Optional<MinMaxContentSize> estimated_inline;
+  MinMaxContentSize minmax_60{LayoutUnit(60), LayoutUnit(60)};
 
   style_->setBorderLeftWidth(border_left.toInt());
   style_->setBorderRightWidth(border_right.toInt());
@@ -430,7 +430,7 @@
 
   NGStaticPosition static_position{NGStaticPosition::kTopLeft,
                                    {LayoutUnit(), LayoutUnit()}};
-  MinAndMaxContentSizes estimated_inline{LayoutUnit(20), LayoutUnit(20)};
+  MinMaxContentSize estimated_inline{LayoutUnit(20), LayoutUnit(20)};
   NGAbsolutePhysicalPosition p;
 
   // WIDTH TESTS
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc
index 975015069..f3a53a8a 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc
@@ -17,7 +17,6 @@
 #include "core/layout/ng/ng_length_utils.h"
 #include "core/layout/ng/ng_line_builder.h"
 #include "core/layout/ng/ng_out_of_flow_layout_part.h"
-#include "core/layout/ng/ng_units.h"
 #include "core/style/ComputedStyle.h"
 #include "platform/LengthFunctions.h"
 #include "wtf/Optional.h"
@@ -313,9 +312,9 @@
       builder_(NGPhysicalFragment::kFragmentBox, node),
       space_builder_(constraint_space_) {}
 
-Optional<MinAndMaxContentSizes>
-NGBlockLayoutAlgorithm::ComputeMinAndMaxContentSizes() const {
-  MinAndMaxContentSizes sizes;
+Optional<MinMaxContentSize> NGBlockLayoutAlgorithm::ComputeMinMaxContentSize()
+    const {
+  MinMaxContentSize sizes;
 
   // Size-contained elements don't consider their contents for intrinsic sizing.
   if (Style().containsSize())
@@ -324,7 +323,7 @@
   // TODO: handle floats & orthogonal children.
   for (NGLayoutInputNode* node = node_->FirstChild(); node;
        node = node->NextSibling()) {
-    MinAndMaxContentSizes child_sizes;
+    MinMaxContentSize child_sizes;
     if (node->Type() == NGLayoutInputNode::kLegacyInline) {
       // From |NGBlockLayoutAlgorithm| perspective, we can handle |NGInlineNode|
       // almost the same as |NGBlockNode|, because an |NGInlineNode| includes
@@ -332,13 +331,12 @@
       // an anonymous box that contains all line boxes.
       // |NextSibling| returns the next block sibling, or nullptr, skipping all
       // following inline siblings and descendants.
-      child_sizes = toNGInlineNode(node)->ComputeMinAndMaxContentSizes();
+      child_sizes = toNGInlineNode(node)->ComputeMinMaxContentSize();
     } else {
-      Optional<MinAndMaxContentSizes> child_minmax;
+      Optional<MinMaxContentSize> child_minmax;
       NGBlockNode* block_child = toNGBlockNode(node);
-      if (NeedMinAndMaxContentSizesForContentContribution(
-              block_child->Style())) {
-        child_minmax = block_child->ComputeMinAndMaxContentSizes();
+      if (NeedMinMaxContentSizeForContentContribution(block_child->Style())) {
+        child_minmax = block_child->ComputeMinMaxContentSize();
       }
 
       child_sizes = ComputeMinAndMaxContentContribution(block_child->Style(),
@@ -378,9 +376,9 @@
 }
 
 RefPtr<NGLayoutResult> NGBlockLayoutAlgorithm::Layout() {
-  WTF::Optional<MinAndMaxContentSizes> sizes;
-  if (NeedMinAndMaxContentSizes(ConstraintSpace(), Style()))
-    sizes = ComputeMinAndMaxContentSizes();
+  WTF::Optional<MinMaxContentSize> sizes;
+  if (NeedMinMaxContentSize(ConstraintSpace(), Style()))
+    sizes = ComputeMinMaxContentSize();
 
   border_and_padding_ = ComputeBorders(ConstraintSpace(), Style()) +
                         ComputePadding(ConstraintSpace(), Style());
@@ -672,9 +670,9 @@
   DCHECK(child);
   const ComputedStyle& child_style = child->Style();
 
-  WTF::Optional<MinAndMaxContentSizes> sizes;
-  if (NeedMinAndMaxContentSizes(space, child_style))
-    sizes = child->ComputeMinAndMaxContentSizes();
+  WTF::Optional<MinMaxContentSize> sizes;
+  if (NeedMinMaxContentSize(space, child_style))
+    sizes = child->ComputeMinMaxContentSize();
 
   LayoutUnit child_inline_size =
       ComputeInlineSizeForFragment(space, child_style, sizes);
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h
index 505983a..904777d 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h
@@ -6,11 +6,11 @@
 #define NGBlockLayoutAlgorithm_h
 
 #include "core/CoreExport.h"
+#include "core/layout/ng/geometry/ng_margin_strut.h"
 #include "core/layout/ng/ng_block_node.h"
 #include "core/layout/ng/ng_constraint_space_builder.h"
 #include "core/layout/ng/ng_fragment_builder.h"
 #include "core/layout/ng/ng_layout_algorithm.h"
-#include "core/layout/ng/ng_units.h"
 #include "wtf/RefPtr.h"
 
 namespace blink {
@@ -34,7 +34,7 @@
                          NGConstraintSpace* space,
                          NGBlockBreakToken* break_token = nullptr);
 
-  Optional<MinAndMaxContentSizes> ComputeMinAndMaxContentSizes() const override;
+  Optional<MinMaxContentSize> ComputeMinMaxContentSize() const override;
   RefPtr<NGLayoutResult> Layout() override;
 
  private:
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm_test.cc b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm_test.cc
index 38c45720..c9648b95 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm_test.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm_test.cc
@@ -16,7 +16,6 @@
 #include "core/layout/ng/ng_length_utils.h"
 #include "core/layout/ng/ng_physical_box_fragment.h"
 #include "core/layout/ng/ng_physical_fragment.h"
-#include "core/layout/ng/ng_units.h"
 #include "core/style/ComputedStyle.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -93,7 +92,7 @@
         toNGPhysicalBoxFragment(result->PhysicalFragment().get()), space);
   }
 
-  MinAndMaxContentSizes RunComputeMinAndMax(NGBlockNode* node) {
+  MinMaxContentSize RunComputeMinAndMax(NGBlockNode* node) {
     // The constraint space is not used for min/max computation, but we need
     // it to create the algorithm.
     RefPtr<NGConstraintSpace> space =
@@ -101,8 +100,8 @@
                                  NGLogicalSize(LayoutUnit(), LayoutUnit()));
 
     NGBlockLayoutAlgorithm algorithm(node, space.get());
-    EXPECT_TRUE(algorithm.ComputeMinAndMaxContentSizes().has_value());
-    return *algorithm.ComputeMinAndMaxContentSizes();
+    EXPECT_TRUE(algorithm.ComputeMinMaxContentSize().has_value());
+    return *algorithm.ComputeMinMaxContentSize();
   }
 
   RefPtr<ComputedStyle> style_;
@@ -1260,7 +1259,7 @@
 
   auto* container = new NGBlockNode(getLayoutObjectByElementId("container"));
 
-  MinAndMaxContentSizes sizes = RunComputeMinAndMax(container);
+  MinMaxContentSize sizes = RunComputeMinAndMax(container);
   EXPECT_EQ(kSecondChildWidth, sizes.min_content);
   EXPECT_EQ(kSecondChildWidth, sizes.max_content);
 }
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc b/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc
index 5276fff8..b39ecf3 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc
@@ -17,6 +17,7 @@
 #include "core/layout/ng/ng_inline_node.h"
 #include "core/layout/ng/ng_layout_result.h"
 #include "core/layout/ng/ng_length_utils.h"
+#include "core/layout/ng/ng_min_max_content_size.h"
 #include "core/layout/ng/ng_writing_mode.h"
 #include "core/paint/PaintLayer.h"
 #include "platform/RuntimeEnabledFeatures.h"
@@ -97,8 +98,8 @@
   return layout_result;
 }
 
-MinAndMaxContentSizes NGBlockNode::ComputeMinAndMaxContentSizes() {
-  MinAndMaxContentSizes sizes;
+MinMaxContentSize NGBlockNode::ComputeMinMaxContentSize() {
+  MinMaxContentSize sizes;
   if (!CanUseNewLayout()) {
     DCHECK(layout_box_);
     // TODO(layout-ng): This could be somewhat optimized by directly calling
@@ -124,8 +125,8 @@
 
   // TODO(cbiesinger): For orthogonal children, we need to always synthesize.
   NGBlockLayoutAlgorithm minmax_algorithm(this, constraint_space.get());
-  Optional<MinAndMaxContentSizes> maybe_sizes =
-      minmax_algorithm.ComputeMinAndMaxContentSizes();
+  Optional<MinMaxContentSize> maybe_sizes =
+      minmax_algorithm.ComputeMinMaxContentSize();
   if (maybe_sizes.has_value())
     return *maybe_sizes;
 
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_node.h b/third_party/WebKit/Source/core/layout/ng/ng_block_node.h
index fe6c053..2c43ffe8 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_block_node.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_block_node.h
@@ -20,7 +20,7 @@
 class NGConstraintSpace;
 class NGLayoutResult;
 struct NGLogicalOffset;
-struct MinAndMaxContentSizes;
+struct MinMaxContentSize;
 
 // Represents a node to be laid out.
 class CORE_EXPORT NGBlockNode final : public NGLayoutInputNode {
@@ -37,12 +37,12 @@
   LayoutObject* GetLayoutObject() override;
 
   // Computes the value of min-content and max-content for this box.
-  // If the underlying layout algorithm's ComputeMinAndMaxContentSizes returns
+  // If the underlying layout algorithm's ComputeMinMaxContentSize returns
   // no value, this function will synthesize these sizes using Layout with
   // special constraint spaces -- infinite available size for max content, zero
   // available size for min content, and percentage resolution size zero for
   // both.
-  MinAndMaxContentSizes ComputeMinAndMaxContentSizes();
+  MinMaxContentSize ComputeMinMaxContentSize();
 
   const ComputedStyle& Style() const;
 
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_node_test.cc b/third_party/WebKit/Source/core/layout/ng/ng_block_node_test.cc
index c7a12ff2..7a38c9e5 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_block_node_test.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_block_node_test.cc
@@ -5,6 +5,9 @@
 #include "core/layout/ng/ng_block_node.h"
 
 #include "core/layout/LayoutTestHelper.h"
+#include "core/layout/ng/ng_box_fragment.h"
+#include "core/layout/ng/ng_min_max_content_size.h"
+#include "core/style/ComputedStyle.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace blink {
@@ -25,7 +28,7 @@
   const int kWidth = 30;
 
   NGBlockNode* box = new NGBlockNode(getLayoutObjectByElementId("box"));
-  MinAndMaxContentSizes sizes = box->ComputeMinAndMaxContentSizes();
+  MinMaxContentSize sizes = box->ComputeMinMaxContentSize();
   EXPECT_EQ(LayoutUnit(kWidth), sizes.min_content);
   EXPECT_EQ(LayoutUnit(kWidth), sizes.max_content);
 }
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_box_fragment.h b/third_party/WebKit/Source/core/layout/ng/ng_box_fragment.h
index ceb5c06..484b3046 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_box_fragment.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_box_fragment.h
@@ -8,7 +8,6 @@
 #include "core/CoreExport.h"
 #include "core/layout/ng/ng_fragment.h"
 #include "core/layout/ng/ng_physical_box_fragment.h"
-#include "core/layout/ng/ng_units.h"
 #include "core/layout/ng/ng_writing_mode.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.h b/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.h
index de696c93..f3db8750 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.h
@@ -6,8 +6,14 @@
 #define NGConstraintSpace_h
 
 #include "core/CoreExport.h"
-#include "core/layout/ng/ng_units.h"
+#include "core/layout/ng/geometry/ng_logical_offset.h"
+#include "core/layout/ng/geometry/ng_logical_size.h"
+#include "core/layout/ng/geometry/ng_margin_strut.h"
+#include "core/layout/ng/geometry/ng_physical_size.h"
+#include "core/layout/ng/ng_exclusion.h"
 #include "core/layout/ng/ng_writing_mode.h"
+#include "platform/heap/Handle.h"
+#include "platform/text/TextDirection.h"
 #include "wtf/Optional.h"
 #include "wtf/RefCounted.h"
 #include "wtf/text/WTFString.h"
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_constraint_space_builder.h b/third_party/WebKit/Source/core/layout/ng/ng_constraint_space_builder.h
index 40d95ad..d1b6458 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_constraint_space_builder.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_constraint_space_builder.h
@@ -6,7 +6,6 @@
 #define NGConstraintSpaceBuilder_h
 
 #include "core/layout/ng/ng_constraint_space.h"
-#include "core/layout/ng/ng_units.h"
 #include "wtf/Allocator.h"
 #include "wtf/Optional.h"
 
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_constraint_space_builder_test.cc b/third_party/WebKit/Source/core/layout/ng/ng_constraint_space_builder_test.cc
index 3a628fc..8fb109d 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_constraint_space_builder_test.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_constraint_space_builder_test.cc
@@ -3,7 +3,6 @@
 // found in the LICENSE file.
 
 #include "core/layout/ng/ng_constraint_space_builder.h"
-#include "core/layout/ng/ng_units.h"
 
 #include "core/layout/LayoutTestHelper.h"
 
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_exclusion.cc b/third_party/WebKit/Source/core/layout/ng/ng_exclusion.cc
new file mode 100644
index 0000000..e5f711b
--- /dev/null
+++ b/third_party/WebKit/Source/core/layout/ng/ng_exclusion.cc
@@ -0,0 +1,50 @@
+// 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/layout/ng/ng_exclusion.h"
+
+#include "wtf/text/WTFString.h"
+
+namespace blink {
+
+bool NGExclusion::operator==(const NGExclusion& other) const {
+  return std::tie(other.rect, other.type) == std::tie(rect, type);
+}
+
+String NGExclusion::ToString() const {
+  return String::format("Rect: %s Type: %d", rect.ToString().ascii().data(),
+                        type);
+}
+
+std::ostream& operator<<(std::ostream& stream, const NGExclusion& value) {
+  return stream << value.ToString();
+}
+
+NGExclusions::NGExclusions()
+    : last_left_float(nullptr), last_right_float(nullptr) {}
+
+NGExclusions::NGExclusions(const NGExclusions& other) {
+  for (const auto& exclusion : other.storage)
+    Add(*exclusion);
+}
+
+void NGExclusions::Add(const NGExclusion& exclusion) {
+  storage.push_back(WTF::makeUnique<NGExclusion>(exclusion));
+  if (exclusion.type == NGExclusion::kFloatLeft) {
+    last_left_float = storage.rbegin()->get();
+  } else if (exclusion.type == NGExclusion::kFloatRight) {
+    last_right_float = storage.rbegin()->get();
+  }
+}
+
+inline NGExclusions& NGExclusions::operator=(const NGExclusions& other) {
+  storage.clear();
+  last_left_float = nullptr;
+  last_right_float = nullptr;
+  for (const auto& exclusion : other.storage)
+    Add(*exclusion);
+  return *this;
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_exclusion.h b/third_party/WebKit/Source/core/layout/ng/ng_exclusion.h
new file mode 100644
index 0000000..b8b86edd
--- /dev/null
+++ b/third_party/WebKit/Source/core/layout/ng/ng_exclusion.h
@@ -0,0 +1,57 @@
+// 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 NGExclusion_h
+#define NGExclusion_h
+
+#include "core/CoreExport.h"
+#include "core/layout/ng/geometry/ng_logical_rect.h"
+#include "wtf/Vector.h"
+
+namespace blink {
+
+// Struct that represents NG exclusion.
+struct CORE_EXPORT NGExclusion {
+  // Type of NG exclusion.
+  enum Type {
+    // Undefined exclusion type.
+    // At this moment it's also used to represent CSS3 exclusion.
+    kExclusionTypeUndefined = 0,
+    // Exclusion that is created by LEFT float.
+    kFloatLeft = 1,
+    // Exclusion that is created by RIGHT float.
+    kFloatRight = 2
+  };
+
+  // Rectangle in logical coordinates the represents this exclusion.
+  NGLogicalRect rect;
+
+  // Type of this exclusion.
+  Type type;
+
+  bool operator==(const NGExclusion& other) const;
+  String ToString() const;
+};
+
+CORE_EXPORT std::ostream& operator<<(std::ostream&, const NGExclusion&);
+
+struct CORE_EXPORT NGExclusions {
+  NGExclusions();
+  NGExclusions(const NGExclusions& other);
+
+  Vector<std::unique_ptr<const NGExclusion>> storage;
+
+  // Last left/right float exclusions are used to enforce the top edge alignment
+  // rule for floats and for the support of CSS "clear" property.
+  const NGExclusion* last_left_float;   // Owned by storage.
+  const NGExclusion* last_right_float;  // Owned by storage.
+
+  NGExclusions& operator=(const NGExclusions& other);
+
+  void Add(const NGExclusion& exclusion);
+};
+
+}  // namespace blink
+
+#endif  // NGExclusion_h
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_floating_object.h b/third_party/WebKit/Source/core/layout/ng/ng_floating_object.h
index 26a21fa..f841775 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_floating_object.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_floating_object.h
@@ -5,9 +5,10 @@
 #ifndef NGFloatingObject_h
 #define NGFloatingObject_h
 
+#include "core/layout/ng/geometry/ng_box_strut.h"
 #include "core/layout/ng/ng_block_node.h"
 #include "core/layout/ng/ng_constraint_space.h"
-#include "core/layout/ng/ng_units.h"
+#include "core/layout/ng/ng_exclusion.h"
 #include "core/style/ComputedStyle.h"
 #include "core/style/ComputedStyleConstants.h"
 #include "platform/heap/Handle.h"
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.h b/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.h
index dc8a59fb..fd11878d 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.h
@@ -9,7 +9,6 @@
 #include "core/layout/ng/ng_constraint_space.h"
 #include "core/layout/ng/ng_floating_object.h"
 #include "core/layout/ng/ng_physical_fragment.h"
-#include "core/layout/ng/ng_units.h"
 #include "wtf/Allocator.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_inline_node.cc b/third_party/WebKit/Source/core/layout/ng/ng_inline_node.cc
index b948222..a4ba2f3 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_inline_node.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_inline_node.cc
@@ -262,7 +262,7 @@
   NGTextLayoutAlgorithm(this, constraint_space).LayoutInline(line_builder);
 }
 
-MinAndMaxContentSizes NGInlineNode::ComputeMinAndMaxContentSizes() {
+MinMaxContentSize NGInlineNode::ComputeMinMaxContentSize() {
   // Compute the max of inline sizes of all line boxes with 0 available inline
   // size. This gives the min-content, the width where lines wrap at every break
   // opportunity.
@@ -275,7 +275,7 @@
           .ToConstraintSpace(writing_mode);
   NGLineBuilder line_builder(this, constraint_space.get());
   LayoutInline(constraint_space.get(), &line_builder);
-  MinAndMaxContentSizes sizes;
+  MinMaxContentSize sizes;
   sizes.min_content = line_builder.MaxInlineSize();
 
   // max-content is the width without any line wrapping.
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_inline_node.h b/third_party/WebKit/Source/core/layout/ng/ng_inline_node.h
index 20f8b40e..1aecc23 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_inline_node.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_inline_node.h
@@ -22,7 +22,7 @@
 class LayoutBlockFlow;
 class LayoutObject;
 class LayoutUnit;
-struct MinAndMaxContentSizes;
+struct MinMaxContentSize;
 class NGConstraintSpace;
 class NGLayoutInlineItem;
 class NGLayoutInlineItemRange;
@@ -47,7 +47,7 @@
   // Computes the value of min-content and max-content for this anonymous block
   // box. min-content is the inline size when lines wrap at every break
   // opportunity, and max-content is when lines do not wrap at all.
-  MinAndMaxContentSizes ComputeMinAndMaxContentSizes();
+  MinMaxContentSize ComputeMinMaxContentSize();
 
   // Instruct to re-compute |PrepareLayout| on the next layout.
   void InvalidatePrepareLayout();
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_inline_node_test.cc b/third_party/WebKit/Source/core/layout/ng/ng_inline_node_test.cc
index 482e823..7976c0b 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_inline_node_test.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_inline_node_test.cc
@@ -216,25 +216,25 @@
   TEST_TEXT_FRAGMENT(fragments[4], node, 8u, 22u, 28u, TextDirection::kLtr);
 }
 
-TEST_F(NGInlineNodeTest, MinAndMaxContentSizes) {
+TEST_F(NGInlineNodeTest, MinMaxContentSize) {
   setAhemToStyle();
   NGInlineNodeForTest* node = new NGInlineNodeForTest(style_.get());
   node->Append("AB CDE", style_.get());
   node->ShapeText();
-  MinAndMaxContentSizes sizes = node->ComputeMinAndMaxContentSizes();
+  MinMaxContentSize sizes = node->ComputeMinMaxContentSize();
   // TODO(kojii): min_content should be 20, but is 30 until NGLineBuilder
   // implements trailing spaces correctly.
   EXPECT_EQ(30, sizes.min_content);
   EXPECT_EQ(60, sizes.max_content);
 }
 
-TEST_F(NGInlineNodeTest, MinAndMaxContentSizesElementBoundary) {
+TEST_F(NGInlineNodeTest, MinMaxContentSizeElementBoundary) {
   setAhemToStyle();
   NGInlineNodeForTest* node = new NGInlineNodeForTest(style_.get());
   node->Append("A B", style_.get());
   node->Append("C D", style_.get());
   node->ShapeText();
-  MinAndMaxContentSizes sizes = node->ComputeMinAndMaxContentSizes();
+  MinMaxContentSize sizes = node->ComputeMinMaxContentSize();
   // |min_content| should be the width of "BC" because there is an element
   // boundary between "B" and "C" but no break opportunities.
   // TODO(kojii): min_content should be 20, but is 30 until NGLineBuilder
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_layout_algorithm.h b/third_party/WebKit/Source/core/layout/ng/ng_layout_algorithm.h
index bc2250c..a04f837 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_layout_algorithm.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_layout_algorithm.h
@@ -6,14 +6,14 @@
 #define NGLayoutAlgorithm_h
 
 #include "core/CoreExport.h"
-#include "core/layout/ng/ng_units.h"
+#include "core/layout/ng/ng_min_max_content_size.h"
 #include "wtf/Allocator.h"
 #include "wtf/Noncopyable.h"
 #include "wtf/Optional.h"
 
 namespace blink {
 
-struct MinAndMaxContentSizes;
+struct MinMaxContentSize;
 class NGLayoutResult;
 
 // Base class for all LayoutNG algorithms.
@@ -34,7 +34,7 @@
   // account. If the return value is empty, the caller is expected to synthesize
   // this value from the overflow rect returned from Layout called with an
   // available width of 0 and LayoutUnit::max(), respectively.
-  virtual Optional<MinAndMaxContentSizes> ComputeMinAndMaxContentSizes() const {
+  virtual Optional<MinMaxContentSize> ComputeMinMaxContentSize() const {
     return WTF::nullopt;
   }
 };
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_layout_opportunity_iterator.cc b/third_party/WebKit/Source/core/layout/ng/ng_layout_opportunity_iterator.cc
index 76961a9..b04dc46 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_layout_opportunity_iterator.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_layout_opportunity_iterator.cc
@@ -4,7 +4,7 @@
 
 #include "core/layout/ng/ng_layout_opportunity_iterator.h"
 
-#include "core/layout/ng/ng_units.h"
+#include "core/layout/ng/ng_exclusion.h"
 #include "wtf/NonCopyingSort.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_layout_opportunity_iterator.h b/third_party/WebKit/Source/core/layout/ng/ng_layout_opportunity_iterator.h
index ea3d3fc..e9780f34 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_layout_opportunity_iterator.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_layout_opportunity_iterator.h
@@ -8,7 +8,6 @@
 #include "core/CoreExport.h"
 #include "core/layout/ng/ng_constraint_space.h"
 #include "core/layout/ng/ng_layout_opportunity_tree_node.h"
-#include "core/layout/ng/ng_units.h"
 #include "platform/heap/Handle.h"
 #include "wtf/Optional.h"
 #include "wtf/Vector.h"
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_layout_opportunity_tree_node.h b/third_party/WebKit/Source/core/layout/ng/ng_layout_opportunity_tree_node.h
index 6c445d1..6e2c913 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_layout_opportunity_tree_node.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_layout_opportunity_tree_node.h
@@ -5,12 +5,13 @@
 #ifndef NGLayoutOpportunityTreeNode_h
 #define NGLayoutOpportunityTreeNode_h
 
-#include "core/layout/ng/ng_units.h"
+#include "core/layout/ng/geometry/ng_edge.h"
+#include "core/layout/ng/geometry/ng_logical_rect.h"
+#include "core/layout/ng/ng_exclusion.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
 
-
 // 3 node R-Tree that represents available space(left, bottom, right) or
 // layout opportunity after the parent spatial rectangle is split by the
 // exclusion rectangle.
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_layout_result.h b/third_party/WebKit/Source/core/layout/ng/ng_layout_result.h
index 49d206a..3ec77699 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_layout_result.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_layout_result.h
@@ -6,8 +6,8 @@
 #define NGLayoutResult_h
 
 #include "core/CoreExport.h"
+#include "core/layout/ng/geometry/ng_static_position.h"
 #include "core/layout/ng/ng_physical_fragment.h"
-#include "core/layout/ng/ng_units.h"
 #include "platform/LayoutUnit.h"
 #include "platform/heap/Handle.h"
 #include "wtf/Vector.h"
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_length_utils.cc b/third_party/WebKit/Source/core/layout/ng/ng_length_utils.cc
index 2f5d30c..f18089c 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_length_utils.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_length_utils.cc
@@ -17,8 +17,8 @@
 // - replaced calculations
 // - Take scrollbars into account
 
-bool NeedMinAndMaxContentSizes(const NGConstraintSpace& constraint_space,
-                               const ComputedStyle& style) {
+bool NeedMinMaxContentSize(const NGConstraintSpace& constraint_space,
+                           const ComputedStyle& style) {
   // This check is technically too broad (fill-available does not need intrinsic
   // size computation) but that's a rare case and only affects performance, not
   // correctness.
@@ -28,8 +28,7 @@
          style.logicalMaxWidth().isIntrinsic();
 }
 
-bool NeedMinAndMaxContentSizesForContentContribution(
-    const ComputedStyle& style) {
+bool NeedMinMaxContentSizeForContentContribution(const ComputedStyle& style) {
   return style.logicalWidth().isIntrinsicOrAuto() ||
          style.logicalMinWidth().isIntrinsic() ||
          style.logicalMaxWidth().isIntrinsic();
@@ -38,7 +37,7 @@
 LayoutUnit ResolveInlineLength(
     const NGConstraintSpace& constraint_space,
     const ComputedStyle& style,
-    const WTF::Optional<MinAndMaxContentSizes>& min_and_max,
+    const WTF::Optional<MinMaxContentSize>& min_and_max,
     const Length& length,
     LengthResolveType type) {
   DCHECK(!length.isMaxSizeNone());
@@ -183,9 +182,9 @@
   }
 }
 
-MinAndMaxContentSizes ComputeMinAndMaxContentContribution(
+MinMaxContentSize ComputeMinAndMaxContentContribution(
     const ComputedStyle& style,
-    const WTF::Optional<MinAndMaxContentSizes>& min_and_max) {
+    const WTF::Optional<MinMaxContentSize>& min_and_max) {
   // Synthesize a zero-sized constraint space for passing to
   // ResolveInlineLength.
   NGWritingMode writing_mode = FromPlatformWritingMode(style.getWritingMode());
@@ -194,7 +193,7 @@
       NGPhysicalSize{LayoutUnit(), LayoutUnit()});
   RefPtr<NGConstraintSpace> space = builder.ToConstraintSpace(writing_mode);
 
-  MinAndMaxContentSizes computed_sizes;
+  MinMaxContentSize computed_sizes;
   Length inline_size = style.logicalWidth();
   if (inline_size.isAuto()) {
     CHECK(min_and_max.has_value());
@@ -234,7 +233,7 @@
 LayoutUnit ComputeInlineSizeForFragment(
     const NGConstraintSpace& space,
     const ComputedStyle& style,
-    const WTF::Optional<MinAndMaxContentSizes>& min_and_max) {
+    const WTF::Optional<MinMaxContentSize>& min_and_max) {
   if (space.IsFixedSizeInline())
     return space.AvailableSize().inline_size;
 
@@ -335,7 +334,7 @@
                           const NGWritingMode writing_mode,
                           const TextDirection direction) {
   // We don't need these for margin computations
-  MinAndMaxContentSizes empty_sizes;
+  MinMaxContentSize empty_sizes;
   // Margins always get computed relative to the inline size:
   // https://www.w3.org/TR/CSS2/box.html#value-def-margin-width
   NGPhysicalBoxStrut physical_dim;
@@ -377,7 +376,7 @@
     return NGBoxStrut();
 
   // We don't need these for padding computations
-  MinAndMaxContentSizes empty_sizes;
+  MinMaxContentSize empty_sizes;
   // Padding always gets computed relative to the inline size:
   // https://www.w3.org/TR/CSS2/box.html#value-def-padding-width
   NGBoxStrut padding;
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_length_utils.h b/third_party/WebKit/Source/core/layout/ng/ng_length_utils.h
index 42d59ac..a4e731d9 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_length_utils.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_length_utils.h
@@ -6,7 +6,8 @@
 #define NGLengthUtils_h
 
 #include "core/CoreExport.h"
-#include "core/layout/ng/ng_units.h"
+#include "core/layout/ng/geometry/ng_box_strut.h"
+#include "core/layout/ng/ng_min_max_content_size.h"
 #include "core/layout/ng/ng_writing_mode.h"
 #include "platform/text/TextDirection.h"
 #include "wtf/Optional.h"
@@ -15,7 +16,7 @@
 class ComputedStyle;
 class LayoutUnit;
 class Length;
-struct MinAndMaxContentSizes;
+struct MinMaxContentSize;
 class NGConstraintSpace;
 struct NGBoxStrut;
 
@@ -29,13 +30,13 @@
 // Whether the caller needs to compute min-content and max-content sizes to
 // pass them to ResolveInlineLength / ComputeInlineSizeForFragment.
 // If this function returns false, it is safe to pass an empty
-// MinAndMaxContentSizes struct to those functions.
-CORE_EXPORT bool NeedMinAndMaxContentSizes(const NGConstraintSpace&,
-                                           const ComputedStyle&);
+// MinMaxContentSize struct to those functions.
+CORE_EXPORT bool NeedMinMaxContentSize(const NGConstraintSpace&,
+                                       const ComputedStyle&);
 
-// Like NeedMinAndMaxContentSizes, but for use when calling
+// Like NeedMinMaxContentSize, but for use when calling
 // ComputeMinAndMaxContentContribution.
-CORE_EXPORT bool NeedMinAndMaxContentSizesForContentContribution(
+CORE_EXPORT bool NeedMinMaxContentSizeForContentContribution(
     const ComputedStyle&);
 
 // Convert an inline-axis length to a layout unit using the given constraint
@@ -43,7 +44,7 @@
 CORE_EXPORT LayoutUnit
 ResolveInlineLength(const NGConstraintSpace&,
                     const ComputedStyle&,
-                    const WTF::Optional<MinAndMaxContentSizes>&,
+                    const WTF::Optional<MinMaxContentSize>&,
                     const Length&,
                     LengthResolveType);
 
@@ -62,9 +63,9 @@
 // to zero) and that an auto inline size resolves to the respective min/max
 // content size.
 // Also, the min/max contribution does include the inline margins as well.
-CORE_EXPORT MinAndMaxContentSizes ComputeMinAndMaxContentContribution(
-    const ComputedStyle&,
-    const WTF::Optional<MinAndMaxContentSizes>&);
+CORE_EXPORT MinMaxContentSize
+ComputeMinAndMaxContentContribution(const ComputedStyle&,
+                                    const WTF::Optional<MinMaxContentSize>&);
 
 // Resolves the given length to a layout unit, constraining it by the min
 // logical width and max logical width properties from the ComputedStyle
@@ -72,7 +73,7 @@
 CORE_EXPORT LayoutUnit
 ComputeInlineSizeForFragment(const NGConstraintSpace&,
                              const ComputedStyle&,
-                             const WTF::Optional<MinAndMaxContentSizes>&);
+                             const WTF::Optional<MinMaxContentSize>&);
 
 // Resolves the given length to a layout unit, constraining it by the min
 // logical height and max logical height properties from the ComputedStyle
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_length_utils_test.cc b/third_party/WebKit/Source/core/layout/ng/ng_length_utils_test.cc
index e8b40a24..097b988c 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_length_utils_test.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_length_utils_test.cc
@@ -9,7 +9,6 @@
 #include "core/layout/ng/ng_constraint_space_builder.h"
 #include "core/layout/ng/ng_fragment_builder.h"
 #include "core/layout/ng/ng_physical_box_fragment.h"
-#include "core/layout/ng/ng_units.h"
 #include "core/style/ComputedStyle.h"
 #include "platform/CalculationValue.h"
 #include "platform/LayoutUnit.h"
@@ -42,7 +41,7 @@
   LayoutUnit ResolveInlineLength(
       const Length& length,
       LengthResolveType type = LengthResolveType::kContentSize,
-      const WTF::Optional<MinAndMaxContentSizes>& sizes = WTF::nullopt) {
+      const WTF::Optional<MinMaxContentSize>& sizes = WTF::nullopt) {
     RefPtr<NGConstraintSpace> constraintSpace =
         ConstructConstraintSpace(200, 300);
     return ::blink::ResolveInlineLength(*constraintSpace, *style_, sizes,
@@ -62,7 +61,7 @@
   LayoutUnit ComputeInlineSizeForFragment(
       RefPtr<const NGConstraintSpace> constraintSpace =
           ConstructConstraintSpace(200, 300),
-      const MinAndMaxContentSizes& sizes = MinAndMaxContentSizes()) {
+      const MinMaxContentSize& sizes = MinMaxContentSize()) {
     return ::blink::ComputeInlineSizeForFragment(*constraintSpace, *style_,
                                                  sizes);
   }
@@ -90,7 +89,7 @@
             ResolveInlineLength(Length(Auto), LengthResolveType::kMaxSize));
   EXPECT_EQ(LayoutUnit(200), ResolveInlineLength(Length(FillAvailable),
                                                  LengthResolveType::kMaxSize));
-  MinAndMaxContentSizes sizes;
+  MinMaxContentSize sizes;
   sizes.min_content = LayoutUnit(30);
   sizes.max_content = LayoutUnit(40);
   EXPECT_EQ(LayoutUnit(30),
@@ -126,18 +125,18 @@
 }
 
 TEST_F(NGLengthUtilsTest, testComputeContentContribution) {
-  MinAndMaxContentSizes sizes;
+  MinMaxContentSize sizes;
   sizes.min_content = LayoutUnit(30);
   sizes.max_content = LayoutUnit(40);
 
-  MinAndMaxContentSizes expected{LayoutUnit(), LayoutUnit()};
+  MinMaxContentSize expected{LayoutUnit(), LayoutUnit()};
   style_->setLogicalWidth(Length(30, Percent));
   EXPECT_EQ(expected, ComputeMinAndMaxContentContribution(*style_, sizes));
 
   style_->setLogicalWidth(Length(FillAvailable));
   EXPECT_EQ(expected, ComputeMinAndMaxContentContribution(*style_, sizes));
 
-  expected = MinAndMaxContentSizes{LayoutUnit(150), LayoutUnit(150)};
+  expected = MinMaxContentSize{LayoutUnit(150), LayoutUnit(150)};
   style_->setLogicalWidth(Length(150, Fixed));
   EXPECT_EQ(expected, ComputeMinAndMaxContentContribution(*style_, sizes));
 
@@ -145,39 +144,39 @@
   style_->setLogicalWidth(Length(Auto));
   EXPECT_EQ(expected, ComputeMinAndMaxContentContribution(*style_, sizes));
 
-  expected = MinAndMaxContentSizes{LayoutUnit(430), LayoutUnit(440)};
+  expected = MinMaxContentSize{LayoutUnit(430), LayoutUnit(440)};
   style_->setPaddingLeft(Length(400, Fixed));
   EXPECT_EQ(expected, ComputeMinAndMaxContentContribution(*style_, sizes));
 
-  expected = MinAndMaxContentSizes{LayoutUnit(100), LayoutUnit(100)};
+  expected = MinMaxContentSize{LayoutUnit(100), LayoutUnit(100)};
   style_->setPaddingLeft(Length(0, Fixed));
   style_->setLogicalWidth(Length(CalculationValue::create(
       PixelsAndPercent(100, -10), ValueRangeNonNegative)));
   EXPECT_EQ(expected, ComputeMinAndMaxContentContribution(*style_, sizes));
 
-  expected = MinAndMaxContentSizes{LayoutUnit(30), LayoutUnit(35)};
+  expected = MinMaxContentSize{LayoutUnit(30), LayoutUnit(35)};
   style_->setLogicalWidth(Length(Auto));
   style_->setMaxWidth(Length(35, Fixed));
   EXPECT_EQ(expected, ComputeMinAndMaxContentContribution(*style_, sizes));
 
-  expected = MinAndMaxContentSizes{LayoutUnit(80), LayoutUnit(80)};
+  expected = MinMaxContentSize{LayoutUnit(80), LayoutUnit(80)};
   style_->setLogicalWidth(Length(50, Fixed));
   style_->setMinWidth(Length(80, Fixed));
   EXPECT_EQ(expected, ComputeMinAndMaxContentContribution(*style_, sizes));
 
-  expected = MinAndMaxContentSizes{LayoutUnit(150), LayoutUnit(150)};
+  expected = MinMaxContentSize{LayoutUnit(150), LayoutUnit(150)};
   style_ = ComputedStyle::create();
   style_->setLogicalWidth(Length(100, Fixed));
   style_->setPaddingLeft(Length(50, Fixed));
   EXPECT_EQ(expected, ComputeMinAndMaxContentContribution(*style_, sizes));
 
-  expected = MinAndMaxContentSizes{LayoutUnit(100), LayoutUnit(100)};
+  expected = MinMaxContentSize{LayoutUnit(100), LayoutUnit(100)};
   style_->setBoxSizing(EBoxSizing::kBorderBox);
   EXPECT_EQ(expected, ComputeMinAndMaxContentContribution(*style_, sizes));
 
   // Content size should never be below zero, even with box-sizing: border-box
   // and a large padding...
-  expected = MinAndMaxContentSizes{LayoutUnit(400), LayoutUnit(400)};
+  expected = MinMaxContentSize{LayoutUnit(400), LayoutUnit(400)};
   style_->setPaddingLeft(Length(400, Fixed));
   EXPECT_EQ(expected, ComputeMinAndMaxContentContribution(*style_, sizes));
 
@@ -189,15 +188,15 @@
   style_->setMaxWidth(Length(MaxContent));
   // Due to padding and box-sizing, width computes to 400px and max-width to
   // 440px, so the result is 400.
-  expected = MinAndMaxContentSizes{LayoutUnit(400), LayoutUnit(400)};
+  expected = MinMaxContentSize{LayoutUnit(400), LayoutUnit(400)};
   EXPECT_EQ(expected, ComputeMinAndMaxContentContribution(*style_, sizes));
-  expected = MinAndMaxContentSizes{LayoutUnit(40), LayoutUnit(40)};
+  expected = MinMaxContentSize{LayoutUnit(40), LayoutUnit(40)};
   style_->setPaddingLeft(Length(0, Fixed));
   EXPECT_EQ(expected, ComputeMinAndMaxContentContribution(*style_, sizes));
 }
 
 TEST_F(NGLengthUtilsTest, testComputeInlineSizeForFragment) {
-  MinAndMaxContentSizes sizes;
+  MinMaxContentSize sizes;
   sizes.min_content = LayoutUnit(30);
   sizes.max_content = LayoutUnit(40);
 
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_line_builder.cc b/third_party/WebKit/Source/core/layout/ng/ng_line_builder.cc
index 3d37cbc..40fcb42 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_line_builder.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_line_builder.cc
@@ -14,7 +14,6 @@
 #include "core/layout/ng/ng_inline_node.h"
 #include "core/layout/ng/ng_length_utils.h"
 #include "core/layout/ng/ng_text_fragment.h"
-#include "core/layout/ng/ng_units.h"
 #include "core/style/ComputedStyle.h"
 #include "platform/text/BidiRunList.h"
 
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_line_builder.h b/third_party/WebKit/Source/core/layout/ng/ng_line_builder.h
index 2727f04..fb5651b 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_line_builder.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_line_builder.h
@@ -6,8 +6,8 @@
 #define NGLineBuilder_h
 
 #include "core/CoreExport.h"
+#include "core/layout/ng/geometry/ng_logical_offset.h"
 #include "core/layout/ng/ng_physical_fragment.h"
-#include "core/layout/ng/ng_units.h"
 #include "platform/fonts/FontBaseline.h"
 #include "platform/heap/Handle.h"
 #include "wtf/Vector.h"
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_min_max_content_size.cc b/third_party/WebKit/Source/core/layout/ng/ng_min_max_content_size.cc
new file mode 100644
index 0000000..7029da6
--- /dev/null
+++ b/third_party/WebKit/Source/core/layout/ng/ng_min_max_content_size.cc
@@ -0,0 +1,22 @@
+// 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/layout/ng/ng_min_max_content_size.h"
+
+namespace blink {
+
+LayoutUnit MinMaxContentSize::ShrinkToFit(LayoutUnit available_size) const {
+  DCHECK_GE(max_content, min_content);
+  return std::min(max_content, std::max(min_content, available_size));
+}
+
+bool MinMaxContentSize::operator==(const MinMaxContentSize& other) const {
+  return min_content == other.min_content && max_content == other.max_content;
+}
+
+std::ostream& operator<<(std::ostream& stream, const MinMaxContentSize& value) {
+  return stream << "(" << value.min_content << ", " << value.max_content << ")";
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_min_max_content_size.h b/third_party/WebKit/Source/core/layout/ng/ng_min_max_content_size.h
new file mode 100644
index 0000000..2fb0a93
--- /dev/null
+++ b/third_party/WebKit/Source/core/layout/ng/ng_min_max_content_size.h
@@ -0,0 +1,25 @@
+// 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 MinMaxContentSize_h
+#define MinMaxContentSize_h
+
+#include "core/CoreExport.h"
+#include "core/layout/ng/ng_writing_mode.h"
+#include "platform/LayoutUnit.h"
+
+namespace blink {
+
+struct CORE_EXPORT MinMaxContentSize {
+  LayoutUnit min_content;
+  LayoutUnit max_content;
+  LayoutUnit ShrinkToFit(LayoutUnit available_size) const;
+  bool operator==(const MinMaxContentSize& other) const;
+};
+
+CORE_EXPORT std::ostream& operator<<(std::ostream&, const MinMaxContentSize&);
+
+}  // namespace blink
+
+#endif  // MinMaxContentSize_h
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_min_max_content_size_test.cc b/third_party/WebKit/Source/core/layout/ng/ng_min_max_content_size_test.cc
new file mode 100644
index 0000000..04eea50
--- /dev/null
+++ b/third_party/WebKit/Source/core/layout/ng/ng_min_max_content_size_test.cc
@@ -0,0 +1,31 @@
+// 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/layout/ng/ng_min_max_content_size.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace blink {
+
+namespace {
+
+TEST(NGUnitsTest, ShrinkToFit) {
+  MinMaxContentSize sizes;
+
+  sizes.min_content = LayoutUnit(100);
+  sizes.max_content = LayoutUnit(200);
+  EXPECT_EQ(LayoutUnit(200), sizes.ShrinkToFit(LayoutUnit(300)));
+
+  sizes.min_content = LayoutUnit(100);
+  sizes.max_content = LayoutUnit(300);
+  EXPECT_EQ(LayoutUnit(200), sizes.ShrinkToFit(LayoutUnit(200)));
+
+  sizes.min_content = LayoutUnit(200);
+  sizes.max_content = LayoutUnit(300);
+  EXPECT_EQ(LayoutUnit(200), sizes.ShrinkToFit(LayoutUnit(100)));
+}
+
+}  // namespace
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.cc b/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.cc
index 32d792c..5e0d4460f 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.cc
@@ -106,7 +106,7 @@
   static_position.offset -= container_border_physical_offset_;
 
   // The inline and block estimates are in the descendant's writing mode.
-  Optional<MinAndMaxContentSizes> inline_estimate;
+  Optional<MinMaxContentSize> inline_estimate;
   Optional<LayoutUnit> block_estimate;
 
   RefPtr<NGLayoutResult> layout_result = nullptr;
@@ -114,7 +114,7 @@
       FromPlatformWritingMode(descendant.Style().getWritingMode()));
 
   if (AbsoluteNeedsChildInlineSize(descendant.Style())) {
-    inline_estimate = descendant.ComputeMinAndMaxContentSizes();
+    inline_estimate = descendant.ComputeMinMaxContentSize();
   }
 
   NGAbsolutePhysicalPosition node_position =
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.h b/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.h
index 6de47bd..e563e7d 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_out_of_flow_layout_part.h
@@ -10,7 +10,6 @@
 #include "core/layout/ng/ng_absolute_utils.h"
 #include "core/layout/ng/ng_constraint_space.h"
 #include "core/layout/ng/ng_layout_algorithm.h"
-#include "core/layout/ng/ng_units.h"
 #include "platform/heap/Handle.h"
 #include "wtf/Optional.h"
 
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_physical_box_fragment.h b/third_party/WebKit/Source/core/layout/ng/ng_physical_box_fragment.h
index 4b03b69..7d6bfed 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_physical_box_fragment.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_physical_box_fragment.h
@@ -6,8 +6,9 @@
 #define NGPhysicalBoxFragment_h
 
 #include "core/CoreExport.h"
+#include "core/layout/ng/geometry/ng_logical_offset.h"
+#include "core/layout/ng/geometry/ng_margin_strut.h"
 #include "core/layout/ng/ng_physical_fragment.h"
-#include "core/layout/ng/ng_units.h"
 #include "platform/heap/Handle.h"
 #include "wtf/Optional.h"
 
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_physical_fragment.h b/third_party/WebKit/Source/core/layout/ng/ng_physical_fragment.h
index cea8301f..146fa785 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_physical_fragment.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_physical_fragment.h
@@ -6,8 +6,9 @@
 #define NGPhysicalFragment_h
 
 #include "core/CoreExport.h"
+#include "core/layout/ng/geometry/ng_physical_offset.h"
+#include "core/layout/ng/geometry/ng_physical_size.h"
 #include "core/layout/ng/ng_break_token.h"
-#include "core/layout/ng/ng_units.h"
 #include "platform/LayoutUnit.h"
 #include "platform/heap/Handle.h"
 #include "wtf/RefPtr.h"
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_units.cc b/third_party/WebKit/Source/core/layout/ng/ng_units.cc
deleted file mode 100644
index 4eafda9c..0000000
--- a/third_party/WebKit/Source/core/layout/ng/ng_units.cc
+++ /dev/null
@@ -1,161 +0,0 @@
-// 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/layout/ng/ng_units.h"
-
-namespace blink {
-
-LayoutUnit MinAndMaxContentSizes::ShrinkToFit(LayoutUnit available_size) const {
-  DCHECK_GE(max_content, min_content);
-  return std::min(max_content, std::max(min_content, available_size));
-}
-
-bool MinAndMaxContentSizes::operator==(
-    const MinAndMaxContentSizes& other) const {
-  return min_content == other.min_content && max_content == other.max_content;
-}
-
-
-bool NGLogicalRect::IsEmpty() const {
-  // TODO(layout-dev): equality check shouldn't allocate an object each time.
-  return *this == NGLogicalRect();
-}
-
-bool NGLogicalRect::IsContained(const NGLogicalRect& other) const {
-  return !(InlineEndOffset() <= other.InlineStartOffset() ||
-           BlockEndOffset() <= other.BlockStartOffset() ||
-           InlineStartOffset() >= other.InlineEndOffset() ||
-           BlockStartOffset() >= other.BlockEndOffset());
-}
-
-bool NGLogicalRect::operator==(const NGLogicalRect& other) const {
-  return std::tie(other.offset, other.size) == std::tie(offset, size);
-}
-
-String NGLogicalRect::ToString() const {
-  return String::format("%s,%s %sx%s",
-                        offset.inline_offset.toString().ascii().data(),
-                        offset.block_offset.toString().ascii().data(),
-                        size.inline_size.toString().ascii().data(),
-                        size.block_size.toString().ascii().data());
-}
-
-
-bool NGBoxStrut::IsEmpty() const {
-  return *this == NGBoxStrut();
-}
-
-bool NGBoxStrut::operator==(const NGBoxStrut& other) const {
-  return std::tie(other.inline_start, other.inline_end, other.block_start,
-                  other.block_end) ==
-         std::tie(inline_start, inline_end, block_start, block_end);
-}
-
-// Converts physical dimensions to logical ones per
-// https://drafts.csswg.org/css-writing-modes-3/#logical-to-physical
-NGBoxStrut NGPhysicalBoxStrut::ConvertToLogical(NGWritingMode writing_mode,
-                                                TextDirection direction) const {
-  NGBoxStrut strut;
-  switch (writing_mode) {
-    case kHorizontalTopBottom:
-      strut = {left, right, top, bottom};
-      break;
-    case kVerticalRightLeft:
-    case kSidewaysRightLeft:
-      strut = {top, bottom, right, left};
-      break;
-    case kVerticalLeftRight:
-      strut = {top, bottom, left, right};
-      break;
-    case kSidewaysLeftRight:
-      strut = {bottom, top, left, right};
-      break;
-  }
-  if (direction == TextDirection::kRtl)
-    std::swap(strut.inline_start, strut.inline_end);
-  return strut;
-}
-
-LayoutUnit NGMarginStrut::Sum() const {
-  return margin + negative_margin;
-}
-
-bool NGMarginStrut::operator==(const NGMarginStrut& other) const {
-  return margin == other.margin && negative_margin == other.negative_margin;
-}
-
-void NGMarginStrut::Append(const LayoutUnit& value) {
-  if (value < 0) {
-    negative_margin = std::min(value, negative_margin);
-  } else {
-    margin = std::max(value, margin);
-  }
-}
-
-String NGMarginStrut::ToString() const {
-  return String::format("%d %d", margin.toInt(), negative_margin.toInt());
-}
-
-bool NGExclusion::operator==(const NGExclusion& other) const {
-  return std::tie(other.rect, other.type) == std::tie(rect, type);
-}
-
-String NGExclusion::ToString() const {
-  return String::format("Rect: %s Type: %d", rect.ToString().ascii().data(),
-                        type);
-}
-
-NGExclusions::NGExclusions()
-    : last_left_float(nullptr), last_right_float(nullptr) {}
-
-NGExclusions::NGExclusions(const NGExclusions& other) {
-  for (const auto& exclusion : other.storage)
-    Add(*exclusion);
-}
-
-void NGExclusions::Add(const NGExclusion& exclusion) {
-  storage.push_back(WTF::makeUnique<NGExclusion>(exclusion));
-  if (exclusion.type == NGExclusion::kFloatLeft) {
-    last_left_float = storage.rbegin()->get();
-  } else if (exclusion.type == NGExclusion::kFloatRight) {
-    last_right_float = storage.rbegin()->get();
-  }
-}
-
-inline NGExclusions& NGExclusions::operator=(const NGExclusions& other) {
-  storage.clear();
-  last_left_float = nullptr;
-  last_right_float = nullptr;
-  for (const auto& exclusion : other.storage)
-    Add(*exclusion);
-  return *this;
-}
-
-NGStaticPosition NGStaticPosition::Create(NGWritingMode writing_mode,
-                                          TextDirection direction,
-                                          NGPhysicalOffset offset) {
-  NGStaticPosition position;
-  position.offset = offset;
-  switch (writing_mode) {
-    case kHorizontalTopBottom:
-      position.type = (direction == TextDirection::kLtr) ? kTopLeft : kTopRight;
-      break;
-    case kVerticalRightLeft:
-    case kSidewaysRightLeft:
-      position.type =
-          (direction == TextDirection::kLtr) ? kTopRight : kBottomRight;
-      break;
-    case kVerticalLeftRight:
-      position.type =
-          (direction == TextDirection::kLtr) ? kTopLeft : kBottomLeft;
-      break;
-    case kSidewaysLeftRight:
-      position.type =
-          (direction == TextDirection::kLtr) ? kBottomLeft : kTopLeft;
-      break;
-  }
-  return position;
-}
-
-}  // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_units.h b/third_party/WebKit/Source/core/layout/ng/ng_units.h
deleted file mode 100644
index 58c9257..0000000
--- a/third_party/WebKit/Source/core/layout/ng/ng_units.h
+++ /dev/null
@@ -1,268 +0,0 @@
-// 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 NGUnits_h
-#define NGUnits_h
-
-#include "core/CoreExport.h"
-#include "core/layout/ng/geometry/ng_logical_offset.h"
-#include "core/layout/ng/geometry/ng_logical_size.h"
-#include "core/layout/ng/geometry/ng_physical_location.h"
-#include "core/layout/ng/geometry/ng_physical_offset.h"
-#include "core/layout/ng/geometry/ng_physical_rect.h"
-#include "core/layout/ng/geometry/ng_physical_size.h"
-#include "core/layout/ng/ng_writing_mode.h"
-#include "platform/LayoutUnit.h"
-#include "platform/text/TextDirection.h"
-#include "wtf/text/WTFString.h"
-
-namespace blink {
-
-struct NGBoxStrut;
-
-#define NGSizeIndefinite LayoutUnit(-1)
-
-struct CORE_EXPORT MinAndMaxContentSizes {
-  LayoutUnit min_content;
-  LayoutUnit max_content;
-  LayoutUnit ShrinkToFit(LayoutUnit available_size) const;
-  bool operator==(const MinAndMaxContentSizes& other) const;
-};
-
-inline std::ostream& operator<<(std::ostream& stream,
-                                const MinAndMaxContentSizes& value) {
-  return stream << "(" << value.min_content << ", " << value.max_content << ")";
-}
-
-// TODO(glebl): move to a separate file in layout/ng/units.
-struct CORE_EXPORT NGLogicalRect {
-  NGLogicalRect() {}
-  NGLogicalRect(const NGLogicalOffset& offset, const NGLogicalSize& size)
-      : offset(offset), size(size) {}
-  NGLogicalRect(LayoutUnit inline_offset,
-                LayoutUnit block_offset,
-                LayoutUnit inline_size,
-                LayoutUnit block_size)
-      : offset(inline_offset, block_offset), size(inline_size, block_size) {}
-
-  bool IsEmpty() const;
-
-  // Whether this rectangle is contained by the provided rectangle.
-  bool IsContained(const NGLogicalRect& other) const;
-
-  String ToString() const;
-  bool operator==(const NGLogicalRect& other) const;
-
-  // Getters
-  LayoutUnit InlineStartOffset() const { return offset.inline_offset; }
-
-  LayoutUnit InlineEndOffset() const {
-    return offset.inline_offset + size.inline_size;
-  }
-
-  LayoutUnit BlockStartOffset() const { return offset.block_offset; }
-
-  LayoutUnit BlockEndOffset() const {
-    return offset.block_offset + size.block_size;
-  }
-
-  LayoutUnit BlockSize() const { return size.block_size; }
-
-  LayoutUnit InlineSize() const { return size.inline_size; }
-
-  NGLogicalOffset offset;
-  NGLogicalSize size;
-};
-
-inline std::ostream& operator<<(std::ostream& stream,
-                                const NGLogicalRect& value) {
-  return stream << value.ToString();
-}
-
-// Struct that represents NG exclusion.
-struct CORE_EXPORT NGExclusion {
-  // Type of NG exclusion.
-  enum Type {
-    // Undefined exclusion type.
-    // At this moment it's also used to represent CSS3 exclusion.
-    kExclusionTypeUndefined = 0,
-    // Exclusion that is created by LEFT float.
-    kFloatLeft = 1,
-    // Exclusion that is created by RIGHT float.
-    kFloatRight = 2
-  };
-
-  // Rectangle in logical coordinates the represents this exclusion.
-  NGLogicalRect rect;
-
-  // Type of this exclusion.
-  Type type;
-
-  bool operator==(const NGExclusion& other) const;
-  String ToString() const;
-};
-
-inline std::ostream& operator<<(std::ostream& stream,
-                                const NGExclusion& value) {
-  return stream << value.ToString();
-}
-
-struct CORE_EXPORT NGExclusions {
-  // Default constructor.
-  NGExclusions();
-
-  // Copy constructor.
-  NGExclusions(const NGExclusions& other);
-
-  Vector<std::unique_ptr<const NGExclusion>> storage;
-
-  // Last left/right float exclusions are used to enforce the top edge alignment
-  // rule for floats and for the support of CSS "clear" property.
-  const NGExclusion* last_left_float;   // Owned by storage.
-  const NGExclusion* last_right_float;  // Owned by storage.
-
-  NGExclusions& operator=(const NGExclusions& other);
-
-  void Add(const NGExclusion& exclusion);
-};
-
-
-// Struct to store physical dimensions, independent of writing mode and
-// direction.
-// See https://drafts.csswg.org/css-writing-modes-3/#abstract-box
-struct CORE_EXPORT NGPhysicalBoxStrut {
-  LayoutUnit left;
-  LayoutUnit right;
-  LayoutUnit top;
-  LayoutUnit bottom;
-  NGBoxStrut ConvertToLogical(NGWritingMode, TextDirection) const;
-};
-
-// This struct is used for storing margins, borders or padding of a box on all
-// four edges.
-struct CORE_EXPORT NGBoxStrut {
-  LayoutUnit inline_start;
-  LayoutUnit inline_end;
-  LayoutUnit block_start;
-  LayoutUnit block_end;
-
-  LayoutUnit InlineSum() const { return inline_start + inline_end; }
-  LayoutUnit BlockSum() const { return block_start + block_end; }
-
-  bool IsEmpty() const;
-
-  // The following two operators exist primarily to have an easy way to access
-  // the sum of border and padding.
-  NGBoxStrut& operator+=(const NGBoxStrut& other) {
-    inline_start += other.inline_start;
-    inline_end += other.inline_end;
-    block_start += other.block_start;
-    block_end += other.block_end;
-    return *this;
-  }
-
-  NGBoxStrut operator+(const NGBoxStrut& other) {
-    NGBoxStrut result(*this);
-    result += other;
-    return result;
-  }
-
-  bool operator==(const NGBoxStrut& other) const;
-
-  String ToString() const {
-    return String::format("Inline: (%d %d) Block: (%d %d)",
-                          inline_start.toInt(), inline_end.toInt(),
-                          block_start.toInt(), block_end.toInt());
-  }
-};
-
-inline std::ostream& operator<<(std::ostream& stream, const NGBoxStrut& value) {
-  return stream << value.ToString();
-}
-
-// This struct is used for the margin collapsing calculation.
-struct CORE_EXPORT NGMarginStrut {
-  LayoutUnit margin;
-  LayoutUnit negative_margin;
-
-  // Appends negative or positive value to the current margin strut.
-  void Append(const LayoutUnit& value);
-
-  // Sum up negative and positive margins of this strut.
-  LayoutUnit Sum() const;
-
-  bool operator==(const NGMarginStrut& other) const;
-
-  String ToString() const;
-};
-
-inline std::ostream& operator<<(std::ostream& stream,
-                                const NGMarginStrut& value) {
-  return stream << value.ToString();
-}
-
-// Struct to represent a simple edge that has start and end.
-struct NGEdge {
-  LayoutUnit start;
-  LayoutUnit end;
-};
-
-// Represents static position of an out of flow descendant.
-struct CORE_EXPORT NGStaticPosition {
-  enum Type { kTopLeft, kTopRight, kBottomLeft, kBottomRight };
-
-  Type type;  // Logical corner that corresponds to physical top left.
-  NGPhysicalOffset offset;
-
-  // Creates a position with proper type wrt writing mode and direction.
-  static NGStaticPosition Create(NGWritingMode,
-                                 TextDirection,
-                                 NGPhysicalOffset);
-  // Left/Right/TopPosition functions map static position to
-  // left/right/top edge wrt container space.
-  // The function arguments are required to solve the equation:
-  // contaner_size = left + margin_left + width + margin_right + right
-  LayoutUnit LeftPosition(LayoutUnit container_size,
-                          LayoutUnit width,
-                          LayoutUnit margin_left,
-                          LayoutUnit margin_right) const {
-    return GenericPosition(HasLeft(), offset.left, container_size, width,
-                           margin_left, margin_right);
-  }
-  LayoutUnit RightPosition(LayoutUnit container_size,
-                           LayoutUnit width,
-                           LayoutUnit margin_left,
-                           LayoutUnit margin_right) const {
-    return GenericPosition(!HasLeft(), offset.left, container_size, width,
-                           margin_left, margin_right);
-  }
-  LayoutUnit TopPosition(LayoutUnit container_size,
-                         LayoutUnit height,
-                         LayoutUnit margin_top,
-                         LayoutUnit margin_bottom) const {
-    return GenericPosition(HasTop(), offset.top, container_size, height,
-                           margin_top, margin_bottom);
-  }
-
- private:
-  bool HasTop() const { return type == kTopLeft || type == kTopRight; }
-  bool HasLeft() const { return type == kTopLeft || type == kBottomLeft; }
-  LayoutUnit GenericPosition(bool position_matches,
-                             LayoutUnit position,
-                             LayoutUnit container_size,
-                             LayoutUnit length,
-                             LayoutUnit margin_start,
-                             LayoutUnit margin_end) const {
-    DCHECK_GE(container_size, LayoutUnit());
-    DCHECK_GE(length, LayoutUnit());
-    if (position_matches)
-      return position;
-    else
-      return container_size - position - length - margin_start - margin_end;
-  }
-};
-
-}  // namespace blink
-
-#endif  // NGUnits_h
diff --git a/third_party/WebKit/Source/core/paint/BackgroundImageGeometry.cpp b/third_party/WebKit/Source/core/paint/BackgroundImageGeometry.cpp
index c6c2fb0..d9c2b1b 100644
--- a/third_party/WebKit/Source/core/paint/BackgroundImageGeometry.cpp
+++ b/third_party/WebKit/Source/core/paint/BackgroundImageGeometry.cpp
@@ -411,7 +411,7 @@
     const LayoutRect& paintRect) {
   LayoutUnit left;
   LayoutUnit top;
-  LayoutSize positioningAreaSize;
+  LayoutRect positioningArea;
   bool isLayoutView = obj.isLayoutView();
   const LayoutBox* rootBox = nullptr;
   if (isLayoutView) {
@@ -473,8 +473,9 @@
       // The background of the box generated by the root element covers the
       // entire canvas and will be painted by the view object, but the we should
       // still use the root element box for positioning.
-      positioningAreaSize =
-          rootBox->size() - LayoutSize(left + right, top + bottom);
+      positioningArea.setSize(rootBox->size());
+      positioningArea.contractEdges(top, right, bottom, left);
+
       // The input paint rect is specified in root element local coordinate
       // (i.e. a transform is applied on the context for painting), and is
       // expanded to cover the whole canvas.  Since left/top is relative to the
@@ -482,12 +483,14 @@
       left -= paintRect.x();
       top -= paintRect.y();
     } else {
-      positioningAreaSize =
-          (cellUsingContainerBackground
-               ? getBackgroundObjectDimensions(toLayoutTableCell(obj),
-                                               toLayoutBox(positioningBox))
-               : paintRect.size()) -
-          LayoutSize(left + right, top + bottom);
+      if (cellUsingContainerBackground) {
+        positioningArea.setSize(getBackgroundObjectDimensions(
+            toLayoutTableCell(obj), toLayoutBox(positioningBox)));
+      } else {
+        positioningArea = paintRect;
+      }
+
+      positioningArea.contractEdges(top, right, bottom, left);
     }
   } else {
     setHasNonLocalGeometry();
@@ -509,11 +512,11 @@
           LayoutPoint(-paintContainer->localToAbsolute(FloatPoint())));
 
     setDestRect(viewportRect);
-    positioningAreaSize = destRect().size();
+    positioningArea = viewportRect;
   }
 
   LayoutSize fillTileSize(
-      calculateFillTileSize(positioningBox, fillLayer, positioningAreaSize));
+      calculateFillTileSize(positioningBox, fillLayer, positioningArea.size()));
   // It's necessary to apply the heuristic here prior to any further
   // calculations to avoid incorrectly using sub-pixel values that won't be
   // present in the painted tile.
@@ -522,12 +525,12 @@
   EFillRepeat backgroundRepeatX = fillLayer.repeatX();
   EFillRepeat backgroundRepeatY = fillLayer.repeatY();
   LayoutUnit unsnappedAvailableWidth =
-      positioningAreaSize.width() - fillTileSize.width();
+      positioningArea.width() - fillTileSize.width();
   LayoutUnit unsnappedAvailableHeight =
-      positioningAreaSize.height() - fillTileSize.height();
-  positioningAreaSize =
-      LayoutSize(snapSizeToPixel(positioningAreaSize.width(), m_destRect.x()),
-                 snapSizeToPixel(positioningAreaSize.height(), m_destRect.y()));
+      positioningArea.height() - fillTileSize.height();
+  LayoutSize positioningAreaSize =
+      LayoutSize(snapSizeToPixel(positioningArea.width(), m_destRect.x()),
+                 snapSizeToPixel(positioningArea.height(), m_destRect.y()));
   LayoutUnit availableWidth = positioningAreaSize.width() - tileSize().width();
   LayoutUnit availableHeight =
       positioningAreaSize.height() - tileSize().height();
diff --git a/third_party/WebKit/Source/core/paint/BoxBorderPainter.cpp b/third_party/WebKit/Source/core/paint/BoxBorderPainter.cpp
index 8d10bb36..3308fa3 100644
--- a/third_party/WebKit/Source/core/paint/BoxBorderPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/BoxBorderPainter.cpp
@@ -976,7 +976,7 @@
       return;
     case BorderStyleDotted:
     case BorderStyleDashed: {
-      drawDashedDottedBoxSideFromPath(graphicsContext, borderPath, thickness,
+      drawDashedDottedBoxSideFromPath(graphicsContext, borderRect, thickness,
                                       drawThickness, color, borderStyle);
       return;
     }
@@ -1011,18 +1011,34 @@
 
 void BoxBorderPainter::drawDashedDottedBoxSideFromPath(
     GraphicsContext& graphicsContext,
-    const Path& borderPath,
+    const LayoutRect& borderRect,
     float thickness,
     float drawThickness,
     Color color,
     EBorderStyle borderStyle) const {
+  // Convert the path to be down the middle of the dots or dashes.
+  const LayoutRectOutsets centerOffsets(
+      -m_edges[BSTop].usedWidth() * 0.5, -m_edges[BSRight].usedWidth() * 0.5,
+      -m_edges[BSBottom].usedWidth() * 0.5, -m_edges[BSLeft].usedWidth() * 0.5);
+  Path centerlinePath;
+  centerlinePath.addRoundedRect(m_style.getRoundedInnerBorderFor(
+      borderRect, centerOffsets, m_includeLogicalLeftEdge,
+      m_includeLogicalRightEdge));
+
   graphicsContext.setStrokeColor(color);
 
+  if (!StrokeData::strokeIsDashed(thickness, borderStyle == BorderStyleDashed
+                                                 ? DashedStroke
+                                                 : DottedStroke)) {
+    drawWideDottedBoxSideFromPath(graphicsContext, centerlinePath, thickness);
+    return;
+  }
+
   // The stroke is doubled here because the provided path is the
   // outside edge of the border so half the stroke is clipped off.
   // The extra multiplier is so that the clipping mask can antialias
   // the edges to prevent jaggies.
-  graphicsContext.setStrokeThickness(drawThickness * 2 * 1.1f);
+  graphicsContext.setStrokeThickness(drawThickness * 1.1f);
   graphicsContext.setStrokeStyle(
       borderStyle == BorderStyleDashed ? DashedStroke : DottedStroke);
 
@@ -1034,11 +1050,10 @@
   // do the same thing as StrokeData::setupPaintDashPathEffect and should be
   // refactored to re-use that code. It would require
   // GraphicsContext::strokePath to take a length parameter.
-
   float dashLength =
       thickness * ((borderStyle == BorderStyleDashed) ? 3.0f : 1.0f);
   float gapLength = dashLength;
-  float numberOfDashes = borderPath.length() / dashLength;
+  float numberOfDashes = centerlinePath.length() / dashLength;
   // Don't try to show dashes if we have less than 2 dashes + 2 gaps.
   // FIXME: should do this test per side.
   if (numberOfDashes >= 4) {
@@ -1057,8 +1072,50 @@
 
   // FIXME: stroking the border path causes issues with tight corners:
   // https://bugs.webkit.org/show_bug.cgi?id=58711
-  // Also, to get the best appearance we should stroke a path between the
-  // two borders.
+  graphicsContext.strokePath(centerlinePath);
+}
+
+void BoxBorderPainter::drawWideDottedBoxSideFromPath(
+    GraphicsContext& graphicsContext,
+    const Path& borderPath,
+    float thickness) const {
+  graphicsContext.setStrokeThickness(thickness);
+  graphicsContext.setStrokeStyle(DottedStroke);
+
+  // TODO(schenney): This code for setting up the dash effect is largely
+  // duplicated from StrokeData::setupPaintDashPathEffect and both this code
+  // and the method above should be refactored to re-use that code. It would
+  // require GraphicsContext::strokePath to take a length parameter.
+  graphicsContext.setLineCap(RoundCap);
+
+  // Adjust the width to get equal dot spacing as much as possible.
+  float perDotLength = thickness * 2;
+  static float epsilon = 1.0e-2f;
+  float pathLength = borderPath.length();
+
+  if (pathLength < perDotLength + thickness) {
+    // Exactly 2 dots with whatever space we can get
+    DashArray lineDash;
+    lineDash.push_back(0);
+    lineDash.push_back(pathLength - thickness - epsilon);
+    graphicsContext.setLineDash(lineDash, 0);
+  } else {
+    // Determine what number of dots gives the minimum deviation from
+    // idealGap between dots. Set the gap to that width.
+    float minNumDots = floorf((pathLength + thickness) / perDotLength);
+    float maxNumDots = minNumDots + 1;
+    float minGap = (pathLength - minNumDots * thickness) / (minNumDots - 1);
+    float maxGap = (pathLength - maxNumDots * thickness) / (maxNumDots - 1);
+    auto gap =
+        fabs(minGap - thickness) < fabs(maxGap - thickness) ? minGap : maxGap;
+    DashArray lineDash;
+    lineDash.push_back(0);
+    lineDash.push_back(gap + thickness - epsilon);
+    graphicsContext.setLineDash(lineDash, 0);
+  }
+
+  // TODO(schenney): stroking the border path causes issues with tight corners:
+  // https://bugs.webkit.org/show_bug.cgi?id=58711
   graphicsContext.strokePath(borderPath);
 }
 
diff --git a/third_party/WebKit/Source/core/paint/BoxBorderPainter.h b/third_party/WebKit/Source/core/paint/BoxBorderPainter.h
index 9ac25d0..56138af 100644
--- a/third_party/WebKit/Source/core/paint/BoxBorderPainter.h
+++ b/third_party/WebKit/Source/core/paint/BoxBorderPainter.h
@@ -77,11 +77,14 @@
                            Color,
                            EBorderStyle) const;
   void drawDashedDottedBoxSideFromPath(GraphicsContext&,
-                                       const Path&,
+                                       const LayoutRect&,
                                        float thickness,
                                        float drawThickness,
                                        Color,
                                        EBorderStyle) const;
+  void drawWideDottedBoxSideFromPath(GraphicsContext&,
+                                     const Path&,
+                                     float thickness) const;
   void drawDoubleBoxSideFromPath(GraphicsContext&,
                                  const LayoutRect&,
                                  const Path&,
diff --git a/third_party/WebKit/Source/core/paint/ObjectPainter.cpp b/third_party/WebKit/Source/core/paint/ObjectPainter.cpp
index 5e77682a..629a62a 100644
--- a/third_party/WebKit/Source/core/paint/ObjectPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/ObjectPainter.cpp
@@ -14,6 +14,7 @@
 #include "core/style/BorderEdge.h"
 #include "core/style/ComputedStyle.h"
 #include "platform/geometry/LayoutPoint.h"
+#include "platform/graphics/GraphicsContextStateSaver.h"
 
 namespace blink {
 
@@ -415,8 +416,7 @@
                                               bool antialias) {
   DCHECK_GT(thickness, 0);
 
-  bool wasAntialiased = graphicsContext.shouldAntialias();
-  StrokeStyle oldStrokeStyle = graphicsContext.getStrokeStyle();
+  GraphicsContextStateSaver stateSaver(graphicsContext);
   graphicsContext.setShouldAntialias(antialias);
   graphicsContext.setStrokeColor(color);
   graphicsContext.setStrokeThickness(thickness);
@@ -437,8 +437,6 @@
       break;
     }
   }
-  graphicsContext.setShouldAntialias(wasAntialiased);
-  graphicsContext.setStrokeStyle(oldStrokeStyle);
 }
 
 void ObjectPainter::drawDoubleBoxSide(GraphicsContext& graphicsContext,
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp b/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp
index 8a5fd7f3..9055171 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp
@@ -314,7 +314,7 @@
   return IntRect();
 }
 
-IntRect PaintLayerScrollableArea::convertFromScrollbarToContainingWidget(
+IntRect PaintLayerScrollableArea::convertFromScrollbarToContainingFrameViewBase(
     const Scrollbar& scrollbar,
     const IntRect& scrollbarRect) const {
   LayoutView* view = box().view();
@@ -327,7 +327,7 @@
   return view->frameView()->convertFromLayoutItem(LayoutBoxItem(&box()), rect);
 }
 
-IntRect PaintLayerScrollableArea::convertFromContainingWidgetToScrollbar(
+IntRect PaintLayerScrollableArea::convertFromContainingFrameViewBaseToScrollbar(
     const Scrollbar& scrollbar,
     const IntRect& parentRect) const {
   LayoutView* view = box().view();
@@ -340,7 +340,8 @@
   return rect;
 }
 
-IntPoint PaintLayerScrollableArea::convertFromScrollbarToContainingWidget(
+IntPoint
+PaintLayerScrollableArea::convertFromScrollbarToContainingFrameViewBase(
     const Scrollbar& scrollbar,
     const IntPoint& scrollbarPoint) const {
   LayoutView* view = box().view();
@@ -352,7 +353,8 @@
   return view->frameView()->convertFromLayoutItem(LayoutBoxItem(&box()), point);
 }
 
-IntPoint PaintLayerScrollableArea::convertFromContainingWidgetToScrollbar(
+IntPoint
+PaintLayerScrollableArea::convertFromContainingFrameViewBaseToScrollbar(
     const Scrollbar& scrollbar,
     const IntPoint& parentPoint) const {
   LayoutView* view = box().view();
@@ -1900,7 +1902,7 @@
              controller.globalRootScroller()) == this;
 }
 
-FrameViewBase* PaintLayerScrollableArea::getWidget() {
+FrameViewBase* PaintLayerScrollableArea::getFrameViewBase() {
   return box().frame()->view();
 }
 
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.h b/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.h
index 98ef35a..e444af6 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.h
+++ b/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.h
@@ -260,14 +260,16 @@
   bool isActive() const override;
   bool isScrollCornerVisible() const override;
   IntRect scrollCornerRect() const override;
-  IntRect convertFromScrollbarToContainingWidget(const Scrollbar&,
-                                                 const IntRect&) const override;
-  IntRect convertFromContainingWidgetToScrollbar(const Scrollbar&,
-                                                 const IntRect&) const override;
-  IntPoint convertFromScrollbarToContainingWidget(
+  IntRect convertFromScrollbarToContainingFrameViewBase(
+      const Scrollbar&,
+      const IntRect&) const override;
+  IntRect convertFromContainingFrameViewBaseToScrollbar(
+      const Scrollbar&,
+      const IntRect&) const override;
+  IntPoint convertFromScrollbarToContainingFrameViewBase(
       const Scrollbar&,
       const IntPoint&) const override;
-  IntPoint convertFromContainingWidgetToScrollbar(
+  IntPoint convertFromContainingFrameViewBaseToScrollbar(
       const Scrollbar&,
       const IntPoint&) const override;
   int scrollSize(ScrollbarOrientation) const override;
@@ -421,7 +423,7 @@
   IntRect rectForHorizontalScrollbar(const IntRect& borderBoxRect) const;
   IntRect rectForVerticalScrollbar(const IntRect& borderBoxRect) const;
 
-  FrameViewBase* getWidget() override;
+  FrameViewBase* getFrameViewBase() override;
   bool shouldPerformScrollAnchoring() const override;
   ScrollAnchor* scrollAnchor() override { return &m_scrollAnchor; }
   bool isPaintLayerScrollableArea() const override { return true; }
diff --git a/third_party/WebKit/Source/core/style/ComputedStyle.h b/third_party/WebKit/Source/core/style/ComputedStyle.h
index 340e8b6..ed8e7e1 100644
--- a/third_party/WebKit/Source/core/style/ComputedStyle.h
+++ b/third_party/WebKit/Source/core/style/ComputedStyle.h
@@ -3790,19 +3790,20 @@
 }
 
 inline bool ComputedStyle::hasAnyPublicPseudoStyles() const {
-  return PublicPseudoIdMask & m_nonInheritedData.m_pseudoBits;
+  return m_nonInheritedData.m_pseudoBits;
 }
 
 inline bool ComputedStyle::hasPseudoStyle(PseudoId pseudo) const {
-  ASSERT(pseudo > PseudoIdNone);
-  ASSERT(pseudo < FirstInternalPseudoId);
-  return (1 << (pseudo - 1)) & m_nonInheritedData.m_pseudoBits;
+  DCHECK(pseudo >= FirstPublicPseudoId);
+  DCHECK(pseudo < FirstInternalPseudoId);
+  return (1 << (pseudo - FirstPublicPseudoId)) &
+         m_nonInheritedData.m_pseudoBits;
 }
 
 inline void ComputedStyle::setHasPseudoStyle(PseudoId pseudo) {
-  ASSERT(pseudo > PseudoIdNone);
-  ASSERT(pseudo < FirstInternalPseudoId);
-  m_nonInheritedData.m_pseudoBits |= 1 << (pseudo - 1);
+  DCHECK(pseudo >= FirstPublicPseudoId);
+  DCHECK(pseudo < FirstInternalPseudoId);
+  m_nonInheritedData.m_pseudoBits |= 1 << (pseudo - FirstPublicPseudoId);
 }
 
 inline bool ComputedStyle::hasPseudoElementStyle() const {
diff --git a/third_party/WebKit/Source/core/style/ComputedStyleConstants.h b/third_party/WebKit/Source/core/style/ComputedStyleConstants.h
index 7cfc428..1175eed8 100644
--- a/third_party/WebKit/Source/core/style/ComputedStyleConstants.h
+++ b/third_party/WebKit/Source/core/style/ComputedStyleConstants.h
@@ -52,8 +52,7 @@
   IndependentInherit,
   Inherit,
   Force,
-  Reattach,
-  ReattachNoLayoutObject
+  Reattach
 };
 
 // Static pseudo styles. Dynamic ones are produced on the fly.
@@ -82,11 +81,9 @@
   AfterLastInternalPseudoId,
   FirstPublicPseudoId = PseudoIdFirstLine,
   FirstInternalPseudoId = PseudoIdScrollbarThumb,
-  PublicPseudoIdMask =
-      ((1 << FirstInternalPseudoId) - 1) & ~((1 << FirstPublicPseudoId) - 1),
-  ElementPseudoIdMask = (1 << (PseudoIdBefore - 1)) |
-                        (1 << (PseudoIdAfter - 1)) |
-                        (1 << (PseudoIdBackdrop - 1))
+  ElementPseudoIdMask = (1 << (PseudoIdBefore - FirstPublicPseudoId)) |
+                        (1 << (PseudoIdAfter - FirstPublicPseudoId)) |
+                        (1 << (PseudoIdBackdrop - FirstPublicPseudoId))
 };
 
 enum ColumnFill { ColumnFillBalance, ColumnFillAuto };
diff --git a/third_party/WebKit/Source/core/style/ComputedStyleTest.cpp b/third_party/WebKit/Source/core/style/ComputedStyleTest.cpp
index f3f588b5..7c8f3c6 100644
--- a/third_party/WebKit/Source/core/style/ComputedStyleTest.cpp
+++ b/third_party/WebKit/Source/core/style/ComputedStyleTest.cpp
@@ -78,4 +78,18 @@
   EXPECT_TRUE(style->isStackingContext());
 }
 
+TEST(ComputedStyleTest, FirstPublicPseudoStyle) {
+  RefPtr<ComputedStyle> style = ComputedStyle::create();
+  style->setHasPseudoStyle(PseudoIdFirstLine);
+  EXPECT_TRUE(style->hasPseudoStyle(PseudoIdFirstLine));
+  EXPECT_TRUE(style->hasAnyPublicPseudoStyles());
+}
+
+TEST(ComputedStyleTest, LastPublicPseudoStyle) {
+  RefPtr<ComputedStyle> style = ComputedStyle::create();
+  style->setHasPseudoStyle(PseudoIdScrollbar);
+  EXPECT_TRUE(style->hasPseudoStyle(PseudoIdScrollbar));
+  EXPECT_TRUE(style->hasAnyPublicPseudoStyles());
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/testing/Internals.cpp b/third_party/WebKit/Source/core/testing/Internals.cpp
index ac589d6..94196d9 100644
--- a/third_party/WebKit/Source/core/testing/Internals.cpp
+++ b/third_party/WebKit/Source/core/testing/Internals.cpp
@@ -2247,7 +2247,7 @@
   }
 
   Page* page = m_document->page();
-  page->frameHost().setDefaultPageScaleLimits(minScaleFactor, maxScaleFactor);
+  page->setDefaultPageScaleLimits(minScaleFactor, maxScaleFactor);
 }
 
 bool Internals::magnifyScaleAroundAnchor(float scaleFactor, float x, float y) {
diff --git a/third_party/WebKit/Source/core/workers/WorkerGlobalScope.cpp b/third_party/WebKit/Source/core/workers/WorkerGlobalScope.cpp
index 47a0ec80..de130946 100644
--- a/third_party/WebKit/Source/core/workers/WorkerGlobalScope.cpp
+++ b/third_party/WebKit/Source/core/workers/WorkerGlobalScope.cpp
@@ -163,6 +163,10 @@
   m_closing = true;
 }
 
+String WorkerGlobalScope::origin() const {
+  return getSecurityOrigin()->toString();
+}
+
 void WorkerGlobalScope::importScripts(const Vector<String>& urls,
                                       ExceptionState& exceptionState) {
   DCHECK(contentSecurityPolicy());
diff --git a/third_party/WebKit/Source/core/workers/WorkerGlobalScope.h b/third_party/WebKit/Source/core/workers/WorkerGlobalScope.h
index d2dad858..7f869a2 100644
--- a/third_party/WebKit/Source/core/workers/WorkerGlobalScope.h
+++ b/third_party/WebKit/Source/core/workers/WorkerGlobalScope.h
@@ -101,6 +101,8 @@
     return ExecutionContext::isSecureContext(StandardSecureContextCheck);
   }
 
+  String origin() const;
+
   DEFINE_ATTRIBUTE_EVENT_LISTENER(error);
   DEFINE_ATTRIBUTE_EVENT_LISTENER(rejectionhandled);
   DEFINE_ATTRIBUTE_EVENT_LISTENER(unhandledrejection);
diff --git a/third_party/WebKit/Source/core/workers/WorkerGlobalScope.idl b/third_party/WebKit/Source/core/workers/WorkerGlobalScope.idl
index 2c6f355..e6c5fc5 100644
--- a/third_party/WebKit/Source/core/workers/WorkerGlobalScope.idl
+++ b/third_party/WebKit/Source/core/workers/WorkerGlobalScope.idl
@@ -63,6 +63,9 @@
     // Secure Contexts
     // https://w3c.github.io/webappsec-secure-contexts/#dom-windoworworkerglobalscope-issecurecontext
     [ImplementedAs=isSecureContextForBindings] readonly attribute boolean isSecureContext;
+
+    // https://html.spec.whatwg.org/#windoworworkerglobalscope-mixin
+    [Replaceable] readonly attribute DOMString origin;
 };
 
 WorkerGlobalScope implements WindowBase64;
diff --git a/third_party/WebKit/Source/devtools/front_end/Tests.js b/third_party/WebKit/Source/devtools/front_end/Tests.js
index 8a2af93..32107ca 100644
--- a/third_party/WebKit/Source/devtools/front_end/Tests.js
+++ b/third_party/WebKit/Source/devtools/front_end/Tests.js
@@ -808,9 +808,9 @@
     setTimeout(reset, 0);
 
     function createSettings() {
-      var localSetting = Common.settings.createSetting('local', undefined, true);
+      var localSetting = Common.settings.createLocalSetting('local', undefined);
       localSetting.set({s: 'local', n: 1});
-      var globalSetting = Common.settings.createSetting('global', undefined, false);
+      var globalSetting = Common.settings.createSetting('global', undefined);
       globalSetting.set({s: 'global', n: 2});
     }
 
@@ -822,11 +822,11 @@
     function gotPreferences(prefs) {
       Main.Main._instanceForTest._createSettings(prefs);
 
-      var localSetting = Common.settings.createSetting('local', undefined, true);
+      var localSetting = Common.settings.createLocalSetting('local', undefined);
       test.assertEquals('object', typeof localSetting.get());
       test.assertEquals('local', localSetting.get().s);
       test.assertEquals(1, localSetting.get().n);
-      var globalSetting = Common.settings.createSetting('global', undefined, false);
+      var globalSetting = Common.settings.createSetting('global', undefined);
       test.assertEquals('object', typeof globalSetting.get());
       test.assertEquals('global', globalSetting.get().s);
       test.assertEquals(2, globalSetting.get().n);
diff --git a/third_party/WebKit/Source/devtools/front_end/common/Settings.js b/third_party/WebKit/Source/devtools/front_end/common/Settings.js
index 28a3087..280e1684 100644
--- a/third_party/WebKit/Source/devtools/front_end/common/Settings.js
+++ b/third_party/WebKit/Source/devtools/front_end/common/Settings.js
@@ -37,8 +37,9 @@
    * @param {!Common.SettingsStorage} localStorage
    */
   constructor(globalStorage, localStorage) {
-    this._settingsStorage = globalStorage;
+    this._globalStorage = globalStorage;
     this._localStorage = localStorage;
+    this._sessionStorage = new Common.SettingsStorage({});
 
     this._eventSupport = new Common.Object();
     /** @type {!Map<string, !Common.Setting>} */
@@ -54,11 +55,24 @@
   _registerModuleSetting(extension) {
     var descriptor = extension.descriptor();
     var settingName = descriptor['settingName'];
-    var settingType = descriptor['settingType'];
+    var isRegex = descriptor['settingType'] === 'regex';
     var defaultValue = descriptor['defaultValue'];
-    var isLocal = !!descriptor['local'];
-    var setting = settingType === 'regex' ? this.createRegExpSetting(settingName, defaultValue, undefined, isLocal) :
-                                            this.createSetting(settingName, defaultValue, isLocal);
+    var storageType;
+    switch (descriptor['storageType']) {
+      case ('local'):
+        storageType = Common.SettingStorageType.Local;
+        break;
+      case ('session'):
+        storageType = Common.SettingStorageType.Session;
+        break;
+      case ('global'):
+        storageType = Common.SettingStorageType.Global;
+        break;
+      default:
+        storageType = Common.SettingStorageType.Global;
+    }
+    var setting = isRegex ? this.createRegExpSetting(settingName, defaultValue, undefined, storageType) :
+                            this.createSetting(settingName, defaultValue, storageType);
     if (descriptor['title'])
       setting.setTitle(descriptor['title']);
     this._moduleSettings.set(settingName, setting);
@@ -89,15 +103,13 @@
   /**
    * @param {string} key
    * @param {*} defaultValue
-   * @param {boolean=} isLocal
+   * @param {!Common.SettingStorageType=} storageType
    * @return {!Common.Setting}
    */
-  createSetting(key, defaultValue, isLocal) {
-    if (!this._registry.get(key)) {
-      this._registry.set(
-          key, new Common.Setting(
-                   this, key, defaultValue, this._eventSupport, isLocal ? this._localStorage : this._settingsStorage));
-    }
+  createSetting(key, defaultValue, storageType) {
+    var storage = this._storageFromType(storageType);
+    if (!this._registry.get(key))
+      this._registry.set(key, new Common.Setting(this, key, defaultValue, this._eventSupport, storage));
     return /** @type {!Common.Setting} */ (this._registry.get(key));
   }
 
@@ -107,32 +119,48 @@
    * @return {!Common.Setting}
    */
   createLocalSetting(key, defaultValue) {
-    return this.createSetting(key, defaultValue, true);
+    return this.createSetting(key, defaultValue, Common.SettingStorageType.Local);
   }
 
   /**
    * @param {string} key
    * @param {string} defaultValue
    * @param {string=} regexFlags
-   * @param {boolean=} isLocal
+   * @param {!Common.SettingStorageType=} storageType
    * @return {!Common.RegExpSetting}
    */
-  createRegExpSetting(key, defaultValue, regexFlags, isLocal) {
+  createRegExpSetting(key, defaultValue, regexFlags, storageType) {
     if (!this._registry.get(key)) {
       this._registry.set(
-          key, new Common.RegExpSetting(
-                   this, key, defaultValue, this._eventSupport, isLocal ? this._localStorage : this._settingsStorage,
-                   regexFlags));
+          key,
+          new Common.RegExpSetting(
+              this, key, defaultValue, this._eventSupport, this._storageFromType(storageType), regexFlags));
     }
     return /** @type {!Common.RegExpSetting} */ (this._registry.get(key));
   }
 
   clearAll() {
-    this._settingsStorage.removeAll();
+    this._globalStorage.removeAll();
     this._localStorage.removeAll();
     var versionSetting = Common.settings.createSetting(Common.VersionController._currentVersionName, 0);
     versionSetting.set(Common.VersionController.currentVersion);
   }
+
+  /**
+   * @param {!Common.SettingStorageType=} storageType
+   * @return {!Common.SettingsStorage}
+   */
+  _storageFromType(storageType) {
+    switch (storageType) {
+      case (Common.SettingStorageType.Local):
+        return this._localStorage;
+      case (Common.SettingStorageType.Session):
+        return this._sessionStorage;
+      case (Common.SettingStorageType.Global):
+        return this._globalStorage;
+    }
+    return this._globalStorage;
+  }
 };
 
 /**
@@ -753,7 +781,7 @@
         continue;
       var value = window.localStorage[key];
       window.localStorage.removeItem(key);
-      Common.settings._settingsStorage[key] = value;
+      Common.settings._globalStorage[key] = value;
     }
   }
 
@@ -778,6 +806,15 @@
 Common.settings;
 
 /**
+ * @enum {symbol}
+ */
+Common.SettingStorageType = {
+  Global: Symbol('Global'),
+  Local: Symbol('Local'),
+  Session: Symbol('Session')
+};
+
+/**
  * @param {string} settingName
  * @return {!Common.Setting}
  */
diff --git a/third_party/WebKit/Source/devtools/front_end/help/Help.js b/third_party/WebKit/Source/devtools/front_end/help/Help.js
index 7d3b6cb..b2028f326 100644
--- a/third_party/WebKit/Source/devtools/front_end/help/Help.js
+++ b/third_party/WebKit/Source/devtools/front_end/help/Help.js
@@ -35,7 +35,7 @@
 Help.releaseNoteVersionSetting = function() {
   if (!Help._releaseNoteVersionSetting) {
     /** @type {!Common.Setting} */
-    Help._releaseNoteVersionSetting = Common.settings.createSetting('releaseNoteVersionSeen', 0, false);
+    Help._releaseNoteVersionSetting = Common.settings.createSetting('releaseNoteVersionSeen', 0);
   }
   return Help._releaseNoteVersionSetting;
 };
diff --git a/third_party/WebKit/Source/devtools/front_end/main/module.json b/third_party/WebKit/Source/devtools/front_end/main/module.json
index 1df7509..c1480768 100644
--- a/third_party/WebKit/Source/devtools/front_end/main/module.json
+++ b/third_party/WebKit/Source/devtools/front_end/main/module.json
@@ -251,6 +251,7 @@
             "title": "Disable JavaScript",
             "settingName": "javaScriptDisabled",
             "settingType": "boolean",
+            "storageType": "session",
             "order": 1,
             "defaultValue": false,
             "options": [
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/NetworkManager.js b/third_party/WebKit/Source/devtools/front_end/sdk/NetworkManager.js
index 2a0ae0a..6392ba0 100644
--- a/third_party/WebKit/Source/devtools/front_end/sdk/NetworkManager.js
+++ b/third_party/WebKit/Source/devtools/front_end/sdk/NetworkManager.js
@@ -689,7 +689,6 @@
     this._blockedURLs = new Set();
     this._blockedSetting = Common.moduleSetting('networkBlockedURLs');
     this._blockedSetting.addChangeListener(this._updateBlockedURLs, this);
-    this._blockedSetting.set([]);
     this._updateBlockedURLs();
 
     this._userAgentOverride = '';
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/module.json b/third_party/WebKit/Source/devtools/front_end/sdk/module.json
index 72143bb..f20f36a 100644
--- a/third_party/WebKit/Source/devtools/front_end/sdk/module.json
+++ b/third_party/WebKit/Source/devtools/front_end/sdk/module.json
@@ -10,6 +10,7 @@
             "type": "setting",
             "settingName": "networkBlockedURLs",
             "settingType": "array",
+            "storageType": "session",
             "defaultValue": []
         },
         {
diff --git a/third_party/WebKit/Source/modules/device_orientation/DeviceAccelerationInit.idl b/third_party/WebKit/Source/modules/device_orientation/DeviceAccelerationInit.idl
new file mode 100644
index 0000000..7276e85
--- /dev/null
+++ b/third_party/WebKit/Source/modules/device_orientation/DeviceAccelerationInit.idl
@@ -0,0 +1,11 @@
+// Copyright 2017 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.
+
+// https://www.w3.org/TR/2016/CR-orientation-event-20160818/#devicemotion
+
+dictionary DeviceAccelerationInit {
+  double? x = null;
+  double? y = null;
+  double? z = null;
+};
diff --git a/third_party/WebKit/Source/modules/device_orientation/DeviceMotionData.cpp b/third_party/WebKit/Source/modules/device_orientation/DeviceMotionData.cpp
index c75a84ac..e0965a8d 100644
--- a/third_party/WebKit/Source/modules/device_orientation/DeviceMotionData.cpp
+++ b/third_party/WebKit/Source/modules/device_orientation/DeviceMotionData.cpp
@@ -24,6 +24,10 @@
  */
 
 #include "modules/device_orientation/DeviceMotionData.h"
+
+#include "modules/device_orientation/DeviceAccelerationInit.h"
+#include "modules/device_orientation/DeviceMotionEventInit.h"
+#include "modules/device_orientation/DeviceRotationRateInit.h"
 #include "public/platform/modules/device_orientation/WebDeviceMotionData.h"
 
 namespace blink {
@@ -39,6 +43,13 @@
                                             canProvideZ, z);
 }
 
+DeviceMotionData::Acceleration* DeviceMotionData::Acceleration::create(
+    const DeviceAccelerationInit& init) {
+  return new DeviceMotionData::Acceleration(
+      init.hasX(), init.hasX() ? init.x() : 0, init.hasY(),
+      init.hasY() ? init.y() : 0, init.hasZ(), init.hasZ() ? init.z() : 0);
+}
+
 DeviceMotionData::Acceleration::Acceleration(bool canProvideX,
                                              double x,
                                              bool canProvideY,
@@ -65,6 +76,14 @@
       canProvideAlpha, alpha, canProvideBeta, beta, canProvideGamma, gamma);
 }
 
+DeviceMotionData::RotationRate* DeviceMotionData::RotationRate::create(
+    const DeviceRotationRateInit& init) {
+  return new DeviceMotionData::RotationRate(
+      init.hasAlpha(), init.hasAlpha() ? init.alpha() : 0, init.hasBeta(),
+      init.hasBeta() ? init.beta() : 0, init.hasGamma(),
+      init.hasGamma() ? init.gamma() : 0);
+}
+
 DeviceMotionData::RotationRate::RotationRate(bool canProvideAlpha,
                                              double alpha,
                                              bool canProvideBeta,
@@ -92,6 +111,21 @@
                               rotationRate, canProvideInterval, interval);
 }
 
+DeviceMotionData* DeviceMotionData::create(const DeviceMotionEventInit& init) {
+  return DeviceMotionData::create(
+      init.hasAcceleration()
+          ? DeviceMotionData::Acceleration::create(init.acceleration())
+          : nullptr,
+      init.hasAccelerationIncludingGravity()
+          ? DeviceMotionData::Acceleration::create(
+                init.accelerationIncludingGravity())
+          : nullptr,
+      init.hasRotationRate()
+          ? DeviceMotionData::RotationRate::create(init.rotationRate())
+          : nullptr,
+      init.hasInterval(), init.hasInterval() ? init.interval() : 0);
+}
+
 DeviceMotionData* DeviceMotionData::create(const WebDeviceMotionData& data) {
   return DeviceMotionData::create(
       DeviceMotionData::Acceleration::create(
diff --git a/third_party/WebKit/Source/modules/device_orientation/DeviceMotionData.h b/third_party/WebKit/Source/modules/device_orientation/DeviceMotionData.h
index 286e137..986088a5 100644
--- a/third_party/WebKit/Source/modules/device_orientation/DeviceMotionData.h
+++ b/third_party/WebKit/Source/modules/device_orientation/DeviceMotionData.h
@@ -30,6 +30,9 @@
 
 namespace blink {
 
+class DeviceAccelerationInit;
+class DeviceMotionEventInit;
+class DeviceRotationRateInit;
 class WebDeviceMotionData;
 
 class DeviceMotionData final : public GarbageCollected<DeviceMotionData> {
@@ -43,6 +46,7 @@
                                 double y,
                                 bool canProvideZ,
                                 double z);
+    static Acceleration* create(const DeviceAccelerationInit&);
     DEFINE_INLINE_TRACE() {}
 
     bool canProvideX() const { return m_canProvideX; }
@@ -79,6 +83,7 @@
                                 double beta,
                                 bool canProvideGamma,
                                 double gamma);
+    static RotationRate* create(const DeviceRotationRateInit&);
     DEFINE_INLINE_TRACE() {}
 
     bool canProvideAlpha() const { return m_canProvideAlpha; }
@@ -112,6 +117,7 @@
                                   RotationRate*,
                                   bool canProvideInterval,
                                   double interval);
+  static DeviceMotionData* create(const DeviceMotionEventInit&);
   static DeviceMotionData* create(const WebDeviceMotionData&);
   DECLARE_TRACE();
 
diff --git a/third_party/WebKit/Source/modules/device_orientation/DeviceMotionEvent.cpp b/third_party/WebKit/Source/modules/device_orientation/DeviceMotionEvent.cpp
index 0985837..0a5c88e 100644
--- a/third_party/WebKit/Source/modules/device_orientation/DeviceMotionEvent.cpp
+++ b/third_party/WebKit/Source/modules/device_orientation/DeviceMotionEvent.cpp
@@ -27,6 +27,7 @@
 
 #include "modules/device_orientation/DeviceAcceleration.h"
 #include "modules/device_orientation/DeviceMotionData.h"
+#include "modules/device_orientation/DeviceMotionEventInit.h"
 #include "modules/device_orientation/DeviceRotationRate.h"
 
 namespace blink {
@@ -37,6 +38,11 @@
     : m_deviceMotionData(DeviceMotionData::create()) {}
 
 DeviceMotionEvent::DeviceMotionEvent(const AtomicString& eventType,
+                                     const DeviceMotionEventInit& initializer)
+    : Event(eventType, initializer),
+      m_deviceMotionData(DeviceMotionData::create(initializer)) {}
+
+DeviceMotionEvent::DeviceMotionEvent(const AtomicString& eventType,
                                      DeviceMotionData* deviceMotionData)
     : Event(eventType, false, false),  // Can't bubble, not cancelable
       m_deviceMotionData(deviceMotionData) {}
diff --git a/third_party/WebKit/Source/modules/device_orientation/DeviceMotionEvent.h b/third_party/WebKit/Source/modules/device_orientation/DeviceMotionEvent.h
index 47ba9603b..672ae11 100644
--- a/third_party/WebKit/Source/modules/device_orientation/DeviceMotionEvent.h
+++ b/third_party/WebKit/Source/modules/device_orientation/DeviceMotionEvent.h
@@ -33,6 +33,7 @@
 
 class DeviceAcceleration;
 class DeviceMotionData;
+class DeviceMotionEventInit;
 class DeviceRotationRate;
 
 class DeviceMotionEvent final : public Event {
@@ -42,6 +43,10 @@
   ~DeviceMotionEvent() override;
   static DeviceMotionEvent* create() { return new DeviceMotionEvent; }
   static DeviceMotionEvent* create(const AtomicString& eventType,
+                                   const DeviceMotionEventInit& initializer) {
+    return new DeviceMotionEvent(eventType, initializer);
+  }
+  static DeviceMotionEvent* create(const AtomicString& eventType,
                                    DeviceMotionData* deviceMotionData) {
     return new DeviceMotionEvent(eventType, deviceMotionData);
   }
@@ -66,6 +71,7 @@
 
  private:
   DeviceMotionEvent();
+  DeviceMotionEvent(const AtomicString&, const DeviceMotionEventInit&);
   DeviceMotionEvent(const AtomicString& eventType, DeviceMotionData*);
 
   Member<DeviceMotionData> m_deviceMotionData;
diff --git a/third_party/WebKit/Source/modules/device_orientation/DeviceMotionEvent.idl b/third_party/WebKit/Source/modules/device_orientation/DeviceMotionEvent.idl
index 4777863..079cc1dd 100644
--- a/third_party/WebKit/Source/modules/device_orientation/DeviceMotionEvent.idl
+++ b/third_party/WebKit/Source/modules/device_orientation/DeviceMotionEvent.idl
@@ -23,9 +23,9 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-// https://w3c.github.io/deviceorientation/spec-source-orientation.html#devicemotion
+// https://www.w3.org/TR/2016/CR-orientation-event-20160818/#devicemotion
 
-// TODO(foolip): DeviceMotionEvent should have a constructor.
+[Constructor(DOMString type, optional DeviceMotionEventInit eventInitDict)]
 interface DeviceMotionEvent : Event {
     readonly attribute DeviceAcceleration? acceleration;
     readonly attribute DeviceAcceleration? accelerationIncludingGravity;
diff --git a/third_party/WebKit/Source/modules/device_orientation/DeviceMotionEventInit.idl b/third_party/WebKit/Source/modules/device_orientation/DeviceMotionEventInit.idl
new file mode 100644
index 0000000..4f8663c
--- /dev/null
+++ b/third_party/WebKit/Source/modules/device_orientation/DeviceMotionEventInit.idl
@@ -0,0 +1,12 @@
+// Copyright 2017 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.
+
+// https://www.w3.org/TR/2016/CR-orientation-event-20160818/#devicemotion
+
+dictionary DeviceMotionEventInit : EventInit {
+  DeviceAccelerationInit? acceleration;
+  DeviceAccelerationInit? accelerationIncludingGravity;
+  DeviceRotationRateInit? rotationRate;
+  double? interval = null;
+};
diff --git a/third_party/WebKit/Source/modules/device_orientation/DeviceRotationRateInit.idl b/third_party/WebKit/Source/modules/device_orientation/DeviceRotationRateInit.idl
new file mode 100644
index 0000000..00fc4a31
--- /dev/null
+++ b/third_party/WebKit/Source/modules/device_orientation/DeviceRotationRateInit.idl
@@ -0,0 +1,11 @@
+// Copyright 2017 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.
+
+// https://www.w3.org/TR/2016/CR-orientation-event-20160818/#devicemotion
+
+dictionary DeviceRotationRateInit {
+  double? alpha = null;
+  double? beta = null;
+  double? gamma = null;
+};
diff --git a/third_party/WebKit/Source/modules/modules_idl_files.gni b/third_party/WebKit/Source/modules/modules_idl_files.gni
index 94ed5f68..5ed3cbc70 100644
--- a/third_party/WebKit/Source/modules/modules_idl_files.gni
+++ b/third_party/WebKit/Source/modules/modules_idl_files.gni
@@ -405,6 +405,9 @@
                     "credentialmanager/LocallyStoredCredentialData.idl",
                     "credentialmanager/PasswordCredentialData.idl",
                     "device_light/DeviceLightEventInit.idl",
+                    "device_orientation/DeviceAccelerationInit.idl",
+                    "device_orientation/DeviceMotionEventInit.idl",
+                    "device_orientation/DeviceRotationRateInit.idl",
                     "encoding/TextDecodeOptions.idl",
                     "encoding/TextDecoderOptions.idl",
                     "encryptedmedia/MediaEncryptedEventInit.idl",
@@ -706,6 +709,12 @@
   "$blink_modules_output_dir/credentialmanager/PasswordCredentialData.h",
   "$blink_modules_output_dir/device_light/DeviceLightEventInit.cpp",
   "$blink_modules_output_dir/device_light/DeviceLightEventInit.h",
+  "$blink_modules_output_dir/device_orientation/DeviceAccelerationInit.cpp",
+  "$blink_modules_output_dir/device_orientation/DeviceAccelerationInit.h",
+  "$blink_modules_output_dir/device_orientation/DeviceMotionEventInit.cpp",
+  "$blink_modules_output_dir/device_orientation/DeviceMotionEventInit.h",
+  "$blink_modules_output_dir/device_orientation/DeviceRotationRateInit.cpp",
+  "$blink_modules_output_dir/device_orientation/DeviceRotationRateInit.h",
   "$blink_modules_output_dir/encoding/TextDecodeOptions.cpp",
   "$blink_modules_output_dir/encoding/TextDecodeOptions.h",
   "$blink_modules_output_dir/encoding/TextDecoderOptions.cpp",
diff --git a/third_party/WebKit/Source/modules/quota/StorageQuotaCallback.h b/third_party/WebKit/Source/modules/quota/StorageQuotaCallback.h
index c2bdf27..0af81fda 100644
--- a/third_party/WebKit/Source/modules/quota/StorageQuotaCallback.h
+++ b/third_party/WebKit/Source/modules/quota/StorageQuotaCallback.h
@@ -40,7 +40,7 @@
  public:
   virtual ~StorageQuotaCallback() {}
   DEFINE_INLINE_VIRTUAL_TRACE() {}
-  virtual void handleEvent(unsigned long long grantedQuotaInBytes) = 0;
+  virtual void handleEvent(uint64_t grantedQuotaInBytes) = 0;
 };
 
 }  // namespace
diff --git a/third_party/WebKit/Source/modules/quota/StorageUsageCallback.h b/third_party/WebKit/Source/modules/quota/StorageUsageCallback.h
index 46265e53..e2a25c3c 100644
--- a/third_party/WebKit/Source/modules/quota/StorageUsageCallback.h
+++ b/third_party/WebKit/Source/modules/quota/StorageUsageCallback.h
@@ -40,8 +40,8 @@
  public:
   virtual ~StorageUsageCallback() {}
   DEFINE_INLINE_VIRTUAL_TRACE() {}
-  virtual void handleEvent(unsigned long long currentUsageInBytes,
-                           unsigned long long currentQuotaInBytes) = 0;
+  virtual void handleEvent(uint64_t currentUsageInBytes,
+                           uint64_t currentQuotaInBytes) = 0;
 };
 
 }  // namespace
diff --git a/third_party/WebKit/Source/platform/FrameViewBase.cpp b/third_party/WebKit/Source/platform/FrameViewBase.cpp
index b48054ff..b1c9347 100644
--- a/third_party/WebKit/Source/platform/FrameViewBase.cpp
+++ b/third_party/WebKit/Source/platform/FrameViewBase.cpp
@@ -62,14 +62,14 @@
   if (const FrameViewBase* parentFrameViewBase = parent()) {
     IntRect parentRect =
         parentFrameViewBase->convertFromRootFrame(rectInRootFrame);
-    return convertFromContainingWidget(parentRect);
+    return convertFromContainingFrameViewBase(parentRect);
   }
   return rectInRootFrame;
 }
 
 IntRect FrameViewBase::convertToRootFrame(const IntRect& localRect) const {
   if (const FrameViewBase* parentFrameViewBase = parent()) {
-    IntRect parentRect = convertToContainingWidget(localRect);
+    IntRect parentRect = convertToContainingFrameViewBase(localRect);
     return parentFrameViewBase->convertToRootFrame(parentRect);
   }
   return localRect;
@@ -80,7 +80,7 @@
   if (const FrameViewBase* parentFrameViewBase = parent()) {
     IntPoint parentPoint =
         parentFrameViewBase->convertFromRootFrame(pointInRootFrame);
-    return convertFromContainingWidget(parentPoint);
+    return convertFromContainingFrameViewBase(parentPoint);
   }
   return pointInRootFrame;
 }
@@ -108,13 +108,13 @@
 
 IntPoint FrameViewBase::convertToRootFrame(const IntPoint& localPoint) const {
   if (const FrameViewBase* parentFrameViewBase = parent()) {
-    IntPoint parentPoint = convertToContainingWidget(localPoint);
+    IntPoint parentPoint = convertToContainingFrameViewBase(localPoint);
     return parentFrameViewBase->convertToRootFrame(parentPoint);
   }
   return localPoint;
 }
 
-IntRect FrameViewBase::convertToContainingWidget(
+IntRect FrameViewBase::convertToContainingFrameViewBase(
     const IntRect& localRect) const {
   if (const FrameViewBase* parentFrameViewBase = parent()) {
     IntRect parentRect(localRect);
@@ -125,7 +125,7 @@
   return localRect;
 }
 
-IntRect FrameViewBase::convertFromContainingWidget(
+IntRect FrameViewBase::convertFromContainingFrameViewBase(
     const IntRect& parentRect) const {
   if (const FrameViewBase* parentFrameViewBase = parent()) {
     IntRect localRect = parentRect;
@@ -137,7 +137,7 @@
   return parentRect;
 }
 
-IntPoint FrameViewBase::convertToContainingWidget(
+IntPoint FrameViewBase::convertToContainingFrameViewBase(
     const IntPoint& localPoint) const {
   if (const FrameViewBase* parentFrameViewBase = parent())
     return parentFrameViewBase->convertChildToSelf(this, localPoint);
@@ -145,7 +145,7 @@
   return localPoint;
 }
 
-IntPoint FrameViewBase::convertFromContainingWidget(
+IntPoint FrameViewBase::convertFromContainingFrameViewBase(
     const IntPoint& parentPoint) const {
   if (const FrameViewBase* parentFrameViewBase = parent())
     return parentFrameViewBase->convertSelfToChild(this, parentPoint);
diff --git a/third_party/WebKit/Source/platform/FrameViewBase.h b/third_party/WebKit/Source/platform/FrameViewBase.h
index 6692b28..cc66a10 100644
--- a/third_party/WebKit/Source/platform/FrameViewBase.h
+++ b/third_party/WebKit/Source/platform/FrameViewBase.h
@@ -112,10 +112,10 @@
 
   virtual void widgetGeometryMayHaveChanged() {}
 
-  virtual IntRect convertToContainingWidget(const IntRect&) const;
-  virtual IntRect convertFromContainingWidget(const IntRect&) const;
-  virtual IntPoint convertToContainingWidget(const IntPoint&) const;
-  virtual IntPoint convertFromContainingWidget(const IntPoint&) const;
+  virtual IntRect convertToContainingFrameViewBase(const IntRect&) const;
+  virtual IntRect convertFromContainingFrameViewBase(const IntRect&) const;
+  virtual IntPoint convertToContainingFrameViewBase(const IntPoint&) const;
+  virtual IntPoint convertFromContainingFrameViewBase(const IntPoint&) const;
 
   // Virtual methods to convert points to/from child frameviewbases.
   virtual IntPoint convertChildToSelf(const FrameViewBase*,
diff --git a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5 b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5
index ec378cd..1022cc5 100644
--- a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5
+++ b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5
@@ -1025,6 +1025,10 @@
     {
       name: "BlockLegacySubresources",
       status: "experimental",
+    },
+    {
+      name: "MediaControlsOverlayPlayButton",
+      settable_from_internals: true,
     }
   ],
 }
diff --git a/third_party/WebKit/Source/platform/audio/PushPullFIFO.cpp b/third_party/WebKit/Source/platform/audio/PushPullFIFO.cpp
index ad3e90a..0435515c 100644
--- a/third_party/WebKit/Source/platform/audio/PushPullFIFO.cpp
+++ b/third_party/WebKit/Source/platform/audio/PushPullFIFO.cpp
@@ -85,11 +85,25 @@
 void PushPullFIFO::pull(AudioBus* outputBus, size_t framesRequested) {
 #if OS(ANDROID)
   if (!outputBus) {
-    // Log when outputBus is invalid. (crbug.com/692423)
-    LOG(WARNING) << "[WebAudio/PushPullFIFO::pull] |outputBus| is invalid.";
+    // Log when outputBus or FIFO object is invalid. (crbug.com/692423)
+    LOG(WARNING) << "[WebAudio/PushPullFIFO::pull <" << (void*)this << ">] "
+                 << "|outputBus| is invalid.";
     // Silently return to avoid crash.
     return;
   }
+
+  // The following checks are in place to catch the inexplicable crash.
+  // (crbug.com/692423)
+  if (framesRequested > m_fifoLength) {
+    LOG(WARNING) << "[WebAudio/PushPullFIFO::pull <" << (void*)this << ">] "
+                 << "framesRequested > m_fifoLength (" << framesRequested
+                 << " > " << m_fifoLength << ")";
+  }
+  if (m_indexRead >= m_fifoLength) {
+    LOG(WARNING) << "[WebAudio/PushPullFIFO::pull <" << (void*)this << ">] "
+                 << "m_indexRead >= m_fifoLength (" << m_indexRead
+                 << " >= " << m_fifoLength << ")";
+  }
 #endif
   CHECK(outputBus);
   SECURITY_CHECK(framesRequested <= outputBus->length());
diff --git a/third_party/WebKit/Source/platform/fonts/Font.cpp b/third_party/WebKit/Source/platform/fonts/Font.cpp
index 1f4cc61b..e858b675 100644
--- a/third_party/WebKit/Source/platform/fonts/Font.cpp
+++ b/third_party/WebKit/Source/platform/fonts/Font.cpp
@@ -203,11 +203,7 @@
 
   FontCachePurgePreventer purgePreventer;
 
-  GlyphData emphasisGlyphData;
-  if (!getEmphasisMarkGlyphData(mark, emphasisGlyphData))
-    return;
-
-  ASSERT(emphasisGlyphData.fontData);
+  const auto emphasisGlyphData = getEmphasisMarkGlyphData(mark);
   if (!emphasisGlyphData.fontData)
     return;
 
@@ -491,36 +487,19 @@
                                       fallbackPriority);
 }
 
-bool Font::getEmphasisMarkGlyphData(const AtomicString& mark,
-                                    GlyphData& glyphData) const {
+GlyphData Font::getEmphasisMarkGlyphData(const AtomicString& mark) const {
   if (mark.isEmpty())
-    return false;
+    return GlyphData();
 
   TextRun emphasisMarkRun(mark, mark.length());
-  TextRunPaintInfo emphasisPaintInfo(emphasisMarkRun);
-  GlyphBuffer glyphBuffer;
-  buildGlyphBuffer(emphasisPaintInfo, glyphBuffer);
-
-  if (glyphBuffer.isEmpty())
-    return false;
-
-  ASSERT(glyphBuffer.fontDataAt(0));
-  glyphData.fontData =
-      glyphBuffer.fontDataAt(0)->emphasisMarkFontData(m_fontDescription).get();
-  glyphData.glyph = glyphBuffer.glyphAt(0);
-
-  return true;
+  return CachingWordShaper(*this).emphasisMarkGlyphData(emphasisMarkRun);
 }
 
 int Font::emphasisMarkAscent(const AtomicString& mark) const {
   FontCachePurgePreventer purgePreventer;
 
-  GlyphData markGlyphData;
-  if (!getEmphasisMarkGlyphData(mark, markGlyphData))
-    return 0;
-
+  const auto markGlyphData = getEmphasisMarkGlyphData(mark);
   const SimpleFontData* markFontData = markGlyphData.fontData;
-  ASSERT(markFontData);
   if (!markFontData)
     return 0;
 
@@ -530,12 +509,8 @@
 int Font::emphasisMarkDescent(const AtomicString& mark) const {
   FontCachePurgePreventer purgePreventer;
 
-  GlyphData markGlyphData;
-  if (!getEmphasisMarkGlyphData(mark, markGlyphData))
-    return 0;
-
+  const auto markGlyphData = getEmphasisMarkGlyphData(mark);
   const SimpleFontData* markFontData = markGlyphData.fontData;
-  ASSERT(markFontData);
   if (!markFontData)
     return 0;
 
@@ -545,12 +520,8 @@
 int Font::emphasisMarkHeight(const AtomicString& mark) const {
   FontCachePurgePreventer purgePreventer;
 
-  GlyphData markGlyphData;
-  if (!getEmphasisMarkGlyphData(mark, markGlyphData))
-    return 0;
-
+  const auto markGlyphData = getEmphasisMarkGlyphData(mark);
   const SimpleFontData* markFontData = markGlyphData.fontData;
-  ASSERT(markFontData);
   if (!markFontData)
     return 0;
 
diff --git a/third_party/WebKit/Source/platform/fonts/Font.h b/third_party/WebKit/Source/platform/fonts/Font.h
index 6afe042..88b85de 100644
--- a/third_party/WebKit/Source/platform/fonts/Font.h
+++ b/third_party/WebKit/Source/platform/fonts/Font.h
@@ -182,7 +182,7 @@
                        const FloatPoint&,
                        float deviceScaleFactor) const;
 
-  bool getEmphasisMarkGlyphData(const AtomicString&, GlyphData&) const;
+  GlyphData getEmphasisMarkGlyphData(const AtomicString&) const;
 
   bool computeCanShapeWordByWord() const;
 
diff --git a/third_party/WebKit/Source/platform/fonts/FontCache.cpp b/third_party/WebKit/Source/platform/fonts/FontCache.cpp
index 63a9561..b894172 100644
--- a/third_party/WebKit/Source/platform/fonts/FontCache.cpp
+++ b/third_party/WebKit/Source/platform/fonts/FontCache.cpp
@@ -472,7 +472,9 @@
       numFamilies = fontMgr->countFamilies();
   }
 
-  debug::alias(&fontDescription);
+  FontDescription fontDescriptionCopy = *fontDescription;
+  debug::alias(&fontDescriptionCopy);
+
   debug::alias(&fontCache);
   debug::alias(&fontMgr);
   debug::alias(&numFamilies);
diff --git a/third_party/WebKit/Source/platform/fonts/SimpleFontData.h b/third_party/WebKit/Source/platform/fonts/SimpleFontData.h
index 73f6a3e..3594351 100644
--- a/third_party/WebKit/Source/platform/fonts/SimpleFontData.h
+++ b/third_party/WebKit/Source/platform/fonts/SimpleFontData.h
@@ -48,7 +48,8 @@
 // given
 // character.
 struct GlyphData {
-  GlyphData(Glyph g = 0, const SimpleFontData* f = 0) : glyph(g), fontData(f) {}
+  GlyphData(Glyph g = 0, const SimpleFontData* f = nullptr)
+      : glyph(g), fontData(f) {}
   Glyph glyph;
   const SimpleFontData* fontData;
 };
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/CachingWordShaper.cpp b/third_party/WebKit/Source/platform/fonts/shaping/CachingWordShaper.cpp
index f6ab60ad..1a0ddd1 100644
--- a/third_party/WebKit/Source/platform/fonts/shaping/CachingWordShaper.cpp
+++ b/third_party/WebKit/Source/platform/fonts/shaping/CachingWordShaper.cpp
@@ -146,4 +146,12 @@
   return buffer.runFontData();
 }
 
+GlyphData CachingWordShaper::emphasisMarkGlyphData(
+    const TextRun& emphasisMarkRun) const {
+  ShapeResultBuffer buffer;
+  shapeResultsForRun(shapeCache(), &m_font, emphasisMarkRun, &buffer);
+
+  return buffer.emphasisMarkGlyphData(m_font.m_fontDescription);
+}
+
 };  // namespace blink
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/CachingWordShaper.h b/third_party/WebKit/Source/platform/fonts/shaping/CachingWordShaper.h
index bf17fa12..30dce35 100644
--- a/third_party/WebKit/Source/platform/fonts/shaping/CachingWordShaper.h
+++ b/third_party/WebKit/Source/platform/fonts/shaping/CachingWordShaper.h
@@ -32,7 +32,6 @@
 #include "wtf/Allocator.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/Vector.h"
-#include <tuple>
 
 namespace blink {
 
@@ -73,6 +72,8 @@
 
   Vector<ShapeResultBuffer::RunFontData> runFontData(const TextRun&) const;
 
+  GlyphData emphasisMarkGlyphData(const TextRun&) const;
+
  private:
   ShapeCache* shapeCache() const;
 
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/ShapeResultBuffer.cpp b/third_party/WebKit/Source/platform/fonts/shaping/ShapeResultBuffer.cpp
index a093da6..7eec345a 100644
--- a/third_party/WebKit/Source/platform/fonts/shaping/ShapeResultBuffer.cpp
+++ b/third_party/WebKit/Source/platform/fonts/shaping/ShapeResultBuffer.cpp
@@ -497,4 +497,21 @@
   return fontData;
 }
 
+GlyphData ShapeResultBuffer::emphasisMarkGlyphData(
+    const FontDescription& fontDescription) const {
+  for (const auto& result : m_results) {
+    for (const auto& run : result->m_runs) {
+      DCHECK(run->m_fontData);
+      if (run->m_glyphData.isEmpty())
+        continue;
+
+      return GlyphData(
+          run->m_glyphData[0].glyph,
+          run->m_fontData->emphasisMarkFontData(fontDescription).get());
+    }
+  }
+
+  return GlyphData();
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/ShapeResultBuffer.h b/third_party/WebKit/Source/platform/fonts/shaping/ShapeResultBuffer.h
index fb94c45..7a99ead 100644
--- a/third_party/WebKit/Source/platform/fonts/shaping/ShapeResultBuffer.h
+++ b/third_party/WebKit/Source/platform/fonts/shaping/ShapeResultBuffer.h
@@ -15,6 +15,7 @@
 namespace blink {
 
 struct CharacterRange;
+class FontDescription;
 class GlyphBuffer;
 struct GlyphData;
 class TextRun;
@@ -65,6 +66,8 @@
 
   Vector<RunFontData> runFontData() const;
 
+  GlyphData emphasisMarkGlyphData(const FontDescription&) const;
+
  private:
   static CharacterRange getCharacterRangeInternal(
       const Vector<RefPtr<const ShapeResult>, 64>&,
diff --git a/third_party/WebKit/Source/platform/geometry/FloatQuad.cpp b/third_party/WebKit/Source/platform/geometry/FloatQuad.cpp
index 7fd3481..0a1c2b9 100644
--- a/third_party/WebKit/Source/platform/geometry/FloatQuad.cpp
+++ b/third_party/WebKit/Source/platform/geometry/FloatQuad.cpp
@@ -82,7 +82,7 @@
 static inline float saturateInf(float value) {
   if (UNLIKELY(std::isinf(value))) {
     return std::signbit(value) ? std::numeric_limits<int>::min()
-                               : std::numeric_limits<int>::min();
+                               : std::numeric_limits<int>::max();
   }
   return value;
 }
diff --git a/third_party/WebKit/Source/platform/geometry/FloatQuadTest.cpp b/third_party/WebKit/Source/platform/geometry/FloatQuadTest.cpp
index 9f918c8..d9cd465 100644
--- a/third_party/WebKit/Source/platform/geometry/FloatQuadTest.cpp
+++ b/third_party/WebKit/Source/platform/geometry/FloatQuadTest.cpp
@@ -4,6 +4,7 @@
 
 #include "platform/geometry/FloatQuad.h"
 
+#include <limits>
 #include "testing/gtest/include/gtest/gtest.h"
 #include "wtf/text/WTFString.h"
 
@@ -15,4 +16,24 @@
   EXPECT_EQ("2,3; 5,7; 11,13; 17,19", quad.toString());
 }
 
+TEST(FloatQuadTest, BoundingBox) {
+  FloatQuad quad(FloatPoint(2, 3), FloatPoint(5, 7), FloatPoint(11, 13),
+                 FloatPoint(17, 19));
+  FloatRect rect = quad.boundingBox();
+  EXPECT_EQ(rect.x(), 2);
+  EXPECT_EQ(rect.y(), 3);
+  EXPECT_EQ(rect.width(), 17 - 2);
+  EXPECT_EQ(rect.height(), 19 - 3);
+}
+
+TEST(FloatQuadTest, BoundingBoxSaturateInf) {
+  double inf = std::numeric_limits<double>::infinity();
+  FloatQuad quad(FloatPoint(-inf, 3), FloatPoint(5, inf), FloatPoint(11, 13),
+                 FloatPoint(17, 19));
+  FloatRect rect = quad.boundingBox();
+  EXPECT_EQ(rect.x(), std::numeric_limits<int>::min());
+  EXPECT_EQ(rect.y(), 3.0f);
+  EXPECT_EQ(rect.width(), 17.0f - std::numeric_limits<int>::min());
+  EXPECT_EQ(rect.height(), std::numeric_limits<int>::max() - 3.0f);
+}
 }  // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsContext.cpp b/third_party/WebKit/Source/platform/graphics/GraphicsContext.cpp
index 6b8397a..cb688e1 100644
--- a/third_party/WebKit/Source/platform/graphics/GraphicsContext.cpp
+++ b/third_party/WebKit/Source/platform/graphics/GraphicsContext.cpp
@@ -501,9 +501,9 @@
   int length = SkScalarRoundToInt(disp.width() + disp.height());
   PaintFlags flags(immutableState()->strokeFlags(length));
 
-  if (getStrokeStyle() == DottedStroke || getStrokeStyle() == DashedStroke) {
+  if (StrokeData::strokeIsDashed(width, getStrokeStyle())) {
     // Do a rect fill of our endpoints.  This ensures we always have the
-    // appearance of being a border.  We then draw the actual dotted/dashed
+    // appearance of being a border. We then draw the actual dotted/dashed
     // line.
     SkRect r1, r2;
     r1.set(p1.x(), p1.y(), p1.x() + width, p1.y() + width);
@@ -520,6 +520,17 @@
     fillFlags.setColor(flags.getColor());
     drawRect(r1, fillFlags);
     drawRect(r2, fillFlags);
+  } else if (getStrokeStyle() == DottedStroke) {
+    // We draw thick dotted lines with 0 length dash strokes and round endcaps,
+    // producing circles. The endcaps extend beyond the line's endpoints,
+    // so move the start and end in.
+    if (isVerticalLine) {
+      p1.setY(p1.y() + width / 2.f);
+      p2.setY(p2.y() - width / 2.f);
+    } else {
+      p1.setX(p1.x() + width / 2.f);
+      p2.setX(p2.x() - width / 2.f);
+    }
   }
 
   adjustLineToPixelBoundaries(p1, p2, width, penStyle);
@@ -1298,7 +1309,7 @@
   // pass us (y1+y2)/2, e.g., (50+53)/2 = 103/2 = 51 when we want 51.5.  It is
   // always true that an even width gave us a perfect position, but an odd width
   // gave us a position that is off by exactly 0.5.
-  if (penStyle == DottedStroke || penStyle == DashedStroke) {
+  if (StrokeData::strokeIsDashed(strokeWidth, penStyle)) {
     if (p1.x() == p2.x()) {
       p1.setY(p1.y() + strokeWidth);
       p2.setY(p2.y() - strokeWidth);
diff --git a/third_party/WebKit/Source/platform/graphics/StrokeData.cpp b/third_party/WebKit/Source/platform/graphics/StrokeData.cpp
index 2bd0a51..cbdb47b 100644
--- a/third_party/WebKit/Source/platform/graphics/StrokeData.cpp
+++ b/third_party/WebKit/Source/platform/graphics/StrokeData.cpp
@@ -70,7 +70,7 @@
 void StrokeData::setupPaintDashPathEffect(PaintFlags* flags, int length) const {
   if (m_dash) {
     flags->setPathEffect(m_dash);
-  } else if (m_style == DashedStroke || m_style == DottedStroke) {
+  } else if (strokeIsDashed(m_thickness, m_style)) {
     float width =
         m_style == DashedStroke ? dashRatio * m_thickness : m_thickness;
 
@@ -96,10 +96,39 @@
     SkScalar intervals[2] = {dashLengthSk, dashLengthSk};
     flags->setPathEffect(
         SkDashPathEffect::Make(intervals, 2, SkIntToScalar(phase)));
+  } else if (m_style == DottedStroke) {
+    flags->setStrokeCap((PaintFlags::Cap)RoundCap);
+    // Adjust the width to get equal dot spacing as much as possible.
+    float perDotLength = m_thickness * 2;
+    static float epsilon = 1.0e-2f;
+    if (length < perDotLength + m_thickness) {
+      // Exactly 2 dots with whatever space we can get
+      SkScalar intervals[2] = {0, length - m_thickness - epsilon};
+      flags->setPathEffect(SkDashPathEffect::Make(intervals, 2, 0));
+      return;
+    }
+
+    // Determine what number of dots gives the minimum deviation from
+    // idealGap between dots. Set the gap to that width.
+    float minNumDots = floorf((length + m_thickness) / perDotLength);
+    float maxNumDots = minNumDots + 1;
+    float minGap = (length - minNumDots * m_thickness) / (minNumDots - 1);
+    float maxGap = (length - maxNumDots * m_thickness) / (maxNumDots - 1);
+    if (fabs(minGap - m_thickness) < fabs(maxGap - m_thickness)) {
+      SkScalar intervals[2] = {0, minGap + m_thickness - epsilon};
+      flags->setPathEffect(SkDashPathEffect::Make(intervals, 2, 0));
+    } else {
+      SkScalar intervals[2] = {0, maxGap + m_thickness - epsilon};
+      flags->setPathEffect(SkDashPathEffect::Make(intervals, 2, 0));
+    }
   } else {
-    // TODO(schenney): WavyStroke:  https://crbug.com/229574
+    // TODO(schenney): WavyStroke https://crbug.com/229574
     flags->setPathEffect(0);
   }
 }
 
+bool StrokeData::strokeIsDashed(float width, StrokeStyle style) {
+  return style == DashedStroke || (style == DottedStroke && width <= 3);
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/StrokeData.h b/third_party/WebKit/Source/platform/graphics/StrokeData.h
index 6bad59cad..f39dffc 100644
--- a/third_party/WebKit/Source/platform/graphics/StrokeData.h
+++ b/third_party/WebKit/Source/platform/graphics/StrokeData.h
@@ -82,6 +82,11 @@
   // line will be adjusted to start and end that length with a dash/dot.
   void setupPaintDashPathEffect(PaintFlags*, int) const;
 
+  // Determine whether a stroked line should be drawn using dashes. In practice,
+  // we draw dashes when a dashed stroke is specified or when a dotted stroke
+  // is specified but the line width is too small to draw circles.
+  static bool strokeIsDashed(float width, StrokeStyle);
+
  private:
   StrokeStyle m_style;
   float m_thickness;
diff --git a/third_party/WebKit/Source/platform/mac/ScrollAnimatorMac.mm b/third_party/WebKit/Source/platform/mac/ScrollAnimatorMac.mm
index ff066d61..7313cccb 100644
--- a/third_party/WebKit/Source/platform/mac/ScrollAnimatorMac.mm
+++ b/third_party/WebKit/Source/platform/mac/ScrollAnimatorMac.mm
@@ -235,7 +235,7 @@
 
   ASSERT(scrollerImp == scrollbarPainterForScrollbar(*scrollbar));
 
-  return scrollbar->convertFromContainingWidget(
+  return scrollbar->convertFromContainingFrameViewBase(
       blink::IntPoint(pointInContentArea));
 }
 
@@ -493,7 +493,7 @@
 
   DCHECK_EQ(scrollerImp, scrollbarPainterForScrollbar(*_scrollbar));
 
-  return _scrollbar->convertFromContainingWidget(
+  return _scrollbar->convertFromContainingFrameViewBase(
       _scrollbar->getScrollableArea()->lastKnownMousePosition());
 }
 
@@ -1072,7 +1072,7 @@
   IntRect rectInViewCoordinates = scrollerThumb;
   if (Scrollbar* verticalScrollbar = m_scrollableArea->verticalScrollbar())
     rectInViewCoordinates =
-        verticalScrollbar->convertToContainingWidget(scrollerThumb);
+        verticalScrollbar->convertToContainingFrameViewBase(scrollerThumb);
 
   if (rectInViewCoordinates == m_visibleScrollerThumbRect)
     return;
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollableArea.cpp b/third_party/WebKit/Source/platform/scroll/ScrollableArea.cpp
index b0a03cd..9beeba9 100644
--- a/third_party/WebKit/Source/platform/scroll/ScrollableArea.cpp
+++ b/third_party/WebKit/Source/platform/scroll/ScrollableArea.cpp
@@ -486,7 +486,7 @@
 
 bool ScrollableArea::scheduleAnimation() {
   if (HostWindow* window = getHostWindow()) {
-    window->scheduleAnimation(getWidget());
+    window->scheduleAnimation(getFrameViewBase());
     return true;
   }
   return false;
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollableArea.h b/third_party/WebKit/Source/platform/scroll/ScrollableArea.h
index 6c5a924..5c74eff 100644
--- a/third_party/WebKit/Source/platform/scroll/ScrollableArea.h
+++ b/third_party/WebKit/Source/platform/scroll/ScrollableArea.h
@@ -184,25 +184,29 @@
   // Convert points and rects between the scrollbar and its containing
   // FrameViewBase. The client needs to implement these in order to be aware of
   // layout effects like CSS transforms.
-  virtual IntRect convertFromScrollbarToContainingWidget(
+  virtual IntRect convertFromScrollbarToContainingFrameViewBase(
       const Scrollbar& scrollbar,
       const IntRect& scrollbarRect) const {
-    return scrollbar.FrameViewBase::convertToContainingWidget(scrollbarRect);
+    return scrollbar.FrameViewBase::convertToContainingFrameViewBase(
+        scrollbarRect);
   }
-  virtual IntRect convertFromContainingWidgetToScrollbar(
+  virtual IntRect convertFromContainingFrameViewBaseToScrollbar(
       const Scrollbar& scrollbar,
       const IntRect& parentRect) const {
-    return scrollbar.FrameViewBase::convertFromContainingWidget(parentRect);
+    return scrollbar.FrameViewBase::convertFromContainingFrameViewBase(
+        parentRect);
   }
-  virtual IntPoint convertFromScrollbarToContainingWidget(
+  virtual IntPoint convertFromScrollbarToContainingFrameViewBase(
       const Scrollbar& scrollbar,
       const IntPoint& scrollbarPoint) const {
-    return scrollbar.FrameViewBase::convertToContainingWidget(scrollbarPoint);
+    return scrollbar.FrameViewBase::convertToContainingFrameViewBase(
+        scrollbarPoint);
   }
-  virtual IntPoint convertFromContainingWidgetToScrollbar(
+  virtual IntPoint convertFromContainingFrameViewBaseToScrollbar(
       const Scrollbar& scrollbar,
       const IntPoint& parentPoint) const {
-    return scrollbar.FrameViewBase::convertFromContainingWidget(parentPoint);
+    return scrollbar.FrameViewBase::convertFromContainingFrameViewBase(
+        parentPoint);
   }
 
   virtual Scrollbar* horizontalScrollbar() const { return nullptr; }
@@ -336,7 +340,7 @@
       OverlayScrollbarClipBehavior = IgnoreOverlayScrollbarSize) const;
 
   // Returns the widget associated with this ScrollableArea.
-  virtual FrameViewBase* getWidget() { return nullptr; }
+  virtual FrameViewBase* getFrameViewBase() { return nullptr; }
 
   virtual LayoutBox* layoutBox() const { return nullptr; }
 
diff --git a/third_party/WebKit/Source/platform/scroll/Scrollbar.cpp b/third_party/WebKit/Source/platform/scroll/Scrollbar.cpp
index b3ec4ef..a3dba61d 100644
--- a/third_party/WebKit/Source/platform/scroll/Scrollbar.cpp
+++ b/third_party/WebKit/Source/platform/scroll/Scrollbar.cpp
@@ -570,39 +570,44 @@
   return m_scrollableArea && m_scrollableArea->isActive();
 }
 
-IntRect Scrollbar::convertToContainingWidget(const IntRect& localRect) const {
-  if (m_scrollableArea)
-    return m_scrollableArea->convertFromScrollbarToContainingWidget(*this,
-                                                                    localRect);
+IntRect Scrollbar::convertToContainingFrameViewBase(
+    const IntRect& localRect) const {
+  if (m_scrollableArea) {
+    return m_scrollableArea->convertFromScrollbarToContainingFrameViewBase(
+        *this, localRect);
+  }
 
-  return FrameViewBase::convertToContainingWidget(localRect);
+  return FrameViewBase::convertToContainingFrameViewBase(localRect);
 }
 
-IntRect Scrollbar::convertFromContainingWidget(
+IntRect Scrollbar::convertFromContainingFrameViewBase(
     const IntRect& parentRect) const {
-  if (m_scrollableArea)
-    return m_scrollableArea->convertFromContainingWidgetToScrollbar(*this,
-                                                                    parentRect);
+  if (m_scrollableArea) {
+    return m_scrollableArea->convertFromContainingFrameViewBaseToScrollbar(
+        *this, parentRect);
+  }
 
-  return FrameViewBase::convertFromContainingWidget(parentRect);
+  return FrameViewBase::convertFromContainingFrameViewBase(parentRect);
 }
 
-IntPoint Scrollbar::convertToContainingWidget(
+IntPoint Scrollbar::convertToContainingFrameViewBase(
     const IntPoint& localPoint) const {
-  if (m_scrollableArea)
-    return m_scrollableArea->convertFromScrollbarToContainingWidget(*this,
-                                                                    localPoint);
+  if (m_scrollableArea) {
+    return m_scrollableArea->convertFromScrollbarToContainingFrameViewBase(
+        *this, localPoint);
+  }
 
-  return FrameViewBase::convertToContainingWidget(localPoint);
+  return FrameViewBase::convertToContainingFrameViewBase(localPoint);
 }
 
-IntPoint Scrollbar::convertFromContainingWidget(
+IntPoint Scrollbar::convertFromContainingFrameViewBase(
     const IntPoint& parentPoint) const {
-  if (m_scrollableArea)
-    return m_scrollableArea->convertFromContainingWidgetToScrollbar(
+  if (m_scrollableArea) {
+    return m_scrollableArea->convertFromContainingFrameViewBaseToScrollbar(
         *this, parentPoint);
+  }
 
-  return FrameViewBase::convertFromContainingWidget(parentPoint);
+  return FrameViewBase::convertFromContainingFrameViewBase(parentPoint);
 }
 
 float Scrollbar::scrollableAreaCurrentPos() const {
diff --git a/third_party/WebKit/Source/platform/scroll/Scrollbar.h b/third_party/WebKit/Source/platform/scroll/Scrollbar.h
index 8a1f8d6..b465474 100644
--- a/third_party/WebKit/Source/platform/scroll/Scrollbar.h
+++ b/third_party/WebKit/Source/platform/scroll/Scrollbar.h
@@ -156,11 +156,11 @@
 
   ScrollbarTheme& theme() const { return m_theme; }
 
-  IntRect convertToContainingWidget(const IntRect&) const override;
-  IntRect convertFromContainingWidget(const IntRect&) const override;
+  IntRect convertToContainingFrameViewBase(const IntRect&) const override;
+  IntRect convertFromContainingFrameViewBase(const IntRect&) const override;
 
-  IntPoint convertToContainingWidget(const IntPoint&) const override;
-  IntPoint convertFromContainingWidget(const IntPoint&) const override;
+  IntPoint convertToContainingFrameViewBase(const IntPoint&) const override;
+  IntPoint convertFromContainingFrameViewBase(const IntPoint&) const override;
 
   void moveThumb(int pos, bool draggingDocument = false);
 
diff --git a/third_party/WebKit/Source/web/WebDevToolsFrontendImpl.cpp b/third_party/WebKit/Source/web/WebDevToolsFrontendImpl.cpp
index f7470bd..2c841279 100644
--- a/third_party/WebKit/Source/web/WebDevToolsFrontendImpl.cpp
+++ b/third_party/WebKit/Source/web/WebDevToolsFrontendImpl.cpp
@@ -32,9 +32,9 @@
 
 #include "bindings/core/v8/ScriptController.h"
 #include "bindings/core/v8/V8DevToolsHost.h"
-#include "core/frame/FrameHost.h"
 #include "core/frame/LocalFrame.h"
 #include "core/inspector/DevToolsHost.h"
+#include "core/page/Page.h"
 #include "public/platform/WebSecurityOrigin.h"
 #include "public/platform/WebString.h"
 #include "public/web/WebDevToolsFrontendClient.h"
@@ -54,7 +54,7 @@
     WebDevToolsFrontendClient* client)
     : m_webFrame(webFrame), m_client(client) {
   m_webFrame->setDevToolsFrontend(this);
-  m_webFrame->frame()->host()->setDefaultPageScaleLimits(1.f, 1.f);
+  m_webFrame->frame()->page()->setDefaultPageScaleLimits(1.f, 1.f);
 }
 
 WebDevToolsFrontendImpl::~WebDevToolsFrontendImpl() {
diff --git a/third_party/WebKit/Source/web/WebFrame.cpp b/third_party/WebKit/Source/web/WebFrame.cpp
index 943f738..59df86f0 100644
--- a/third_party/WebKit/Source/web/WebFrame.cpp
+++ b/third_party/WebKit/Source/web/WebFrame.cpp
@@ -15,6 +15,7 @@
 #include "core/page/Page.h"
 #include "platform/UserGestureIndicator.h"
 #include "platform/heap/Handle.h"
+#include "platform/instrumentation/tracing/TraceEvent.h"
 #include "public/web/WebElement.h"
 #include "public/web/WebFrameOwnerProperties.h"
 #include "public/web/WebSandboxFlags.h"
@@ -99,6 +100,10 @@
         toHTMLFrameOwnerElement(owner)->setWidget(localFrame.view());
     } else {
       localFrame.page()->setMainFrame(&localFrame);
+      // This trace event is needed to detect the main frame of the
+      // renderer in telemetry metrics. See crbug.com/692112#c11.
+      TRACE_EVENT_INSTANT1("loading", "markAsMainFrame",
+                           TRACE_EVENT_SCOPE_THREAD, "frame", &localFrame);
     }
   } else {
     toWebRemoteFrameImpl(frame)->initializeCoreFrame(host, owner, name,
diff --git a/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp b/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp
index a95f10f..917372c4 100644
--- a/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp
+++ b/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp
@@ -1612,6 +1612,12 @@
 
     frame()->interfaceRegistry()->addInterface(WTF::bind(
         &InstallationServiceImpl::create, wrapWeakPersistent(frame())));
+    if (!owner) {
+      // This trace event is needed to detect the main frame of the
+      // renderer in telemetry metrics. See crbug.com/692112#c11.
+      TRACE_EVENT_INSTANT1("loading", "markAsMainFrame",
+                           TRACE_EVENT_SCOPE_THREAD, "frame", frame());
+    }
   }
 }
 
diff --git a/third_party/WebKit/Source/web/WebRemoteFrameImpl.cpp b/third_party/WebKit/Source/web/WebRemoteFrameImpl.cpp
index 3fcba55..fc2e921 100644
--- a/third_party/WebKit/Source/web/WebRemoteFrameImpl.cpp
+++ b/third_party/WebKit/Source/web/WebRemoteFrameImpl.cpp
@@ -5,6 +5,7 @@
 #include "web/WebRemoteFrameImpl.h"
 
 #include "bindings/core/v8/RemoteWindowProxy.h"
+#include "bindings/core/v8/V8Window.h"
 #include "core/dom/Fullscreen.h"
 #include "core/dom/RemoteSecurityContext.h"
 #include "core/dom/SecurityContext.h"
@@ -26,6 +27,7 @@
 #include "web/RemoteFrameOwner.h"
 #include "web/WebLocalFrameImpl.h"
 #include "web/WebViewImpl.h"
+#include "wtf/debug/Alias.h"
 
 namespace blink {
 
@@ -215,9 +217,23 @@
 
 v8::Local<v8::Context> WebRemoteFrameImpl::deprecatedMainWorldScriptContext()
     const {
-  return static_cast<RemoteWindowProxy*>(
-             frame()->windowProxy(DOMWrapperWorld::mainWorld()))
-      ->contextIfInitialized();
+  v8::Local<v8::Context> context =
+      static_cast<RemoteWindowProxy*>(
+          frame()->windowProxy(DOMWrapperWorld::mainWorld()))
+          ->contextIfInitialized();
+
+  DOMWindow* window = frame()->domWindow();
+  // Prevent this local from getting optimized out, and hopefully, the heap
+  // contents captured into minidumps.
+  WTF::debug::alias(&window);
+
+  v8::Local<v8::Object> globalProxy = context->Global();
+  CHECK(!globalProxy.IsEmpty());
+  CHECK(V8Window::hasInstance(globalProxy, v8::Isolate::GetCurrent()));
+  CHECK(window);
+  CHECK_EQ(window, V8Window::toImpl(globalProxy));
+
+  return context;
 }
 
 void WebRemoteFrameImpl::reload(WebFrameLoadType) {
diff --git a/third_party/WebKit/Source/web/WebRuntimeFeatures.cpp b/third_party/WebKit/Source/web/WebRuntimeFeatures.cpp
index 8fc301e..501ab3b 100644
--- a/third_party/WebKit/Source/web/WebRuntimeFeatures.cpp
+++ b/third_party/WebKit/Source/web/WebRuntimeFeatures.cpp
@@ -392,4 +392,8 @@
   RuntimeEnabledFeatures::setVideoFullscreenOrientationLockEnabled(enable);
 }
 
+void WebRuntimeFeatures::enableMediaControlsOverlayPlayButton(bool enable) {
+  RuntimeEnabledFeatures::setMediaControlsOverlayPlayButtonEnabled(enable);
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/web/WebSettingsImpl.cpp b/third_party/WebKit/Source/web/WebSettingsImpl.cpp
index ff5ac4d2..30777b980 100644
--- a/third_party/WebKit/Source/web/WebSettingsImpl.cpp
+++ b/third_party/WebKit/Source/web/WebSettingsImpl.cpp
@@ -621,10 +621,6 @@
   m_settings->setShouldRespectImageOrientation(enabled);
 }
 
-void WebSettingsImpl::setMediaControlsOverlayPlayButtonEnabled(bool enabled) {
-  m_settings->setMediaControlsOverlayPlayButtonEnabled(enabled);
-}
-
 void WebSettingsImpl::setMediaPlaybackRequiresUserGesture(bool required) {
   m_settings->setMediaPlaybackRequiresUserGesture(required);
 }
diff --git a/third_party/WebKit/Source/web/WebSettingsImpl.h b/third_party/WebKit/Source/web/WebSettingsImpl.h
index 95178e0..4508d26 100644
--- a/third_party/WebKit/Source/web/WebSettingsImpl.h
+++ b/third_party/WebKit/Source/web/WebSettingsImpl.h
@@ -120,7 +120,6 @@
   void setMainFrameClipsContent(bool) override;
   void setMainFrameResizesAreOrientationChanges(bool) override;
   void setMaxTouchPoints(int) override;
-  void setMediaControlsOverlayPlayButtonEnabled(bool) override;
   void setMediaPlaybackRequiresUserGesture(bool) override;
   void setMediaPlaybackGestureWhitelistScope(const WebString&) override;
   void setPresentationRequiresUserGesture(bool) override;
diff --git a/third_party/WebKit/Source/web/WebViewImpl.cpp b/third_party/WebKit/Source/web/WebViewImpl.cpp
index 8a38208..367265b 100644
--- a/third_party/WebKit/Source/web/WebViewImpl.cpp
+++ b/third_party/WebKit/Source/web/WebViewImpl.cpp
@@ -3043,7 +3043,7 @@
 }
 
 void WebViewImpl::setDefaultPageScaleLimits(float minScale, float maxScale) {
-  return page()->frameHost().setDefaultPageScaleLimits(minScale, maxScale);
+  return page()->setDefaultPageScaleLimits(minScale, maxScale);
 }
 
 void WebViewImpl::setInitialPageScaleOverride(
@@ -3056,7 +3056,7 @@
     return;
 
   pageScaleConstraintsSet().setNeedsReset(true);
-  page()->frameHost().setUserAgentPageScaleConstraints(constraints);
+  page()->setUserAgentPageScaleConstraints(constraints);
 }
 
 void WebViewImpl::setMaximumLegibleScale(float maximumLegibleScale) {
@@ -3075,7 +3075,7 @@
     constraints.minimumScale = -1;
     constraints.maximumScale = -1;
   }
-  page()->frameHost().setUserAgentPageScaleConstraints(constraints);
+  page()->setUserAgentPageScaleConstraints(constraints);
 }
 
 IntSize WebViewImpl::mainFrameSize() {
diff --git a/third_party/WebKit/Source/web/tests/DocumentLoadingRenderingTest.cpp b/third_party/WebKit/Source/web/tests/DocumentLoadingRenderingTest.cpp
index 9fdbe5e..3a7abbe 100644
--- a/third_party/WebKit/Source/web/tests/DocumentLoadingRenderingTest.cpp
+++ b/third_party/WebKit/Source/web/tests/DocumentLoadingRenderingTest.cpp
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "core/dom/ClientRect.h"
 #include "core/dom/Document.h"
 #include "core/dom/FrameRequestCallback.h"
 #include "core/html/HTMLIFrameElement.h"
@@ -380,4 +381,43 @@
   EXPECT_TRUE(document().isRenderingReady());
 }
 
+TEST_F(DocumentLoadingRenderingTest,
+       returnBoundingClientRectCorrectlyWhileLoadingImport) {
+  SimRequest mainResource("https://example.com/test.html", "text/html");
+  SimRequest importResource("https://example.com/import.css", "text/css");
+
+  loadURL("https://example.com/test.html");
+
+  webView().resize(WebSize(800, 600));
+
+  mainResource.start();
+
+  mainResource.write(
+      "<html><body>"
+      "  <div id='test' style='font-size: 16px'>test</div>"
+      "  <script>"
+      "    var link = document.createElement('link');"
+      "    link.rel = 'import';"
+      "    link.href = 'import.css';"
+      "    document.head.appendChild(link);"
+      "  </script>");
+  importResource.start();
+
+  // Import loader isn't finish, shoudn't paint.
+  EXPECT_FALSE(document().isRenderingReady());
+
+  // If ignoringPendingStylesheets==true, element should get non-empty rect.
+  Element* element = document().getElementById("test");
+  ClientRect* rect = element->getBoundingClientRect();
+  EXPECT_TRUE(rect->width() > 0.f);
+  EXPECT_TRUE(rect->height() > 0.f);
+
+  // After reset ignoringPendingStylesheets, we should block rendering again.
+  EXPECT_FALSE(document().isRenderingReady());
+
+  importResource.write("div { color: red; }");
+  importResource.finish();
+  mainResource.finish();
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/wtf/BitVector.h b/third_party/WebKit/Source/wtf/BitVector.h
index 034c33d..dd0b2aa 100644
--- a/third_party/WebKit/Source/wtf/BitVector.h
+++ b/third_party/WebKit/Source/wtf/BitVector.h
@@ -103,19 +103,19 @@
   void clearAll();
 
   bool quickGet(size_t bit) const {
-    SECURITY_DCHECK(bit < size());
+    SECURITY_CHECK(bit < size());
     return !!(bits()[bit / bitsInPointer()] &
               (static_cast<uintptr_t>(1) << (bit & (bitsInPointer() - 1))));
   }
 
   void quickSet(size_t bit) {
-    SECURITY_DCHECK(bit < size());
+    SECURITY_CHECK(bit < size());
     bits()[bit / bitsInPointer()] |=
         (static_cast<uintptr_t>(1) << (bit & (bitsInPointer() - 1)));
   }
 
   void quickClear(size_t bit) {
-    SECURITY_DCHECK(bit < size());
+    SECURITY_CHECK(bit < size());
     bits()[bit / bitsInPointer()] &=
         ~(static_cast<uintptr_t>(1) << (bit & (bitsInPointer() - 1)));
   }
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/baseline_optimizer.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/baseline_optimizer.py
index d67aef8d..09302cb8 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/baseline_optimizer.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/baseline_optimizer.py
@@ -48,9 +48,145 @@
         self._webkit_base = port.webkit_base()
         self._layout_tests_dir = port.layout_tests_dir()
 
-        # Only used by unittests.
+        # Only used by unit tests.
         self.new_results_by_directory = []
 
+    def optimize(self, baseline_name):
+        # The virtual fallback path is the same as the non-virtual one
+        # tacked on to the bottom of the non-virtual path. See
+        # https://docs.google.com/a/chromium.org/drawings/d/1eGdsIKzJ2dxDDBbUaIABrN4aMLD1bqJTfyxNGZsTdmg/edit
+        # for a visual representation of this.
+        # So, we can optimize the virtual path, then the virtual root, and then
+        # the regular path.
+
+        _log.debug("Optimizing regular fallback path.")
+        result = self._optimize_subtree(baseline_name)
+        non_virtual_baseline_name = self._virtual_base(baseline_name)
+        if not non_virtual_baseline_name:
+            return result
+
+        self._optimize_virtual_root(baseline_name, non_virtual_baseline_name)
+
+        _log.debug("Optimizing non-virtual fallback path.")
+        result |= self._optimize_subtree(non_virtual_baseline_name)
+        return result
+
+    def write_by_directory(self, results_by_directory, writer, indent):
+        for path in sorted(results_by_directory):
+            writer("%s%s: %s" % (indent, self._platform(path), results_by_directory[path][0:6]))
+
+    def read_results_by_directory(self, baseline_name):
+        results_by_directory = {}
+        directories = functools.reduce(set.union, map(set, [self._relative_baseline_search_paths(
+            port, baseline_name) for port in self._ports.values()]))
+
+        for directory in directories:
+            path = self._join_directory(directory, baseline_name)
+            if self._filesystem.exists(path):
+                results_by_directory[directory] = self._filesystem.sha1(path)
+        return results_by_directory
+
+    def _optimize_subtree(self, baseline_name):
+        basename = self._filesystem.basename(baseline_name)
+        results_by_directory, new_results_by_directory = self._find_optimal_result_placement(baseline_name)
+
+        if new_results_by_directory == results_by_directory:
+            if new_results_by_directory:
+                _log.debug("  %s: (already optimal)", basename)
+                self.write_by_directory(results_by_directory, _log.debug, "    ")
+            else:
+                _log.debug("  %s: (no baselines found)", basename)
+            # This is just used for unit tests.
+            # Intentionally set it to the old data if we don't modify anything.
+            self.new_results_by_directory.append(results_by_directory)
+            return True
+
+        if (self._results_by_port_name(results_by_directory, baseline_name) !=
+                self._results_by_port_name(new_results_by_directory, baseline_name)):
+            # This really should never happen. Just a sanity check to make
+            # sure the script fails in the case of bugs instead of committing
+            # incorrect baselines.
+            _log.error("  %s: optimization failed", basename)
+            self.write_by_directory(results_by_directory, _log.warning, "      ")
+            return False
+
+        _log.debug("  %s:", basename)
+        _log.debug("    Before: ")
+        self.write_by_directory(results_by_directory, _log.debug, "      ")
+        _log.debug("    After: ")
+        self.write_by_directory(new_results_by_directory, _log.debug, "      ")
+
+        self._move_baselines(baseline_name, results_by_directory, new_results_by_directory)
+        return True
+
+    def _move_baselines(self, baseline_name, results_by_directory, new_results_by_directory):
+        data_for_result = {}
+        for directory, result in results_by_directory.items():
+            if result not in data_for_result:
+                source = self._join_directory(directory, baseline_name)
+                data_for_result[result] = self._filesystem.read_binary_file(source)
+
+        fs_files = []
+        for directory, result in results_by_directory.items():
+            if new_results_by_directory.get(directory) != result:
+                file_name = self._join_directory(directory, baseline_name)
+                if self._filesystem.exists(file_name):
+                    fs_files.append(file_name)
+
+        if fs_files:
+            _log.debug("    Deleting (file system):")
+            for platform_dir in sorted(self._platform(filename) for filename in fs_files):
+                _log.debug("      " + platform_dir)
+            for filename in fs_files:
+                self._filesystem.remove(filename)
+        else:
+            _log.debug("    (Nothing to delete)")
+
+        file_names = []
+        for directory, result in new_results_by_directory.items():
+            if results_by_directory.get(directory) != result:
+                destination = self._join_directory(directory, baseline_name)
+                self._filesystem.maybe_make_directory(self._filesystem.split(destination)[0])
+                self._filesystem.write_binary_file(destination, data_for_result[result])
+                file_names.append(destination)
+
+        if file_names:
+            _log.debug("    Adding:")
+            for platform_dir in sorted(self._platform(filename) for filename in file_names):
+                _log.debug("      " + platform_dir)
+        else:
+            _log.debug("    (Nothing to add)")
+
+    def _platform(self, filename):
+        platform_dir = self.ROOT_LAYOUT_TESTS_DIRECTORY + self._filesystem.sep + 'platform' + self._filesystem.sep
+        if filename.startswith(platform_dir):
+            return filename.replace(platform_dir, '').split(self._filesystem.sep)[0]
+        platform_dir = self._filesystem.join(self._webkit_base, platform_dir)
+        if filename.startswith(platform_dir):
+            return filename.replace(platform_dir, '').split(self._filesystem.sep)[0]
+        return '(generic)'
+
+    def _optimize_virtual_root(self, baseline_name, non_virtual_baseline_name):
+        virtual_root_baseline_path = self._filesystem.join(self._layout_tests_dir, baseline_name)
+        if not self._filesystem.exists(virtual_root_baseline_path):
+            return
+        root_sha1 = self._filesystem.sha1(virtual_root_baseline_path)
+
+        results_by_directory = self.read_results_by_directory(non_virtual_baseline_name)
+        # See if all the immediate predecessors of the virtual root have the same expected result.
+        for port in self._ports.values():
+            directories = self._relative_baseline_search_paths(port, non_virtual_baseline_name)
+            for directory in directories:
+                if directory not in results_by_directory:
+                    continue
+                if results_by_directory[directory] != root_sha1:
+                    return
+                break
+
+        _log.debug("Deleting redundant virtual root expected result.")
+        _log.debug("    Deleting (file system): " + virtual_root_baseline_path)
+        self._filesystem.remove(virtual_root_baseline_path)
+
     def _baseline_root(self, baseline_name):
         virtual_suite = self._virtual_suite(baseline_name)
         if virtual_suite:
@@ -70,17 +206,21 @@
         return self._default_port.lookup_virtual_test_base(baseline_name)
 
     def _relative_baseline_search_paths(self, port, baseline_name):
+        """Returns a list of paths to check for baselines in order."""
         baseline_search_path = self._baseline_search_path(port, baseline_name)
         baseline_root = self._baseline_root(baseline_name)
         relative_paths = [self._filesystem.relpath(path, self._webkit_base) for path in baseline_search_path]
         return relative_paths + [baseline_root]
 
     def _join_directory(self, directory, baseline_name):
-        # This code is complicated because both the directory name and the baseline_name have the virtual
-        # test suite in the name and the virtual baseline name is not a strict superset of the non-virtual name.
-        # For example, virtual/gpu/fast/canvas/foo-expected.png corresponds to fast/canvas/foo-expected.png and
-        # the baseline directories are like platform/mac/virtual/gpu/fast/canvas. So, to get the path
-        # to the baseline in the platform directory, we need to append just foo-expected.png to the directory.
+        # This code is complicated because both the directory name and the
+        # baseline_name have the virtual test suite in the name and the virtual
+        # baseline name is not a strict superset of the non-virtual name.
+        # For example, virtual/gpu/fast/canvas/foo-expected.png corresponds to
+        # fast/canvas/foo-expected.png and the baseline directories are like
+        # platform/mac/virtual/gpu/fast/canvas. So, to get the path to the
+        # baseline in the platform directory, we need to append just
+        # foo-expected.png to the directory.
         virtual_suite = self._virtual_suite(baseline_name)
         if virtual_suite:
             baseline_name_without_virtual = baseline_name[len(virtual_suite.name) + 1:]
@@ -88,16 +228,6 @@
             baseline_name_without_virtual = baseline_name
         return self._filesystem.join(self._webkit_base, directory, baseline_name_without_virtual)
 
-    def read_results_by_directory(self, baseline_name):
-        results_by_directory = {}
-        directories = functools.reduce(set.union, map(set, [self._relative_baseline_search_paths(
-            port, baseline_name) for port in self._ports.values()]))
-
-        for directory in directories:
-            path = self._join_directory(directory, baseline_name)
-            if self._filesystem.exists(path):
-                results_by_directory[directory] = self._filesystem.sha1(path)
-        return results_by_directory
 
     def _results_by_port_name(self, results_by_directory, baseline_name):
         results_by_port_name = {}
@@ -194,124 +324,3 @@
                 return index, directory
         assert False, "result %s not found in fallback_path %s, %s" % (current_result, fallback_path, results_by_directory)
 
-    def _platform(self, filename):
-        platform_dir = self.ROOT_LAYOUT_TESTS_DIRECTORY + self._filesystem.sep + 'platform' + self._filesystem.sep
-        if filename.startswith(platform_dir):
-            return filename.replace(platform_dir, '').split(self._filesystem.sep)[0]
-        platform_dir = self._filesystem.join(self._webkit_base, platform_dir)
-        if filename.startswith(platform_dir):
-            return filename.replace(platform_dir, '').split(self._filesystem.sep)[0]
-        return '(generic)'
-
-    def _move_baselines(self, baseline_name, results_by_directory, new_results_by_directory):
-        data_for_result = {}
-        for directory, result in results_by_directory.items():
-            if result not in data_for_result:
-                source = self._join_directory(directory, baseline_name)
-                data_for_result[result] = self._filesystem.read_binary_file(source)
-
-        fs_files = []
-        for directory, result in results_by_directory.items():
-            if new_results_by_directory.get(directory) != result:
-                file_name = self._join_directory(directory, baseline_name)
-                if self._filesystem.exists(file_name):
-                    fs_files.append(file_name)
-
-        if fs_files:
-            _log.debug("    Deleting (file system):")
-            for platform_dir in sorted(self._platform(filename) for filename in fs_files):
-                _log.debug("      " + platform_dir)
-            for filename in fs_files:
-                self._filesystem.remove(filename)
-        else:
-            _log.debug("    (Nothing to delete)")
-
-        file_names = []
-        for directory, result in new_results_by_directory.items():
-            if results_by_directory.get(directory) != result:
-                destination = self._join_directory(directory, baseline_name)
-                self._filesystem.maybe_make_directory(self._filesystem.split(destination)[0])
-                self._filesystem.write_binary_file(destination, data_for_result[result])
-                file_names.append(destination)
-
-        if file_names:
-            _log.debug("    Adding:")
-            for platform_dir in sorted(self._platform(filename) for filename in file_names):
-                _log.debug("      " + platform_dir)
-        else:
-            _log.debug("    (Nothing to add)")
-
-    def write_by_directory(self, results_by_directory, writer, indent):
-        for path in sorted(results_by_directory):
-            writer("%s%s: %s" % (indent, self._platform(path), results_by_directory[path][0:6]))
-
-    def _optimize_subtree(self, baseline_name):
-        basename = self._filesystem.basename(baseline_name)
-        results_by_directory, new_results_by_directory = self._find_optimal_result_placement(baseline_name)
-
-        if new_results_by_directory == results_by_directory:
-            if new_results_by_directory:
-                _log.debug("  %s: (already optimal)", basename)
-                self.write_by_directory(results_by_directory, _log.debug, "    ")
-            else:
-                _log.debug("  %s: (no baselines found)", basename)
-            # This is just used for unittests. Intentionally set it to the old data if we don't modify anything.
-            self.new_results_by_directory.append(results_by_directory)
-            return True
-
-        if self._results_by_port_name(results_by_directory, baseline_name) != self._results_by_port_name(
-                new_results_by_directory, baseline_name):
-            # This really should never happen. Just a sanity check to make sure the script fails in the case of bugs
-            # instead of committing incorrect baselines.
-            _log.error("  %s: optimization failed", basename)
-            self.write_by_directory(results_by_directory, _log.warning, "      ")
-            return False
-
-        _log.debug("  %s:", basename)
-        _log.debug("    Before: ")
-        self.write_by_directory(results_by_directory, _log.debug, "      ")
-        _log.debug("    After: ")
-        self.write_by_directory(new_results_by_directory, _log.debug, "      ")
-
-        self._move_baselines(baseline_name, results_by_directory, new_results_by_directory)
-        return True
-
-    def _optimize_virtual_root(self, baseline_name, non_virtual_baseline_name):
-        virtual_root_baseline_path = self._filesystem.join(self._layout_tests_dir, baseline_name)
-        if not self._filesystem.exists(virtual_root_baseline_path):
-            return
-        root_sha1 = self._filesystem.sha1(virtual_root_baseline_path)
-
-        results_by_directory = self.read_results_by_directory(non_virtual_baseline_name)
-        # See if all the immediate predecessors of the virtual root have the same expected result.
-        for port in self._ports.values():
-            directories = self._relative_baseline_search_paths(port, non_virtual_baseline_name)
-            for directory in directories:
-                if directory not in results_by_directory:
-                    continue
-                if results_by_directory[directory] != root_sha1:
-                    return
-                break
-
-        _log.debug("Deleting redundant virtual root expected result.")
-        _log.debug("    Deleting (file system): " + virtual_root_baseline_path)
-        self._filesystem.remove(virtual_root_baseline_path)
-
-    def optimize(self, baseline_name):
-        # The virtual fallback path is the same as the non-virtual one tacked on to the bottom of the non-virtual path.
-        # See https://docs.google.com/a/chromium.org/drawings/d/1eGdsIKzJ2dxDDBbUaIABrN4aMLD1bqJTfyxNGZsTdmg/edit for
-        # a visual representation of this.
-        #
-        # So, we can optimize the virtual path, then the virtual root and then the regular path.
-
-        _log.debug("Optimizing regular fallback path.")
-        result = self._optimize_subtree(baseline_name)
-        non_virtual_baseline_name = self._virtual_base(baseline_name)
-        if not non_virtual_baseline_name:
-            return result
-
-        self._optimize_virtual_root(baseline_name, non_virtual_baseline_name)
-
-        _log.debug("Optimizing non-virtual fallback path.")
-        result |= self._optimize_subtree(non_virtual_baseline_name)
-        return result
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/baseline_optimizer_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/baseline_optimizer_unittest.py
index 88711dc..7514e04 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/baseline_optimizer_unittest.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/baseline_optimizer_unittest.py
@@ -35,75 +35,19 @@
 
 class BaselineOptimizerTest(unittest.TestCase):
 
-    # Protected method _move_baselines is tested below - pylint: disable=protected-access
-    def test_move_baselines(self):
-        host = MockHost()
-        host.filesystem.write_text_file('/mock-checkout/third_party/WebKit/LayoutTests/VirtualTestSuites', '[]')
-        host.filesystem.write_binary_file(
-            '/mock-checkout/third_party/WebKit/LayoutTests/platform/win/another/test-expected.txt', 'result A')
-        host.filesystem.write_binary_file(
-            '/mock-checkout/third_party/WebKit/LayoutTests/platform/mac/another/test-expected.txt', 'result A')
-        host.filesystem.write_binary_file('/mock-checkout/third_party/WebKit/LayoutTests/another/test-expected.txt', 'result B')
-        baseline_optimizer = BaselineOptimizer(
-            host, host.port_factory.get(), host.port_factory.all_port_names())
-        baseline_optimizer._move_baselines(
-            'another/test-expected.txt',
-            {
-                '/mock-checkout/third_party/WebKit/LayoutTests/platform/win': 'aaa',
-                '/mock-checkout/third_party/WebKit/LayoutTests/platform/mac': 'aaa',
-                '/mock-checkout/third_party/WebKit/LayoutTests': 'bbb',
-            },
-            {
-                '/mock-checkout/third_party/WebKit/LayoutTests': 'aaa',
-            })
-        self.assertEqual(host.filesystem.read_binary_file(
-            '/mock-checkout/third_party/WebKit/LayoutTests/another/test-expected.txt'), 'result A')
-
-    def test_move_baselines_skip_git_commands(self):
-        host = MockHost()
-        host.filesystem.write_text_file('/mock-checkout/third_party/WebKit/LayoutTests/VirtualTestSuites', '[]')
-        host.filesystem.write_binary_file(
-            '/mock-checkout/third_party/WebKit/LayoutTests/platform/win/another/test-expected.txt', 'result A')
-        host.filesystem.write_binary_file(
-            '/mock-checkout/third_party/WebKit/LayoutTests/platform/mac/another/test-expected.txt', 'result A')
-        host.filesystem.write_binary_file('/mock-checkout/third_party/WebKit/LayoutTests/another/test-expected.txt', 'result B')
-        baseline_optimizer = BaselineOptimizer(host, host.port_factory.get(
-        ), host.port_factory.all_port_names())
-        baseline_optimizer._move_baselines(
-            'another/test-expected.txt',
-            {
-                '/mock-checkout/third_party/WebKit/LayoutTests/platform/win': 'aaa',
-                '/mock-checkout/third_party/WebKit/LayoutTests/platform/mac': 'aaa',
-                '/mock-checkout/third_party/WebKit/LayoutTests': 'bbb',
-            },
-            {
-                '/mock-checkout/third_party/WebKit/LayoutTests/platform/linux': 'bbb',
-                '/mock-checkout/third_party/WebKit/LayoutTests': 'aaa',
-            })
-        self.assertEqual(
-            host.filesystem.read_binary_file(
-                '/mock-checkout/third_party/WebKit/LayoutTests/another/test-expected.txt'),
-            'result A')
-
-    def _assert_optimization(
-            self,
-            results_by_directory,
-            directory_to_new_results,
-            baseline_dirname='', host=None):
-        if not host:
-            host = MockHost()
+    def _assert_optimization(self, results_by_directory, directory_to_new_results, baseline_dirname='', host=None):
+        host = host or MockHost()
         fs = host.filesystem
         webkit_base = WebKitFinder(fs).webkit_base()
         baseline_name = 'mock-baseline-expected.txt'
-        fs.write_text_file(fs.join(webkit_base, 'LayoutTests', 'VirtualTestSuites'),
-                           '[{"prefix": "gpu", "base": "fast/canvas", "args": ["--foo"]}]')
+        fs.write_text_file(
+            fs.join(webkit_base, 'LayoutTests', 'VirtualTestSuites'),
+            '[{"prefix": "gpu", "base": "fast/canvas", "args": ["--foo"]}]')
 
         for dirname, contents in results_by_directory.items():
-            path = fs.join(webkit_base, 'LayoutTests', dirname, baseline_name)
-            fs.write_binary_file(path, contents)
+            fs.write_binary_file(fs.join(webkit_base, 'LayoutTests', dirname, baseline_name), contents)
 
-        baseline_optimizer = BaselineOptimizer(host, host.port_factory.get(
-        ), host.port_factory.all_port_names())
+        baseline_optimizer = BaselineOptimizer(host, host.port_factory.get(), host.port_factory.all_port_names())
         self.assertTrue(baseline_optimizer.optimize(fs.join(baseline_dirname, baseline_name)))
 
         for dirname, contents in directory_to_new_results.items():
@@ -254,3 +198,54 @@
                 'platform/mac/fast/canvas': '1',
             },
             baseline_dirname='virtual/gpu/fast/canvas')
+
+    # Tests for protected methods - pylint: disable=protected-access
+
+    def test_move_baselines(self):
+        host = MockHost()
+        host.filesystem.write_text_file('/mock-checkout/third_party/WebKit/LayoutTests/VirtualTestSuites', '[]')
+        host.filesystem.write_binary_file(
+            '/mock-checkout/third_party/WebKit/LayoutTests/platform/win/another/test-expected.txt', 'result A')
+        host.filesystem.write_binary_file(
+            '/mock-checkout/third_party/WebKit/LayoutTests/platform/mac/another/test-expected.txt', 'result A')
+        host.filesystem.write_binary_file('/mock-checkout/third_party/WebKit/LayoutTests/another/test-expected.txt', 'result B')
+        baseline_optimizer = BaselineOptimizer(
+            host, host.port_factory.get(), host.port_factory.all_port_names())
+        baseline_optimizer._move_baselines(
+            'another/test-expected.txt',
+            {
+                '/mock-checkout/third_party/WebKit/LayoutTests/platform/win': 'aaa',
+                '/mock-checkout/third_party/WebKit/LayoutTests/platform/mac': 'aaa',
+                '/mock-checkout/third_party/WebKit/LayoutTests': 'bbb',
+            },
+            {
+                '/mock-checkout/third_party/WebKit/LayoutTests': 'aaa',
+            })
+        self.assertEqual(host.filesystem.read_binary_file(
+            '/mock-checkout/third_party/WebKit/LayoutTests/another/test-expected.txt'), 'result A')
+
+    def test_move_baselines_skip_git_commands(self):
+        host = MockHost()
+        host.filesystem.write_text_file('/mock-checkout/third_party/WebKit/LayoutTests/VirtualTestSuites', '[]')
+        host.filesystem.write_binary_file(
+            '/mock-checkout/third_party/WebKit/LayoutTests/platform/win/another/test-expected.txt', 'result A')
+        host.filesystem.write_binary_file(
+            '/mock-checkout/third_party/WebKit/LayoutTests/platform/mac/another/test-expected.txt', 'result A')
+        host.filesystem.write_binary_file('/mock-checkout/third_party/WebKit/LayoutTests/another/test-expected.txt', 'result B')
+        baseline_optimizer = BaselineOptimizer(host, host.port_factory.get(
+        ), host.port_factory.all_port_names())
+        baseline_optimizer._move_baselines(
+            'another/test-expected.txt',
+            {
+                '/mock-checkout/third_party/WebKit/LayoutTests/platform/win': 'aaa',
+                '/mock-checkout/third_party/WebKit/LayoutTests/platform/mac': 'aaa',
+                '/mock-checkout/third_party/WebKit/LayoutTests': 'bbb',
+            },
+            {
+                '/mock-checkout/third_party/WebKit/LayoutTests/platform/linux': 'bbb',
+                '/mock-checkout/third_party/WebKit/LayoutTests': 'aaa',
+            })
+        self.assertEqual(
+            host.filesystem.read_binary_file(
+                '/mock-checkout/third_party/WebKit/LayoutTests/another/test-expected.txt'),
+            'result A')
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/log_testing.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/log_testing.py
index a71bfe0..97df6c5 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/log_testing.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/log_testing.py
@@ -35,7 +35,8 @@
 
 # pylint: disable=invalid-name
 # Camel-case names are used here to match the style of the TestCase methods.
-
+# TODO(qyearsley): Change these names to use lowercase-only, for consistency
+# with other unit test helper methods.
 
 class TestLogStream(object):
     """Represents a file-like object for unit-testing logging.
@@ -193,7 +194,6 @@
 
 
 class LoggingTestCase(unittest.TestCase):
-
     """Supports end-to-end unit-testing of log messages.
 
     This class needs to inherit from unittest.TestCase.  Otherwise, the
@@ -216,6 +216,9 @@
     def setUp(self):
         self._log = LogTesting.setUp(self)
 
+    def set_logging_level(self, logging_level):
+        self._log = LogTesting.setUp(self, logging_level=logging_level)
+
     def tearDown(self):
         self._log.tearDown()
 
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/platform_info.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/platform_info.py
index 860fcd6..acf588a 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/platform_info.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/platform_info.py
@@ -147,9 +147,8 @@
 
     def _determine_mac_version(self, mac_version_string):
         minor_release = int(mac_version_string.split('.')[1])
-        # FIXME: This should really be >= 9, and we should get rid of 'future'.
-        assert minor_release >= 6, 'Unsupported mac os version: %s' % mac_version_string
-        if minor_release in (9, 10, 11):
+        assert minor_release >= 9, 'Unsupported mac OS version: %s' % mac_version_string
+        if minor_release <= 12:
             return 'mac10.%d' % minor_release
         return 'future'
 
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/platform_info_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/platform_info_unittest.py
index eda5bc7..ff36290 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/platform_info_unittest.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/platform_info_unittest.py
@@ -47,7 +47,7 @@
     return FakeSysModule()
 
 
-def fake_platform(mac_version_string='10.6.3', release_string='bar', linux_version='trusty'):
+def fake_platform(mac_version_string='10.12.3', release_string='bar', linux_version='trusty'):
 
     class FakePlatformModule(object):
 
@@ -108,7 +108,7 @@
         self.assertFalse(info.is_win())
         self.assertFalse(info.is_freebsd())
 
-        info = self.make_info(fake_sys('darwin'), fake_platform('10.6.3'))
+        info = self.make_info(fake_sys('darwin'), fake_platform('10.12.3'))
         self.assertEqual(info.os_name, 'mac')
         self.assertFalse(info.is_linux())
         self.assertTrue(info.is_mac())
@@ -139,11 +139,12 @@
         self.assertRaises(AssertionError, self.make_info, fake_sys('vms'))
 
     def test_os_version(self):
-        self.assertRaises(AssertionError, self.make_info, fake_sys('darwin'), fake_platform('10.4.3'))
+        self.assertRaises(AssertionError, self.make_info, fake_sys('darwin'), fake_platform('10.6.3'))
         self.assertEqual(self.make_info(fake_sys('darwin'), fake_platform('10.9.0')).os_version, 'mac10.9')
         self.assertEqual(self.make_info(fake_sys('darwin'), fake_platform('10.10.0')).os_version, 'mac10.10')
         self.assertEqual(self.make_info(fake_sys('darwin'), fake_platform('10.11.0')).os_version, 'mac10.11')
-        self.assertEqual(self.make_info(fake_sys('darwin'), fake_platform('10.12.0')).os_version, 'future')
+        self.assertEqual(self.make_info(fake_sys('darwin'), fake_platform('10.12.0')).os_version, 'mac10.12')
+        self.assertEqual(self.make_info(fake_sys('darwin'), fake_platform('10.15.0')).os_version, 'future')
 
         self.assertEqual(self.make_info(fake_sys('linux2')).os_version, 'trusty')
         info = self.make_info(fake_sys('linux2'), fake_platform(linux_version='utopic'))
@@ -203,7 +204,7 @@
         self.assertNotEquals(info.display_name(), '')
 
     def test_total_bytes_memory(self):
-        info = self.make_info(fake_sys('darwin'), fake_platform('10.6.3'), executive=fake_executive('1234'))
+        info = self.make_info(fake_sys('darwin'), fake_platform('10.12.3'), executive=fake_executive('1234'))
         self.assertEqual(info.total_bytes_memory(), 1234)
 
         info = self.make_info(fake_sys('win32', tuple([6, 1, 7600])))
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/base.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/base.py
index 03246f1c..177028ad 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/base.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/base.py
@@ -191,9 +191,6 @@
         return "Port{name=%s, version=%s, architecture=%s, test_configuration=%s}" % (
             self._name, self._version, self._architecture, self._test_configuration)
 
-    def buildbot_archives_baselines(self):
-        return True
-
     def additional_driver_flag(self):
         if self.driver_name() == self.CONTENT_SHELL_NAME:
             return ['--run-layout-test']
@@ -202,9 +199,6 @@
     def supports_per_test_timeout(self):
         return False
 
-    def default_pixel_tests(self):
-        return True
-
     def default_smoke_test_only(self):
         return False
 
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/mac.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/mac.py
index 8ad87584..680e06d 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/mac.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/mac.py
@@ -37,7 +37,7 @@
 
 
 class MacPort(base.Port):
-    SUPPORTED_VERSIONS = ('mac10.9', 'mac10.10', 'mac10.11', 'retina')
+    SUPPORTED_VERSIONS = ('mac10.9', 'mac10.10', 'mac10.11', 'mac10.12', 'retina')
     port_name = 'mac'
 
     # FIXME: We treat Retina (High-DPI) devices as if they are running
@@ -48,7 +48,8 @@
     # We also currently only support Retina on 10.11.
 
     FALLBACK_PATHS = {}
-    FALLBACK_PATHS['mac10.11'] = ['mac']
+    FALLBACK_PATHS['mac10.12'] = ['mac']
+    FALLBACK_PATHS['mac10.11'] = ['mac-mac10.11'] + FALLBACK_PATHS['mac10.12']
     FALLBACK_PATHS['mac10.10'] = ['mac-mac10.10'] + FALLBACK_PATHS['mac10.11']
     FALLBACK_PATHS['mac10.9'] = ['mac-mac10.9'] + FALLBACK_PATHS['mac10.10']
     FALLBACK_PATHS['retina'] = ['mac-retina', 'mac']
@@ -62,10 +63,7 @@
     @classmethod
     def determine_full_port_name(cls, host, options, port_name):
         if port_name.endswith('mac'):
-            if host.platform.os_version in ('future',):
-                version = 'mac10.11'
-            else:
-                version = host.platform.os_version
+            version = host.platform.os_version
             if host.platform.is_highdpi():
                 version = 'retina'
             return port_name + '-' + version
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/mac_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/mac_unittest.py
index 7c8a2763..5310598 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/mac_unittest.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/mac_unittest.py
@@ -34,9 +34,9 @@
 
 class MacPortTest(port_testcase.PortTestCase):
     os_name = 'mac'
-    os_version = 'mac10.11'
+    os_version = 'mac10.12'
     port_name = 'mac'
-    full_port_name = 'mac-mac10.11'
+    full_port_name = 'mac-mac10.12'
     port_maker = mac.MacPort
 
     def assert_name(self, port_name, os_version_string, expected):
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/port_testcase.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/port_testcase.py
index f05e102..ab8887f4 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/port_testcase.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/port_testcase.py
@@ -126,9 +126,6 @@
         self.assertEqual(self.make_port(options=optparse.Values({'configuration': 'Release'})).default_timeout_ms(), 6000)
         self.assertEqual(self.make_port(options=optparse.Values({'configuration': 'Debug'})).default_timeout_ms(), 18000)
 
-    def test_default_pixel_tests(self):
-        self.assertEqual(self.make_port().default_pixel_tests(), True)
-
     def test_driver_cmd_line(self):
         port = self.make_port()
         self.assertTrue(len(port.driver_cmd_line()))
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/test.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/test.py
index f54ce253..7c47439 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/test.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/test.py
@@ -430,9 +430,6 @@
     def buildbot_archives_baselines(self):
         return self._name != 'test-win-win7'
 
-    def default_pixel_tests(self):
-        return True
-
     def _path_to_driver(self):
         # This routine shouldn't normally be called, but it is called by
         # the mock_drt Driver. We return something, but make sure it's useless.
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests.py
index 7e7bd00..113c3d3 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/run_webkit_tests.py
@@ -190,12 +190,14 @@
                 "--pixel-tests",
                 dest="pixel_tests",
                 action="store_true",
-                help="Enable pixel-to-pixel PNG comparisons"),
+                default=True,
+                help="Enable pixel-to-pixel PNG comparisons (enabled by default)"),
             optparse.make_option(
                 "--no-pixel",
                 "--no-pixel-tests",
                 dest="pixel_tests",
                 action="store_false",
+                default=True,
                 help="Disable pixel-to-pixel PNG comparisons"),
             # FIXME: we should support a comma separated list with
             # --pixel-test-directory as well.
@@ -485,9 +487,6 @@
     if not options.configuration:
         options.configuration = port.default_configuration()
 
-    if options.pixel_tests is None:
-        options.pixel_tests = port.default_pixel_tests()
-
     if not options.time_out_ms:
         options.time_out_ms = str(port.default_timeout_ms())
 
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/servers/wptserve_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/servers/wptserve_unittest.py
index 7fc95b6..ad3c736 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/servers/wptserve_unittest.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/servers/wptserve_unittest.py
@@ -4,7 +4,7 @@
 
 import logging
 
-from webkitpy.common.system.log_testing import LoggingTestCase, LogTesting
+from webkitpy.common.system.log_testing import LoggingTestCase
 from webkitpy.common.host_mock import MockHost
 from webkitpy.layout_tests.port import test
 from webkitpy.layout_tests.servers.wptserve import WPTServe
@@ -42,7 +42,7 @@
 
     def test_start_with_unkillable_zombie_process(self):
         # Allow asserting about debug logs.
-        self._log = LogTesting.setUp(self, logging_level=logging.DEBUG)
+        self.set_logging_level(logging.DEBUG)
 
         host = MockHost()
         test_port = test.TestPort(host)
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/update_test_expectations_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/update_test_expectations_unittest.py
index b936f50..a3f3c76 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/update_test_expectations_unittest.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/update_test_expectations_unittest.py
@@ -8,7 +8,7 @@
 
 from webkitpy.common.host_mock import MockHost
 from webkitpy.common.system.filesystem_mock import MockFileSystem
-from webkitpy.common.system.log_testing import LoggingTestCase, LogTesting
+from webkitpy.common.system.log_testing import LoggingTestCase
 from webkitpy.layout_tests.builder_list import BuilderList
 from webkitpy.layout_tests.port.factory import PortFactory
 from webkitpy.layout_tests.port.test import LAYOUT_TEST_DIR
@@ -723,9 +723,9 @@
         that have builders, then it can be removed, even if there are extra
         configurations with no existing builders.
         """
-        # Set the logging level used for assertLog to allow us to check all messages,
-        # even messages with a "debug" severity level.
-        self._log = LogTesting.setUp(self, logging_level=logging.DEBUG)
+        # Set the logging level used for assertLog to allow us to check
+        # messages with a "debug" severity level.
+        self.set_logging_level(logging.DEBUG)
 
         test_expectations_before = """
             # There are no builders that match this configuration at all.
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline.py b/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline.py
index e988bd8cd..0e0f965 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline.py
@@ -165,8 +165,6 @@
         immediate_predecessors = []
         for port_name in port_names:
             port = self._tool.port_factory.get(port_name)
-            if not port.buildbot_archives_baselines():
-                continue
             baseline_search_path = port.baseline_search_path()
             try:
                 index = baseline_search_path.index(path_to_rebaseline)
diff --git a/third_party/WebKit/public/web/WebRuntimeFeatures.h b/third_party/WebKit/public/web/WebRuntimeFeatures.h
index c1188d3b..9e685b5b 100644
--- a/third_party/WebKit/public/web/WebRuntimeFeatures.h
+++ b/third_party/WebKit/public/web/WebRuntimeFeatures.h
@@ -146,6 +146,7 @@
   BLINK_EXPORT static void enableSendBeaconThrowForBlobWithNonSimpleType(bool);
   BLINK_EXPORT static void enableBackgroundVideoTrackOptimization(bool);
   BLINK_EXPORT static void enableVideoFullscreenOrientationLock(bool);
+  BLINK_EXPORT static void enableMediaControlsOverlayPlayButton(bool);
 
  private:
   WebRuntimeFeatures();
diff --git a/third_party/WebKit/public/web/WebSettings.h b/third_party/WebKit/public/web/WebSettings.h
index 70fe7252..9d9aaaff 100644
--- a/third_party/WebKit/public/web/WebSettings.h
+++ b/third_party/WebKit/public/web/WebSettings.h
@@ -198,7 +198,6 @@
   virtual void setMainFrameClipsContent(bool) = 0;
   virtual void setMainFrameResizesAreOrientationChanges(bool) = 0;
   virtual void setMaxTouchPoints(int) = 0;
-  virtual void setMediaControlsOverlayPlayButtonEnabled(bool) = 0;
   virtual void setMediaPlaybackRequiresUserGesture(bool) = 0;
   virtual void setMediaPlaybackGestureWhitelistScope(const WebString&) = 0;
   virtual void setPresentationRequiresUserGesture(bool) = 0;
diff --git a/third_party/freetype-android/.clang-format b/third_party/freetype/.clang-format
similarity index 100%
rename from third_party/freetype-android/.clang-format
rename to third_party/freetype/.clang-format
diff --git a/third_party/freetype-android/BUILD.gn b/third_party/freetype/BUILD.gn
similarity index 92%
rename from third_party/freetype-android/BUILD.gn
rename to third_party/freetype/BUILD.gn
index c853c762..30c0b37 100644
--- a/third_party/freetype-android/BUILD.gn
+++ b/third_party/freetype/BUILD.gn
@@ -65,8 +65,8 @@
     "DARWIN_NO_CARBON",
 
     # Long directory name to avoid accidentally using wrong headers.
-    "FT_CONFIG_MODULES_H=<freetype-android-config/ftmodule.h>",
-    "FT_CONFIG_OPTIONS_H=<freetype-android-config/ftoption.h>",
+    "FT_CONFIG_MODULES_H=<freetype-custom-config/ftmodule.h>",
+    "FT_CONFIG_OPTIONS_H=<freetype-custom-config/ftoption.h>",
   ]
 
   public_configs = [ ":freetype_config" ]
@@ -74,7 +74,7 @@
   configs += [
     "//build/config/compiler:no_chromium_code",
     ":freetype-warnings",
-    ":freetype-visibility"
+    ":freetype-visibility",
   ]
 
   deps = [
diff --git a/third_party/freetype-android/OWNERS b/third_party/freetype/OWNERS
similarity index 100%
rename from third_party/freetype-android/OWNERS
rename to third_party/freetype/OWNERS
diff --git a/third_party/freetype-android/README.chromium b/third_party/freetype/README.chromium
similarity index 100%
rename from third_party/freetype-android/README.chromium
rename to third_party/freetype/README.chromium
diff --git a/third_party/freetype-android/include/freetype-android-config/ftmodule.h b/third_party/freetype/include/freetype-custom-config/ftmodule.h
similarity index 100%
rename from third_party/freetype-android/include/freetype-android-config/ftmodule.h
rename to third_party/freetype/include/freetype-custom-config/ftmodule.h
diff --git a/third_party/freetype-android/include/freetype-android-config/ftoption.h b/third_party/freetype/include/freetype-custom-config/ftoption.h
similarity index 100%
rename from third_party/freetype-android/include/freetype-android-config/ftoption.h
rename to third_party/freetype/include/freetype-custom-config/ftoption.h
diff --git a/third_party/libaddressinput/chromium/chrome_storage_impl.cc b/third_party/libaddressinput/chromium/chrome_storage_impl.cc
index 4daab33..2504eee 100644
--- a/third_party/libaddressinput/chromium/chrome_storage_impl.cc
+++ b/third_party/libaddressinput/chromium/chrome_storage_impl.cc
@@ -26,7 +26,7 @@
   DCHECK(data);
   std::unique_ptr<std::string> owned_data(data);
   backing_store_->SetValue(
-      key, base::MakeUnique<base::StringValue>(std::move(*owned_data)),
+      key, base::MakeUnique<base::Value>(std::move(*owned_data)),
       WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
 }
 
diff --git a/tools/chrome_proxy/webdriver/common.py b/tools/chrome_proxy/webdriver/common.py
index be29345..57bab09 100644
--- a/tools/chrome_proxy/webdriver/common.py
+++ b/tools/chrome_proxy/webdriver/common.py
@@ -578,11 +578,12 @@
       self.assertNotIn(expected_via_header,
         http_response.response_headers['via'])
 
-  def assertLoFiResponse(self, http_response, expected_lo_fi):
-    """Asserts that the response and request headers contain the given directive
-    and the content size is less than 100 if |expected_lo_fi|. Otherwise, checks
-    that the response and request headers don't contain the Lo-Fi directive and
-    the content size is greater than 100.
+  def checkLoFiResponse(self, http_response, expected_lo_fi):
+    """Asserts that if expected the response headers contain the Lo-Fi directive
+    then the request headers do too. Also checks that the content size is less
+    than 100 if |expected_lo_fi|. Otherwise, checks that the response and
+    request headers don't contain the Lo-Fi directive and the content size is
+    greater than 100.
 
     Args:
       http_response: The HTTPResponse object to check.
@@ -613,6 +614,29 @@
       self.assertTrue(int(content_length) > 100)
       return False;
 
+  def checkLitePageResponse(self, http_response):
+    """Asserts that if the response headers contain the Lite Page directive then
+    the request headers do too.
+
+    Args:
+      http_response: The HTTPResponse object to check.
+
+    Returns:
+      Whether the response was a Lite Page.
+    """
+
+    self.assertHasChromeProxyViaHeader(http_response)
+    if ('chrome-proxy-content-transform' not in http_response.response_headers):
+      return False;
+    cpct_response = http_response.response_headers[
+                      'chrome-proxy-content-transform']
+    cpat_request = http_response.request_headers[
+                      'chrome-proxy-accept-transform']
+    if ('lite-page' in cpct_response):
+      self.assertIn('lite-page', cpat_request)
+      return True;
+    return False;
+
   @staticmethod
   def RunAllTests(run_all_tests=False):
     """A simple helper method to run all tests using unittest.main().
diff --git a/tools/chrome_proxy/webdriver/lite_page.py b/tools/chrome_proxy/webdriver/lite_page.py
new file mode 100644
index 0000000..a833813
--- /dev/null
+++ b/tools/chrome_proxy/webdriver/lite_page.py
@@ -0,0 +1,115 @@
+# Copyright 2017 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 common
+from common import TestDriver
+from common import IntegrationTest
+
+
+class LitePage(IntegrationTest):
+
+  # Checks that a Lite Page is served and that the ignore_preview_blacklist
+  # experiment is being used.
+  def testLitePage(self):
+    with TestDriver() as test_driver:
+      test_driver.AddChromeArg('--enable-spdy-proxy-auth')
+      test_driver.AddChromeArg('--data-reduction-proxy-lo-fi=always-on')
+      test_driver.AddChromeArg('--enable-data-reduction-proxy-lite-page')
+
+      test_driver.LoadURL('http://check.googlezip.net/test.html')
+
+      lite_page_responses = 0
+      for response in test_driver.GetHTTPResponses():
+        # Skip CSI requests when validating Lite Page headers. CSI requests
+        # aren't expected to have LoFi headers.
+        if '/csi?' in response.url:
+          continue
+        if response.url.startswith('data:'):
+          continue
+        self.assertIn('exp=ignore_preview_blacklist',
+          response.request_headers['chrome-proxy'])
+        if (self.checkLitePageResponse(response)):
+          lite_page_responses = lite_page_responses + 1
+
+      # Verify that a Lite Page response for the main frame was seen.
+      self.assertEqual(1, lite_page_responses)
+
+  # Checks that Lo-Fi images are used when the user is in the
+  # DataCompressionProxyLitePageFallback field trial and a Lite Page is not
+  # served.
+  def testLitePageFallback(self):
+    with TestDriver() as test_driver:
+      test_driver.AddChromeArg('--enable-spdy-proxy-auth')
+      test_driver.AddChromeArg('--force-fieldtrials='
+                               'DataCompressionProxyLoFi/Enabled_Preview/'
+                               'DataCompressionProxyLitePageFallback/Enabled')
+      test_driver.AddChromeArg('--force-fieldtrial-params='
+                               'DataCompressionProxyLoFi.Enabled_Preview:'
+                               'effective_connection_type/4G')
+      test_driver.AddChromeArg('--force-net-effective-connection-type=2g')
+
+      test_driver.LoadURL('http://check.googlezip.net/lite-page-fallback')
+
+      lite_page_requests = 0
+      lo_fi_responses = 0
+      for response in test_driver.GetHTTPResponses():
+        if not response.request_headers:
+          continue
+
+        cpat_request = response.request_headers['chrome-proxy-accept-transform']
+        if ('lite-page' in cpat_request):
+          lite_page_requests = lite_page_requests + 1
+          self.assertFalse(self.checkLitePageResponse(response))
+
+        if not response.url.endswith('png'):
+          continue
+
+        if (self.checkLoFiResponse(response, True)):
+          lo_fi_responses = lo_fi_responses + 1
+
+      # Verify that a Lite Page was requested and that the page fell back to
+      # Lo-Fi images.
+      self.assertEqual(1, lite_page_requests)
+      self.assertEqual(1, lo_fi_responses)
+
+  # Checks that Lo-Fi images are not used when the user is not in the
+  # DataCompressionProxyLitePageFallback field trial and a Lite Page is not
+  # served.
+  def testLitePageNoFallback(self):
+    with TestDriver() as test_driver:
+      test_driver.AddChromeArg('--enable-spdy-proxy-auth')
+      # Lite Pages must be enabled via the field trial because the Lite Page
+      # flag always falls back to Lo-Fi.
+      test_driver.AddChromeArg('--force-fieldtrials='
+                               'DataCompressionProxyLoFi/Enabled_Preview')
+      test_driver.AddChromeArg('--force-fieldtrial-params='
+                               'DataCompressionProxyLoFi.Enabled_Preview:'
+                               'effective_connection_type/4G')
+      test_driver.AddChromeArg('--force-net-effective-connection-type=2g')
+
+      test_driver.LoadURL('http://check.googlezip.net/lite-page-fallback')
+
+      lite_page_requests = 0
+      for response in test_driver.GetHTTPResponses():
+        if not response.request_headers:
+          continue
+
+        if ('chrome-proxy-accept-transform' in response.request_headers):
+          cpat_request = response.request_headers[
+                           'chrome-proxy-accept-transform']
+          if ('lite-page' in cpat_request):
+            lite_page_requests = lite_page_requests + 1
+            self.assertFalse(self.checkLitePageResponse(response))
+
+        if not response.url.endswith('png'):
+          continue
+
+        self.checkLoFiResponse(response, False)
+
+      # Verify that a Lite Page was requested and that the page fell back to
+      # Lo-Fi images.
+      self.assertEqual(1, lite_page_requests)
+
+if __name__ == '__main__':
+  IntegrationTest.RunAllTests()
diff --git a/tools/chrome_proxy/webdriver/lofi.py b/tools/chrome_proxy/webdriver/lofi.py
index 8b2fd5d4..fca1f85 100644
--- a/tools/chrome_proxy/webdriver/lofi.py
+++ b/tools/chrome_proxy/webdriver/lofi.py
@@ -28,44 +28,12 @@
           continue
         if not response.request_headers:
           continue
-        if (self.assertLoFiResponse(response, True)):
+        if (self.checkLoFiResponse(response, True)):
           lofi_responses = lofi_responses + 1
 
       # Verify that Lo-Fi responses were seen.
       self.assertNotEqual(0, lofi_responses)
 
-  # Checks that a Lite Page is served and that the ignore_preview_blacklist
-  # experiment is being used.
-  def testLitePage(self):
-    with TestDriver() as test_driver:
-      test_driver.AddChromeArg('--enable-spdy-proxy-auth')
-      test_driver.AddChromeArg('--data-reduction-proxy-lo-fi=always-on')
-      test_driver.AddChromeArg('--enable-data-reduction-proxy-lite-page')
-
-      test_driver.LoadURL('http://check.googlezip.net/test.html')
-
-      lite_page_responses = 0
-      for response in test_driver.GetHTTPResponses():
-        # Skip CSI requests when validating Lite Page headers. CSI requests
-        # aren't expected to have LoFi headers.
-        if '/csi?' in response.url:
-          continue
-        if response.url.startswith('data:'):
-          continue
-        chrome_proxy_request = response.request_headers['chrome-proxy']
-        cpat_request = response.request_headers['chrome-proxy-accept-transform']
-        cpct_response = response.response_headers[
-                          'chrome-proxy-content-transform']
-        self.assertHasChromeProxyViaHeader(response)
-        self.assertIn('exp=ignore_preview_blacklist',
-          chrome_proxy_request)
-        if ('lite-page' in cpct_response):
-          lite_page_responses = lite_page_responses + 1
-          self.assertIn('lite-page', cpat_request)
-
-      # Verify that a Lite Page response for the main frame was seen.
-      self.assertEqual(1, lite_page_responses)
-
   # Checks that Lo-Fi placeholder images are not loaded from cache on page
   # reloads when Lo-Fi mode is disabled or data reduction proxy is disabled.
   # First a test page is opened with Lo-Fi and chrome proxy enabled. This allows
@@ -96,7 +64,7 @@
           continue
         if not response.request_headers:
           continue
-        if (self.assertLoFiResponse(response, True)):
+        if (self.checkLoFiResponse(response, True)):
           lofi_responses = lofi_responses + 1
 
       # Verify that Lo-Fi responses were seen.
@@ -115,7 +83,7 @@
           continue
         responses = responses + 1
         self.assertNotHasChromeProxyViaHeader(response)
-        self.assertLoFiResponse(response, False)
+        self.checkLoFiResponse(response, False)
 
       # Verify that responses were seen.
       self.assertNotEqual(0, responses)
@@ -135,7 +103,7 @@
           continue
         responses = responses + 1
         self.assertHasChromeProxyViaHeader(response)
-        self.assertLoFiResponse(response, False)
+        self.checkLoFiResponse(response, False)
 
       # Verify that responses were seen.
       self.assertNotEqual(0, responses)
diff --git a/tools/clang/value_cleanup/ListValueRewriter.cpp b/tools/clang/value_cleanup/ListValueRewriter.cpp
index 85b1d28..67988b5 100644
--- a/tools/clang/value_cleanup/ListValueRewriter.cpp
+++ b/tools/clang/value_cleanup/ListValueRewriter.cpp
@@ -408,20 +408,20 @@
                                           realFloatingPointType())))))))))))),
       &append_double_callback_);
 
-  // base::ListValue::Append(new base::StringValue(...))
+  // base::ListValue::Append(new base::Value(...))
   //     => base::ListValue::AppendString()
   match_finder->addMatcher(
       id("callExpr",
          cxxMemberCallExpr(
              is_list_append,
              hasArgument(
-                 0, ignoringParenImpCasts(id(
-                        "newExpr",
-                        cxxNewExpr(has(cxxConstructExpr(
-                            hasDeclaration(cxxMethodDecl(
-                                hasName("::base::StringValue::StringValue"))),
-                            argumentCountIs(1),
-                            hasArgument(0, id("argExpr", expr())))))))))),
+                 0, ignoringParenImpCasts(
+                        id("newExpr",
+                           cxxNewExpr(has(cxxConstructExpr(
+                               hasDeclaration(cxxMethodDecl(
+                                   hasName("::base::Value::StringValue"))),
+                               argumentCountIs(1),
+                               hasArgument(0, id("argExpr", expr())))))))))),
       &append_string_callback_);
 
   auto is_unique_ptr_release =
diff --git a/tools/clang/value_cleanup/tests/list-value-append-original.cc b/tools/clang/value_cleanup/tests/list-value-append-original.cc
index 806da66..adebcf4 100644
--- a/tools/clang/value_cleanup/tests/list-value-append-original.cc
+++ b/tools/clang/value_cleanup/tests/list-value-append-original.cc
@@ -29,7 +29,7 @@
   list.Append(new base::Value(true));
   list.Append(new base::Value(static_cast<unsigned char>(1.0)));
   list.Append(new base::Value(double{3}));
-  list.Append(new base::StringValue("abc"));
+  list.Append(new base::Value("abc"));
 
   list.Append(ReturnsUniquePtr().release());
   Thing thing;
diff --git a/tools/gn/build_settings.cc b/tools/gn/build_settings.cc
index 3fac976..c60002d 100644
--- a/tools/gn/build_settings.cc
+++ b/tools/gn/build_settings.cc
@@ -18,9 +18,9 @@
       secondary_source_path_(other.secondary_source_path_),
       python_path_(other.python_path_),
       build_config_file_(other.build_config_file_),
+      arg_file_template_path_(other.arg_file_template_path_),
       build_dir_(other.build_dir_),
-      build_args_(other.build_args_) {
-}
+      build_args_(other.build_args_) {}
 
 BuildSettings::~BuildSettings() {
 }
diff --git a/tools/gn/build_settings.h b/tools/gn/build_settings.h
index 0b986cd..3f9f45b 100644
--- a/tools/gn/build_settings.h
+++ b/tools/gn/build_settings.h
@@ -52,6 +52,14 @@
   const SourceFile& build_config_file() const { return build_config_file_; }
   void set_build_config_file(const SourceFile& f) { build_config_file_ = f; }
 
+  // Path to a file containing the default text to use when running `gn args`.
+  const SourceFile& arg_file_template_path() const {
+    return arg_file_template_path_;
+  }
+  void set_arg_file_template_path(const SourceFile& f) {
+    arg_file_template_path_ = f;
+  }
+
   // The build directory is the root of all output files. The default toolchain
   // files go into here, and non-default toolchains will have separate
   // toolchain-specific root directories inside this.
@@ -102,6 +110,7 @@
   base::FilePath python_path_;
 
   SourceFile build_config_file_;
+  SourceFile arg_file_template_path_;
   SourceDir build_dir_;
   Args build_args_;
 
diff --git a/tools/gn/command_args.cc b/tools/gn/command_args.cc
index 98283f29..2772fc2 100644
--- a/tools/gn/command_args.cc
+++ b/tools/gn/command_args.cc
@@ -268,16 +268,32 @@
     // Ensure the file exists. Need to normalize path separators since on
     // Windows they can come out as forward slashes here, and that confuses some
     // of the commands.
+    BuildSettings build_settings = setup.build_settings();
     base::FilePath arg_file =
-        setup.build_settings().GetFullPath(setup.GetBuildArgFile())
-        .NormalizePathSeparators();
+        build_settings.GetFullPath(setup.GetBuildArgFile())
+            .NormalizePathSeparators();
     if (!base::PathExists(arg_file)) {
       std::string argfile_default_contents =
-          "# Build arguments go here. Examples:\n"
-          "#   is_component_build = true\n"
-          "#   is_debug = false\n"
+          "# Build arguments go here.\n"
           "# See \"gn args <out_dir> --list\" for available build "
           "arguments.\n";
+
+      SourceFile template_path = build_settings.arg_file_template_path();
+      if (!template_path.is_null()) {
+        base::FilePath full_path =
+            build_settings.GetFullPath(template_path).NormalizePathSeparators();
+        if (!base::PathExists(full_path)) {
+          Err err =
+              Err(Location(), std::string("Can't load arg_file_template:\n  ") +
+                                  template_path.value());
+          err.PrintToStdout();
+          return 1;
+        }
+
+        // Ignore the return code; if the read fails (unlikely), we'll just
+        // use the default contents.
+        base::ReadFileToString(full_path, &argfile_default_contents);
+      }
 #if defined(OS_WIN)
       // Use Windows lineendings for this file since it will often open in
       // Notepad which can't handle Unix ones.
diff --git a/tools/gn/command_desc.cc b/tools/gn/command_desc.cc
index 1de9fbb..8e4ebd7 100644
--- a/tools/gn/command_desc.cc
+++ b/tools/gn/command_desc.cc
@@ -85,7 +85,7 @@
   const base::ListValue* list;
   if (value->GetAsList(&list)) {
     if (list->empty()) {
-      base::StringValue str("(no visibility)");
+      base::Value str("(no visibility)");
       DefaultHandler(name, &str);
     } else {
       DefaultHandler(name, value);
@@ -97,7 +97,7 @@
   std::string p;
   if (value->GetAsString(&p)) {
     if (p == "*") {
-      base::StringValue str("[All headers listed in the sources are public.]");
+      base::Value str("[All headers listed in the sources are public.]");
       DefaultHandler(name, &str);
       return;
     }
diff --git a/tools/gn/desc_builder.cc b/tools/gn/desc_builder.cc
index a1a5710..c04fad6 100644
--- a/tools/gn/desc_builder.cc
+++ b/tools/gn/desc_builder.cc
@@ -123,17 +123,17 @@
 
   ValuePtr RenderValue(const std::string& s, bool optional = false) {
     return (s.empty() && optional) ? base::Value::CreateNullValue()
-                                   : ValuePtr(new base::StringValue(s));
+                                   : ValuePtr(new base::Value(s));
   }
 
   ValuePtr RenderValue(const SourceDir& d) {
     return d.is_null() ? base::Value::CreateNullValue()
-                       : ValuePtr(new base::StringValue(FormatSourceDir(d)));
+                       : ValuePtr(new base::Value(FormatSourceDir(d)));
   }
 
   ValuePtr RenderValue(const SourceFile& f) {
     return f.is_null() ? base::Value::CreateNullValue()
-                       : ValuePtr(new base::StringValue(f.value()));
+                       : ValuePtr(new base::Value(f.value()));
   }
 
   ValuePtr RenderValue(const LibFile& lib) {
@@ -679,7 +679,7 @@
         // Indent string values in blame mode
         if (blame_ && rendered->GetAsString(&str)) {
           str = "  " + str;
-          rendered = base::MakeUnique<base::StringValue>(str);
+          rendered = base::MakeUnique<base::Value>(str);
         }
         res->Append(std::move(rendered));
       }
diff --git a/tools/gn/docs/reference.md b/tools/gn/docs/reference.md
index 97a2c86..db5c341 100644
--- a/tools/gn/docs/reference.md
+++ b/tools/gn/docs/reference.md
@@ -3893,7 +3893,7 @@
 
   This should be set to the most specific value possible. So, "android" or
   "chromeos" should be used instead of "linux" where applicable, even though
-  Android and Chrome OS are both Linux variants. This can mean that one needs to
+  Android and ChromeOS are both Linux variants. This can mean that one needs to
   write
 
       if (target_os == "android" || target_os == "linux") {
@@ -5307,12 +5307,28 @@
   config applying to this target specifies this value. In addition, the tool
   corresponding to the source files must also specify precompiled headers (see
   "gn help tool"). The tool will also specify what type of precompiled headers
-  to use.
+  to use, by setting precompiled_header_type to either "gcc" or "msvc".
 
   The precompiled header/source variables can be specified on a target or a
   config, but must be the same for all configs applying to a given target since
   a target can only have one precompiled header.
 
+  If you use both C and C++ sources, the precompiled header and source file
+  will be compiled once per language. You will want to make sure to wrap C++
+  includes in __cplusplus #ifdefs so the file will compile in C mode.
+
+```
+
+### **GCC precompiled headers**
+
+```
+  When using GCC-style precompiled headers, "precompiled_source" contains the
+  path of a .h file that is precompiled and then included by all source files
+  in targets that set "precompiled_source".
+
+  The value of "precompiled_header" is not used with GCC-style precompiled
+  headers.
+
 ```
 
 ### **MSVC precompiled headers**
@@ -5320,8 +5336,8 @@
 ```
   When using MSVC-style precompiled headers, the "precompiled_header" value is
   a string corresponding to the header. This is NOT a path to a file that GN
-  recognises, but rather the exact string that appears in quotes after an
-  #include line in source code. The compiler will match this string against
+  recognises, but rather the exact string that appears in quotes after
+  an #include line in source code. The compiler will match this string against
   includes or forced includes (/FI).
 
   MSVC also requires a source file to compile the header with. This must be
@@ -5329,10 +5345,6 @@
   this IS a GN-style file name, and tells GN which source file to compile to
   make the .pch file used for subsequent compiles.
 
-  If you use both C and C++ sources, the precompiled header and source file
-  will be compiled using both tools. You will want to make sure to wrap C++
-  includes in __cplusplus #ifdefs so the file will compile in C mode.
-
   For example, if the toolchain specifies MSVC headers:
 
     toolchain("vc_x64") {
@@ -5360,6 +5372,13 @@
 
 
 ```
+## **precompiled_header_type**: [string] "gcc" or "msvc".
+
+```
+  See "gn help precompiled_header".
+
+
+```
 ## **precompiled_source**: [file name] Source file to precompile.
 
 ```
@@ -5796,8 +5815,12 @@
 ### **Variables**
 
 ```
+  arg_file_template [optional]
+      Path to a file containing the text that should be used as the default
+      args.gn content when you run `gn args`.
+
   buildconfig [required]
-      Label of the build config file. This file will be used to set up the
+      Path to the build config file. This file will be used to set up the
       build file execution environment for each toolchain.
 
   check_targets [optional]
diff --git a/tools/gn/setup.cc b/tools/gn/setup.cc
index 5c4e9842..2c2ba38 100644
--- a/tools/gn/setup.cc
+++ b/tools/gn/setup.cc
@@ -58,8 +58,12 @@
 
 Variables
 
+  arg_file_template [optional]
+      Path to a file containing the text that should be used as the default
+      args.gn content when you run `gn args`.
+
   buildconfig [required]
-      Label of the build config file. This file will be used to set up the
+      Path to the build config file. This file will be used to set up the
       build file execution environment for each toolchain.
 
   check_targets [optional]
@@ -790,5 +794,16 @@
     default_args_ = default_args_value->scope_value();
   }
 
+  const Value* arg_file_template_value =
+      dotfile_scope_.GetValue("arg_file_template", true);
+  if (arg_file_template_value) {
+    if (!arg_file_template_value->VerifyTypeIs(Value::STRING, &err)) {
+      err.PrintToStdout();
+      return false;
+    }
+    SourceFile path(arg_file_template_value->string_value());
+    build_settings_.set_arg_file_template_path(path);
+  }
+
   return true;
 }
diff --git a/tools/ipc_fuzzer/fuzzer/fuzzer.cc b/tools/ipc_fuzzer/fuzzer/fuzzer.cc
index 8efc54741..eac733f 100644
--- a/tools/ipc_fuzzer/fuzzer/fuzzer.cc
+++ b/tools/ipc_fuzzer/fuzzer/fuzzer.cc
@@ -530,7 +530,7 @@
           std::string tmp;
           p->GetString(index, &tmp);
           fuzzer->FuzzString(&tmp);
-          p->Set(index, new base::StringValue(tmp));
+          p->Set(index, new base::Value(tmp));
           break;
         }
         case base::Value::Type::BINARY: {
@@ -599,7 +599,7 @@
         case base::Value::Type::STRING: {
           std::string tmp;
           fuzzer->FuzzString(&tmp);
-          p->SetWithoutPathExpansion(property, new base::StringValue(tmp));
+          p->SetWithoutPathExpansion(property, new base::Value(tmp));
           break;
         }
         case base::Value::Type::BINARY: {
diff --git a/tools/json_schema_compiler/cc_generator.py b/tools/json_schema_compiler/cc_generator.py
index b653a9c..26cab363 100644
--- a/tools/json_schema_compiler/cc_generator.py
+++ b/tools/json_schema_compiler/cc_generator.py
@@ -567,7 +567,7 @@
 
     var: variable or variable*
 
-    E.g for std::string, generate new base::StringValue(var)
+    E.g for std::string, generate new base::Value(var)
     """
     c = Code()
     underlying_type = self._type_helper.FollowRef(type_)
@@ -631,7 +631,7 @@
       maybe_namespace = ''
       if type_.property_type == PropertyType.REF:
         maybe_namespace = '%s::' % underlying_type.namespace.unix_name
-      return 'base::MakeUnique<base::StringValue>(%sToString(%s))' % (
+      return 'base::MakeUnique<base::Value>(%sToString(%s))' % (
           maybe_namespace, var)
     elif underlying_type.property_type == PropertyType.BINARY:
       if is_ptr:
@@ -648,7 +648,7 @@
       if is_ptr:
         var = '*%s' % var
       if underlying_type.property_type == PropertyType.STRING:
-        return 'base::MakeUnique<base::StringValue>(%s)' % var
+        return 'base::MakeUnique<base::Value>(%s)' % var
       else:
         return 'base::MakeUnique<base::Value>(%s)' % var
     else:
diff --git a/tools/json_schema_compiler/test/any_unittest.cc b/tools/json_schema_compiler/test/any_unittest.cc
index 33da1ba..9010ffc 100644
--- a/tools/json_schema_compiler/test/any_unittest.cc
+++ b/tools/json_schema_compiler/test/any_unittest.cc
@@ -38,7 +38,7 @@
   }
   {
     std::unique_ptr<base::ListValue> params_value(new base::ListValue());
-    std::unique_ptr<base::Value> param(new base::StringValue("asdf"));
+    std::unique_ptr<base::Value> param(new base::Value("asdf"));
     params_value->Append(param->CreateDeepCopy());
     std::unique_ptr<OptionalAny::Params> params(
         OptionalAny::Params::Create(*params_value));
diff --git a/tools/json_schema_compiler/test/choices_unittest.cc b/tools/json_schema_compiler/test/choices_unittest.cc
index 584641c..35ec229 100644
--- a/tools/json_schema_compiler/test/choices_unittest.cc
+++ b/tools/json_schema_compiler/test/choices_unittest.cc
@@ -46,8 +46,8 @@
 TEST(JsonSchemaCompilerChoicesTest, ObjectWithChoicesParamsCreate) {
   {
     std::unique_ptr<ObjectWithChoices::Params> params(
-        ObjectWithChoices::Params::Create(*List(
-            Dictionary("strings", new base::StringValue("asdf")).release())));
+        ObjectWithChoices::Params::Create(
+            *List(Dictionary("strings", new base::Value("asdf")).release())));
     ASSERT_TRUE(params);
     EXPECT_FALSE(params->string_info.strings.as_strings);
     EXPECT_EQ("asdf", *params->string_info.strings.as_string);
@@ -56,8 +56,8 @@
   {
     std::unique_ptr<ObjectWithChoices::Params> params(
         ObjectWithChoices::Params::Create(
-            *List(Dictionary("strings", new base::StringValue("asdf"),
-                             "integers", new base::Value(6))
+            *List(Dictionary("strings", new base::Value("asdf"), "integers",
+                             new base::Value(6))
                       .release())));
     ASSERT_TRUE(params);
     EXPECT_FALSE(params->string_info.strings.as_strings);
@@ -85,10 +85,8 @@
   {
     std::unique_ptr<base::DictionaryValue> object_param(
         new base::DictionaryValue());
-    object_param->SetWithoutPathExpansion("strings",
-                                          new base::StringValue("asdf"));
-    object_param->SetWithoutPathExpansion("integers",
-                                          new base::StringValue("asdf"));
+    object_param->SetWithoutPathExpansion("strings", new base::Value("asdf"));
+    object_param->SetWithoutPathExpansion("integers", new base::Value("asdf"));
     std::unique_ptr<base::ListValue> params_value(new base::ListValue());
     params_value->Append(std::move(object_param));
     std::unique_ptr<ObjectWithChoices::Params> params(
diff --git a/tools/json_schema_compiler/test/crossref_unittest.cc b/tools/json_schema_compiler/test/crossref_unittest.cc
index 75406ea..21e52aa 100644
--- a/tools/json_schema_compiler/test/crossref_unittest.cc
+++ b/tools/json_schema_compiler/test/crossref_unittest.cc
@@ -18,7 +18,7 @@
   std::unique_ptr<base::DictionaryValue> value(new base::DictionaryValue());
   value->Set("number", new base::Value(1.1));
   value->Set("integer", new base::Value(4));
-  value->Set("string", new base::StringValue("bling"));
+  value->Set("string", new base::Value("bling"));
   value->Set("boolean", new base::Value(true));
   return value;
 }
@@ -28,8 +28,8 @@
 TEST(JsonSchemaCompilerCrossrefTest, CrossrefTypePopulateAndToValue) {
   base::DictionaryValue crossref_orig;
   crossref_orig.Set("testType", CreateTestTypeValue().release());
-  crossref_orig.Set("testEnumRequired", new base::StringValue("one"));
-  crossref_orig.Set("testEnumOptional", new base::StringValue("two"));
+  crossref_orig.Set("testEnumRequired", new base::Value("one"));
+  crossref_orig.Set("testEnumOptional", new base::Value("two"));
 
   // Test Populate of the value --> compiled type.
   crossref::CrossrefType crossref_type;
@@ -115,7 +115,7 @@
     std::unique_ptr<base::ListValue> params_value(new base::ListValue());
     std::unique_ptr<base::DictionaryValue> param_object_value(
         new base::DictionaryValue());
-    param_object_value->Set("testType", new base::StringValue("invalid"));
+    param_object_value->Set("testType", new base::Value("invalid"));
     param_object_value->Set("boolean", new base::Value(true));
     params_value->Append(std::move(param_object_value));
     std::unique_ptr<crossref::TestTypeInObject::Params> params(
diff --git a/tools/json_schema_compiler/test/enums_unittest.cc b/tools/json_schema_compiler/test/enums_unittest.cc
index d5ba3250..5318981 100644
--- a/tools/json_schema_compiler/test/enums_unittest.cc
+++ b/tools/json_schema_compiler/test/enums_unittest.cc
@@ -14,7 +14,7 @@
   {
     EnumType enum_type;
     base::DictionaryValue value;
-    value.Set("type", new base::StringValue("one"));
+    value.Set("type", new base::Value("one"));
     EXPECT_TRUE(EnumType::Populate(value, &enum_type));
     EXPECT_EQ(ENUMERATION_ONE, enum_type.type);
     EXPECT_TRUE(value.Equals(enum_type.ToValue().get()));
@@ -22,7 +22,7 @@
   {
     EnumType enum_type;
     base::DictionaryValue value;
-    value.Set("type", new base::StringValue("invalid"));
+    value.Set("type", new base::Value("invalid"));
     EXPECT_FALSE(EnumType::Populate(value, &enum_type));
   }
 }
@@ -50,11 +50,11 @@
     base::DictionaryValue value;
     ASSERT_FALSE(HasEnumeration::Populate(value, &enumeration));
 
-    value.Set("enumeration", new base::StringValue("one"));
+    value.Set("enumeration", new base::Value("one"));
     ASSERT_TRUE(HasEnumeration::Populate(value, &enumeration));
     EXPECT_TRUE(value.Equals(enumeration.ToValue().get()));
 
-    value.Set("optional_enumeration", new base::StringValue("two"));
+    value.Set("optional_enumeration", new base::Value("two"));
     ASSERT_TRUE(HasEnumeration::Populate(value, &enumeration));
     EXPECT_TRUE(value.Equals(enumeration.ToValue().get()));
   }
@@ -63,7 +63,7 @@
     base::DictionaryValue value;
     ASSERT_FALSE(ReferenceEnum::Populate(value, &enumeration));
 
-    value.Set("reference_enum", new base::StringValue("one"));
+    value.Set("reference_enum", new base::Value("one"));
     ASSERT_TRUE(ReferenceEnum::Populate(value, &enumeration));
     EXPECT_TRUE(value.Equals(enumeration.ToValue().get()));
   }
@@ -72,8 +72,7 @@
 TEST(JsonSchemaCompilerEnumsTest, EnumsArrayAsType) {
   {
     base::ListValue params_value;
-    params_value.Append(
-        List(new base::StringValue("one"), new base::StringValue("two")));
+    params_value.Append(List(new base::Value("one"), new base::Value("two")));
     std::unique_ptr<TakesEnumArrayAsType::Params> params(
         TakesEnumArrayAsType::Params::Create(params_value));
     ASSERT_TRUE(params);
@@ -83,7 +82,7 @@
   }
   {
     base::ListValue params_value;
-    params_value.Append(List(new base::StringValue("invalid")));
+    params_value.Append(List(new base::Value("invalid")));
     std::unique_ptr<TakesEnumArrayAsType::Params> params(
         TakesEnumArrayAsType::Params::Create(params_value));
     EXPECT_FALSE(params);
@@ -93,8 +92,8 @@
 TEST(JsonSchemaCompilerEnumsTest, ReturnsEnumCreate) {
   {
     Enumeration state = ENUMERATION_ONE;
-    std::unique_ptr<base::Value> result(new base::StringValue(ToString(state)));
-    std::unique_ptr<base::Value> expected(new base::StringValue("one"));
+    std::unique_ptr<base::Value> result(new base::Value(ToString(state)));
+    std::unique_ptr<base::Value> expected(new base::Value("one"));
     EXPECT_TRUE(result->Equals(expected.get()));
   }
   {
@@ -122,7 +121,7 @@
   {
     OptionalEnumType enum_type;
     base::DictionaryValue value;
-    value.Set("type", new base::StringValue("two"));
+    value.Set("type", new base::Value("two"));
     EXPECT_TRUE(OptionalEnumType::Populate(value, &enum_type));
     EXPECT_EQ(ENUMERATION_TWO, enum_type.type);
     EXPECT_TRUE(value.Equals(enum_type.ToValue().get()));
@@ -137,7 +136,7 @@
   {
     OptionalEnumType enum_type;
     base::DictionaryValue value;
-    value.Set("type", new base::StringValue("invalid"));
+    value.Set("type", new base::Value("invalid"));
     EXPECT_FALSE(OptionalEnumType::Populate(value, &enum_type));
   }
 }
@@ -163,8 +162,7 @@
 TEST(JsonSchemaCompilerEnumsTest, TakesEnumArrayParamsCreate) {
   {
     base::ListValue params_value;
-    params_value.Append(
-        List(new base::StringValue("one"), new base::StringValue("two")));
+    params_value.Append(List(new base::Value("one"), new base::Value("two")));
     std::unique_ptr<TakesEnumArray::Params> params(
         TakesEnumArray::Params::Create(params_value));
     ASSERT_TRUE(params);
@@ -174,7 +172,7 @@
   }
   {
     base::ListValue params_value;
-    params_value.Append(List(new base::StringValue("invalid")));
+    params_value.Append(List(new base::Value("invalid")));
     std::unique_ptr<TakesEnumArray::Params> params(
         TakesEnumArray::Params::Create(params_value));
     EXPECT_FALSE(params);
@@ -247,9 +245,8 @@
 TEST(JsonSchemaCompilerEnumsTest, OnEnumFiredCreate) {
   {
     Enumeration some_enum = ENUMERATION_ONE;
-    std::unique_ptr<base::Value> result(
-        new base::StringValue(ToString(some_enum)));
-    std::unique_ptr<base::Value> expected(new base::StringValue("one"));
+    std::unique_ptr<base::Value> result(new base::Value(ToString(some_enum)));
+    std::unique_ptr<base::Value> expected(new base::Value("one"));
     EXPECT_TRUE(result->Equals(expected.get()));
   }
   {
diff --git a/tools/json_schema_compiler/test/error_generation_unittest.cc b/tools/json_schema_compiler/test/error_generation_unittest.cc
index 7812be62..e55ecb9 100644
--- a/tools/json_schema_compiler/test/error_generation_unittest.cc
+++ b/tools/json_schema_compiler/test/error_generation_unittest.cc
@@ -36,7 +36,7 @@
 TEST(JsonSchemaCompilerErrorTest, RequiredPropertyPopulate) {
   {
     std::unique_ptr<base::DictionaryValue> value =
-        Dictionary("string", new base::StringValue("bling"));
+        Dictionary("string", new base::Value("bling"));
     EXPECT_TRUE(EqualsUtf16("", GetPopulateError<TestType>(*value)));
   }
   {
@@ -113,7 +113,7 @@
 TEST(JsonSchemaCompilerErrorTest, WrongPropertyValueType) {
   {
     std::unique_ptr<base::DictionaryValue> value =
-        Dictionary("string", new base::StringValue("yes"));
+        Dictionary("string", new base::Value("yes"));
     EXPECT_TRUE(EqualsUtf16("", GetPopulateError<TestType>(*value)));
   }
   {
@@ -128,7 +128,7 @@
   {
     base::string16 error;
     std::unique_ptr<base::ListValue> params_value =
-        List(new base::StringValue("Yeah!"));
+        List(new base::Value("Yeah!"));
     EXPECT_TRUE(TestString::Params::Create(*params_value, &error));
   }
   {
@@ -205,12 +205,12 @@
 TEST(JsonSchemaCompilerErrorTest, BadEnumValue) {
   {
     std::unique_ptr<base::DictionaryValue> value =
-        Dictionary("enumeration", new base::StringValue("one"));
+        Dictionary("enumeration", new base::Value("one"));
     EXPECT_TRUE(EqualsUtf16("", GetPopulateError<HasEnumeration>(*value)));
   }
   {
     std::unique_ptr<base::DictionaryValue> value =
-        Dictionary("enumeration", new base::StringValue("bad sauce"));
+        Dictionary("enumeration", new base::Value("bad sauce"));
     EXPECT_TRUE(EqualsUtf16("'Enumeration': expected \"one\" or \"two\" "
               "or \"three\", got \"bad sauce\"",
         GetPopulateError<HasEnumeration>(*value)));
@@ -222,7 +222,7 @@
 TEST(JsonSchemaCompilerErrorTest, WarnOnOptionalFailure) {
   {
     std::unique_ptr<base::DictionaryValue> value =
-        Dictionary("string", new base::StringValue("bling"));
+        Dictionary("string", new base::Value("bling"));
     EXPECT_TRUE(EqualsUtf16("", GetPopulateError<OptionalTestType>(*value)));
   }
   {
@@ -318,13 +318,13 @@
 TEST(JsonSchemaCompilerErrorTest, TooManyKeys) {
   {
     std::unique_ptr<base::DictionaryValue> value =
-        Dictionary("string", new base::StringValue("yes"));
+        Dictionary("string", new base::Value("yes"));
     EXPECT_TRUE(EqualsUtf16("", GetPopulateError<TestType>(*value)));
   }
   {
     std::unique_ptr<base::DictionaryValue> value =
-        Dictionary("string", new base::StringValue("yes"), "ohno",
-                   new base::StringValue("many values"));
+        Dictionary("string", new base::Value("yes"), "ohno",
+                   new base::Value("many values"));
     EXPECT_TRUE(EqualsUtf16("found unexpected key 'ohno'",
         GetPopulateError<TestType>(*value)));
   }
diff --git a/tools/json_schema_compiler/test/simple_api_unittest.cc b/tools/json_schema_compiler/test/simple_api_unittest.cc
index b79e3bc..29d7637 100644
--- a/tools/json_schema_compiler/test/simple_api_unittest.cc
+++ b/tools/json_schema_compiler/test/simple_api_unittest.cc
@@ -14,7 +14,7 @@
   std::unique_ptr<base::DictionaryValue> value(new base::DictionaryValue());
   value->SetWithoutPathExpansion("number", new base::Value(1.1));
   value->SetWithoutPathExpansion("integer", new base::Value(4));
-  value->SetWithoutPathExpansion("string", new base::StringValue("bling"));
+  value->SetWithoutPathExpansion("string", new base::Value("bling"));
   value->SetWithoutPathExpansion("boolean", new base::Value(true));
   return value;
 }
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index 9d128cf..4ac66145 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -241,6 +241,7 @@
       'Android Release (Nexus 6P)': 'android_release_trybot_arm64',
       'Android Release (Nexus 9)': 'android_release_trybot_arm64',
       'Android Release (Pixel C)': 'android_release_trybot_arm64',
+      'Android Release (NVIDIA Shield)': 'android_release_trybot',
       'GPU Linux Builder (dbg)': 'gpu_fyi_tests_debug_trybot',
       'GPU Linux Builder': 'gpu_fyi_tests_release_trybot',
       'GPU Mac Builder': 'gpu_fyi_tests_release_trybot',
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 4fd60561d..da1f11b 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -26053,10 +26053,18 @@
 </histogram>
 
 <histogram name="Media.Duration" units="ms">
+  <obsolete>
+    Removed 03/2017 in favor of Media.Duration2 with larger max bucket.
+  </obsolete>
   <owner>scherkus@chromium.org</owner>
   <summary>Duration in milliseconds of HTML5 media (when known).</summary>
 </histogram>
 
+<histogram name="Media.Duration2" units="ms">
+  <owner>dalecurtis@chromium.org</owner>
+  <summary>Duration in milliseconds of HTML5 media (when known).</summary>
+</histogram>
+
 <histogram name="Media.EME.CdmFileIO.FileSizeKBOnError" units="KB">
   <owner>xhwang@chromium.org</owner>
   <summary>
@@ -29057,6 +29065,33 @@
   </summary>
 </histogram>
 
+<histogram name="Mobile.SystemNotification.Blocked"
+    enum="SystemNotificationType">
+  <owner>dtrainor@chromium.org</owner>
+  <summary>
+    Android: Represents the number of system notifications that were blocked and
+    could not be shown by type.
+  </summary>
+</histogram>
+
+<histogram name="Mobile.SystemNotification.BlockedAfterShown"
+    enum="SystemNotificationType">
+  <owner>dtrainor@chromium.org</owner>
+  <summary>
+    Android: Represents the type of notification that was last shown before the
+    user disabled notification permissions on Chrome.  This is only logged the
+    first time we attempt to show a notification and fail.
+  </summary>
+</histogram>
+
+<histogram name="Mobile.SystemNotification.Shown" enum="SystemNotificationType">
+  <owner>dtrainor@chromium.org</owner>
+  <summary>
+    Android: Represents the number of system notifications that will be
+    successfully shown to the user by type.
+  </summary>
+</histogram>
+
 <histogram name="MobileDownload.BytesDownloaded" units="KB">
   <owner>qinmin@chromium.org</owner>
   <summary>
@@ -63891,6 +63926,15 @@
   </summary>
 </histogram>
 
+<histogram name="Settings.TimeUntilInteractive" units="ms">
+  <owner>dbeam@chromium.org</owner>
+  <summary>
+    The time until the settings Web UI is loaded, rendered, and interactive for
+    users (as in they can change a setting). Automatically logged each time the
+    settings page is opened (if not closed before interactive).
+  </summary>
+</histogram>
+
 <histogram name="Settings.TrackedPreferenceChanged" enum="TrackedPreference">
   <owner>gab@chromium.org</owner>
   <summary>
@@ -88430,7 +88474,7 @@
   <int value="333" label="EnableMediaRouter"/>
   <int value="334" label="DHEEnabled"/>
   <int value="335" label="CertificateTransparencyEnforcementDisabledForUrls"/>
-  <int value="336" label="LoginApps"/>
+  <int value="336" label="DeviceLoginScreenAppInstallList"/>
   <int value="337" label="ArcBackupRestoreEnabled"/>
   <int value="338" label="NTPContentSuggestionsEnabled"/>
   <int value="339" label="WebRtcUdpPortRange"/>
@@ -88460,6 +88504,7 @@
   <int value="363" label="ArcLocationServiceEnabled"/>
   <int value="364" label="DeviceLoginScreenLocales"/>
   <int value="365" label="DeviceLoginScreenInputMethods"/>
+  <int value="366" label="EnableCommonNameFallbackForLocalAnchors"/>
 </enum>
 
 <enum name="EnterprisePolicyInvalidations" type="int">
@@ -92981,6 +93026,7 @@
   <int value="1846" label="ScrollByKeyboardSpacebarKey"/>
   <int value="1847" label="ScrollByTouch"/>
   <int value="1848" label="ScrollByWheel"/>
+  <int value="1849" label="ScheduledActionIgnored"/>
 </enum>
 
 <enum name="FetchRequestMode" type="int">
@@ -110975,6 +111021,12 @@
   <int value="25" label="VPN"/>
 </enum>
 
+<enum name="SystemNotificationType" type="int">
+  <int value="0" label="Downloads - Files"/>
+  <int value="1" label="Downloads - Pages"/>
+  <int value="2" label="Close Incognito Tabs"/>
+</enum>
+
 <enum name="TabBackgroundLoadStatus" type="int">
   <int value="0" label="Loaded on creation and shown"/>
   <int value="1" label="Loaded on creation and lost"/>
diff --git a/tools/origin_trials/generate_token.py b/tools/origin_trials/generate_token.py
index a79f169..35ca521 100755
--- a/tools/origin_trials/generate_token.py
+++ b/tools/origin_trials/generate_token.py
@@ -179,6 +179,7 @@
   print " Is Subdomain: %s" % args.is_subdomain
   print " Feature: %s" % args.trial_name
   print " Expiry: %d (%s UTC)" % (expiry, datetime.utcfromtimestamp(expiry))
+  print " Signature: %s" % ", ".join('0x%02x' % ord(x) for x in signature)
   print
 
   # Output the properly-formatted token.
diff --git a/tools/perf/benchmarks/media.py b/tools/perf/benchmarks/media.py
index 4ba2e0a1e..c5c6ba6 100644
--- a/tools/perf/benchmarks/media.py
+++ b/tools/perf/benchmarks/media.py
@@ -38,9 +38,8 @@
 
 
 # android: See media.android.tough_video_cases below
-# win8: crbug.com/531618
 # crbug.com/565180: Only include cases that report time_to_play
-@benchmark.Disabled('android', 'win8')
+@benchmark.Disabled('android')
 class Media(perf_benchmark.PerfBenchmark):
   """Obtains media metrics for key user scenarios."""
   test = media.Media
@@ -52,7 +51,7 @@
 
 
 # crbug.com/565180: Only include cases that don't report time_to_play
-@benchmark.Disabled('android', 'win8')
+@benchmark.Disabled('android')
 class MediaExtra(perf_benchmark.PerfBenchmark):
   """Obtains extra media metrics for key user scenarios."""
   test = media.Media
diff --git a/tools/perf/page_sets/data/system_health_desktop.json b/tools/perf/page_sets/data/system_health_desktop.json
index 35f5945..a542d44 100644
--- a/tools/perf/page_sets/data/system_health_desktop.json
+++ b/tools/perf/page_sets/data/system_health_desktop.json
@@ -171,6 +171,9 @@
         "long_running:tools:gmail-foreground": {
             "DEFAULT": "system_health_desktop_028.wpr"
         },
+        "multitab:misc:typical24": {
+            "DEFAULT": "system_health_desktop_048.wpr"
+        },
         "play:media:google_play_music": {
             "DEFAULT": "system_health_desktop_030.wpr"
         },
@@ -186,4 +189,4 @@
     },
     "description": "Describes the Web Page Replay archives for a story set. Don't edit by hand! Use record_wpr for updating.",
     "platform_specific": true
-}
\ No newline at end of file
+}
diff --git a/tools/perf/page_sets/data/system_health_desktop_048.wpr.sha1 b/tools/perf/page_sets/data/system_health_desktop_048.wpr.sha1
new file mode 100644
index 0000000..4ff3d4e1
--- /dev/null
+++ b/tools/perf/page_sets/data/system_health_desktop_048.wpr.sha1
@@ -0,0 +1 @@
+420bd07a02c3966d5945cebf32417a5832764626
diff --git a/tools/perf/page_sets/system_health/multi_tab_stories.py b/tools/perf/page_sets/system_health/multi_tab_stories.py
new file mode 100644
index 0000000..f472a6be
--- /dev/null
+++ b/tools/perf/page_sets/system_health/multi_tab_stories.py
@@ -0,0 +1,81 @@
+# Copyright 2017 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 py_utils
+import logging
+
+from page_sets.system_health import system_health_story
+from page_sets.system_health import story_tags
+from page_sets.system_health import platforms
+
+
+class _MultiTabStory(system_health_story.SystemHealthStory):
+  ABSTRACT_STORY = True
+
+  def RunNavigateSteps(self, action_runner):
+    tabs = action_runner.tab.browser.tabs
+
+    # No need to create the first tab as there is already one
+    # when the browser is ready,
+    if self.URL_LIST:
+      action_runner.Navigate(self.URL_LIST[0])
+    for url in self.URL_LIST[1:]:
+      new_tab = tabs.New()
+      new_tab.action_runner.Navigate(url)
+
+    for i, url in enumerate(self.URL_LIST):
+      try:
+        tabs[i].action_runner.WaitForNetworkQuiescence()
+      except py_utils.TimeoutException:
+        logging.warning('WaitForNetworkQuiescence() timeout, url[%d]: %s'
+                        % (i, url))
+
+  def RunPageInteractions(self, action_runner):
+    for tab in action_runner.tab.browser.tabs:
+      tab.Activate()
+      tab.WaitForFrameToBeDisplayed()
+
+
+class MultiTabTypical24Story(_MultiTabStory):
+  NAME = 'multitab:misc:typical24'
+  TAGS = [story_tags.TABS_SWITCHING]
+  URL_LIST = [
+    # Why: Alexa games #48
+    'http://www.nick.com/games',
+    # Why: Alexa sports #45
+    'http://www.rei.com/',
+    # Why: Alexa sports #50
+    'http://www.fifa.com/',
+    # Why: Alexa shopping #41
+    'http://www.gamestop.com/ps3',
+    # Why: Alexa news #55
+    ('http://www.economist.com/news/science-and-technology/21573529-small-'
+     'models-cosmic-phenomena-are-shedding-light-real-thing-how-build'),
+    # Why: Alexa news #67
+    'http://www.theonion.com',
+    'http://arstechnica.com/',
+    # Why: Alexa home #10
+    'http://allrecipes.com/Recipe/Pull-Apart-Hot-Cross-Buns/Detail.aspx',
+    'http://www.html5rocks.com/en/',
+    'http://www.mlb.com/',
+    'http://gawker.com/5939683/based-on-a-true-story-is-a-rotten-lie-i-hope-you-never-believe',
+    'http://www.imdb.com/title/tt0910970/',
+    'http://www.flickr.com/search/?q=monkeys&f=hp',
+    'http://money.cnn.com/',
+    'http://www.nationalgeographic.com/',
+    'http://premierleague.com',
+    'http://www.osubeavers.com/',
+    'http://walgreens.com',
+    'http://colorado.edu',
+    ('http://www.ticketmaster.com/JAY-Z-and-Justin-Timberlake-tickets/artist/'
+     '1837448?brand=none&tm_link=tm_homeA_rc_name2'),
+    # pylint: disable=line-too-long
+    'http://www.theverge.com/2013/3/5/4061684/inside-ted-the-smartest-bubble-in-the-world',
+    'http://www.airbnb.com/',
+    'http://www.ign.com/',
+    # Why: Alexa health #25
+    'http://www.fda.gov',
+  ]
+  URL = URL_LIST[0]
+  SUPPORTED_PLATFORMS = platforms.DESKTOP_ONLY
diff --git a/tools/win/DebugVisualizers/chrome.natvis b/tools/win/DebugVisualizers/chrome.natvis
index fc9f9a9..8ed8e1d 100644
--- a/tools/win/DebugVisualizers/chrome.natvis
+++ b/tools/win/DebugVisualizers/chrome.natvis
@@ -237,7 +237,7 @@
       <Item Name="Double">double_value_</Item>
     </Expand>
   </Type>
-  <Type Name="base::StringValue">
+  <Type Name="base::Value">
     <DisplayString>String ({value_})</DisplayString>
     <Expand>
       <ExpandedItem>(base::Value*)this,nd</ExpandedItem>
diff --git a/ui/arc/notification/arc_custom_notification_item.cc b/ui/arc/notification/arc_custom_notification_item.cc
index 54b194b..d3cac1be 100644
--- a/ui/arc/notification/arc_custom_notification_item.cc
+++ b/ui/arc/notification/arc_custom_notification_item.cc
@@ -25,7 +25,9 @@
 class ArcNotificationDelegate : public message_center::NotificationDelegate {
  public:
   explicit ArcNotificationDelegate(ArcCustomNotificationItem* item)
-      : item_(item) {}
+      : item_(item) {
+    DCHECK(item_);
+  }
 
   std::unique_ptr<message_center::CustomContent> CreateCustomContent()
       override {
@@ -35,6 +37,8 @@
         std::move(view), std::move(content_view_delegate));
   }
 
+  void Close(bool by_user) override { item_->Close(by_user); }
+
  private:
   // The destructor is private since this class is ref-counted.
   ~ArcNotificationDelegate() override {}
@@ -109,13 +113,6 @@
   AddToMessageCenter();
 }
 
-void ArcCustomNotificationItem::CloseFromCloseButton() {
-  // Needs to manually remove notification from MessageCenter because
-  // the floating close button is not part of MessageCenter.
-  message_center()->RemoveNotification(notification_id(), true);
-  Close(true);
-}
-
 void ArcCustomNotificationItem::AddObserver(Observer* observer) {
   observers_.AddObserver(observer);
 }
diff --git a/ui/arc/notification/arc_custom_notification_view.cc b/ui/arc/notification/arc_custom_notification_view.cc
index 5367000a..6b509af 100644
--- a/ui/arc/notification/arc_custom_notification_view.cc
+++ b/ui/arc/notification/arc_custom_notification_view.cc
@@ -496,12 +496,18 @@
 }
 
 void ArcCustomNotificationView::OnFocus() {
+  CHECK_EQ(message_center::CustomNotificationView::kViewClassName,
+           parent()->GetClassName());
+
   NativeViewHost::OnFocus();
   static_cast<message_center::CustomNotificationView*>(parent())
       ->OnContentFocused();
 }
 
 void ArcCustomNotificationView::OnBlur() {
+  CHECK_EQ(message_center::CustomNotificationView::kViewClassName,
+           parent()->GetClassName());
+
   NativeViewHost::OnBlur();
   static_cast<message_center::CustomNotificationView*>(parent())
       ->OnContentBlured();
@@ -525,7 +531,10 @@
 void ArcCustomNotificationView::ButtonPressed(views::Button* sender,
                                               const ui::Event& event) {
   if (item_ && !item_->pinned() && sender == close_button_) {
-    item_->CloseFromCloseButton();
+    CHECK_EQ(message_center::CustomNotificationView::kViewClassName,
+             parent()->GetClassName());
+    static_cast<message_center::CustomNotificationView*>(parent())
+        ->OnCloseButtonPressed();
   }
   if (item_ && settings_button_ && sender == settings_button_) {
     item_->OpenSettings();
diff --git a/ui/aura/mus/window_tree_client.cc b/ui/aura/mus/window_tree_client.cc
index 93426157..3328445f 100644
--- a/ui/aura/mus/window_tree_client.cc
+++ b/ui/aura/mus/window_tree_client.cc
@@ -588,7 +588,9 @@
     const gfx::Rect& new_bounds) {
   const uint32_t change_id = ScheduleInFlightChange(
       base::MakeUnique<InFlightBoundsChange>(this, window, old_bounds));
-  tree_->SetWindowBounds(change_id, window->server_id(), new_bounds);
+  // TODO(fsamuel): Allocate a new LocalSurfaceId on size change.
+  tree_->SetWindowBounds(change_id, window->server_id(), new_bounds,
+                         base::nullopt);
 }
 
 void WindowTreeClient::OnWindowMusCreated(WindowMus* window) {
@@ -960,9 +962,11 @@
   DCHECK_EQ(0u, data->parent_id);
 }
 
-void WindowTreeClient::OnWindowBoundsChanged(Id window_id,
-                                             const gfx::Rect& old_bounds,
-                                             const gfx::Rect& new_bounds) {
+void WindowTreeClient::OnWindowBoundsChanged(
+    Id window_id,
+    const gfx::Rect& old_bounds,
+    const gfx::Rect& new_bounds,
+    const base::Optional<cc::LocalSurfaceId>& local_surface_id) {
   WindowMus* window = GetWindowByServerId(window_id);
   if (!window)
     return;
diff --git a/ui/aura/mus/window_tree_client.h b/ui/aura/mus/window_tree_client.h
index 3e42a2e..60abb544 100644
--- a/ui/aura/mus/window_tree_client.h
+++ b/ui/aura/mus/window_tree_client.h
@@ -301,9 +301,11 @@
                          ui::mojom::WindowDataPtr data,
                          int64_t display_id,
                          bool drawn) override;
-  void OnWindowBoundsChanged(Id window_id,
-                             const gfx::Rect& old_bounds,
-                             const gfx::Rect& new_bounds) override;
+  void OnWindowBoundsChanged(
+      Id window_id,
+      const gfx::Rect& old_bounds,
+      const gfx::Rect& new_bounds,
+      const base::Optional<cc::LocalSurfaceId>& local_surface_id) override;
   void OnClientAreaChanged(
       uint32_t window_id,
       const gfx::Insets& new_client_area,
diff --git a/ui/aura/mus/window_tree_client_unittest.cc b/ui/aura/mus/window_tree_client_unittest.cc
index c15f3b7..86f6703 100644
--- a/ui/aura/mus/window_tree_client_unittest.cc
+++ b/ui/aura/mus/window_tree_client_unittest.cc
@@ -43,6 +43,7 @@
 #include "ui/display/screen.h"
 #include "ui/events/event.h"
 #include "ui/events/event_utils.h"
+#include "ui/events/test/test_event_handler.h"
 #include "ui/gfx/geometry/dip_util.h"
 #include "ui/gfx/geometry/rect.h"
 
@@ -275,7 +276,8 @@
   // Simulate the server responding with a bounds change.
   const gfx::Rect server_changed_bounds(gfx::Rect(0, 0, 101, 102));
   window_tree_client()->OnWindowBoundsChanged(
-      server_id(root_window()), original_bounds, server_changed_bounds);
+      server_id(root_window()), original_bounds, server_changed_bounds,
+      base::nullopt);
 
   // This shouldn't trigger the bounds changing yet.
   EXPECT_EQ(new_bounds, root_window()->bounds());
@@ -287,8 +289,9 @@
   EXPECT_EQ(server_changed_bounds, root_window()->bounds());
 
   // Simulate server changing back to original bounds. Should take immediately.
-  window_tree_client()->OnWindowBoundsChanged(
-      server_id(root_window()), server_changed_bounds, original_bounds);
+  window_tree_client()->OnWindowBoundsChanged(server_id(root_window()),
+                                              server_changed_bounds,
+                                              original_bounds, base::nullopt);
   EXPECT_EQ(original_bounds, root_window()->bounds());
 }
 
@@ -536,6 +539,37 @@
   DISALLOW_COPY_AND_ASSIGN(InputEventBasicTestWindowDelegate);
 };
 
+class InputEventBasicTestEventHandler : public ui::test::TestEventHandler {
+ public:
+  InputEventBasicTestEventHandler() {}
+  ~InputEventBasicTestEventHandler() override {}
+
+  bool got_move() const { return got_move_; }
+  const gfx::Point& last_event_location() const { return last_event_location_; }
+  void set_event_id(uint32_t event_id) { event_id_ = event_id; }
+
+  // ui::test::TestEventHandler overrides.
+  void OnMouseEvent(ui::MouseEvent* event) override {
+    if (event->type() == ui::ET_MOUSE_MOVED)
+      got_move_ = true;
+    last_event_location_ = event->location();
+    event->SetHandled();
+  }
+
+  void reset() {
+    got_move_ = false;
+    last_event_location_ = gfx::Point();
+    event_id_ = 0;
+  }
+
+ private:
+  bool got_move_ = false;
+  gfx::Point last_event_location_;
+  uint32_t event_id_ = 0;
+
+  DISALLOW_COPY_AND_ASSIGN(InputEventBasicTestEventHandler);
+};
+
 }  // namespace
 
 TEST_F(WindowTreeClientClientTest, InputEventBasic) {
@@ -779,6 +813,47 @@
   capture_client.reset();
 }
 
+TEST_F(WindowTreeClientClientTest, InputEventRootWindow) {
+  WindowTreeHostMus window_tree_host(window_tree_client_impl());
+  Window* top_level = window_tree_host.window();
+  InputEventBasicTestEventHandler root_handler;
+  top_level->AddPreTargetHandler(&root_handler);
+  const gfx::Rect bounds(0, 0, 100, 100);
+  window_tree_host.SetBoundsInPixels(bounds);
+  window_tree_host.InitHost();
+  window_tree_host.Show();
+  EXPECT_EQ(bounds, top_level->bounds());
+  EXPECT_EQ(bounds, window_tree_host.GetBoundsInPixels());
+  InputEventBasicTestWindowDelegate child_delegate(window_tree());
+  Window child(&child_delegate);
+  child.Init(ui::LAYER_NOT_DRAWN);
+  top_level->AddChild(&child);
+  child.SetBounds(gfx::Rect(10, 10, 100, 100));
+  child.Show();
+
+  EXPECT_FALSE(root_handler.got_move());
+  EXPECT_FALSE(child_delegate.got_move());
+
+  const gfx::Point event_location_in_child(20, 30);
+  const uint32_t event_id = 1;
+  root_handler.set_event_id(event_id);
+  child_delegate.set_event_id(event_id);
+  std::unique_ptr<ui::Event> ui_event(
+      new ui::MouseEvent(ui::ET_MOUSE_MOVED, event_location_in_child,
+                         gfx::Point(), ui::EventTimeForNow(), ui::EF_NONE, 0));
+  window_tree_client()->OnWindowInputEvent(
+      event_id, server_id(top_level), window_tree_host.display_id(),
+      ui::Event::Clone(*ui_event.get()), 0);
+
+  EXPECT_TRUE(window_tree()->WasEventAcked(event_id));
+  EXPECT_EQ(ui::mojom::EventResult::HANDLED,
+            window_tree()->GetEventResult(event_id));
+  EXPECT_TRUE(root_handler.got_move());
+  EXPECT_EQ(gfx::Point(20, 30), root_handler.last_event_location());
+  EXPECT_FALSE(child_delegate.got_move());
+  EXPECT_EQ(gfx::Point(), child_delegate.last_event_location());
+}
+
 class WindowTreeClientPointerObserverTest : public WindowTreeClientClientTest {
  public:
   WindowTreeClientPointerObserverTest() {}
@@ -1785,7 +1860,8 @@
   // in pixels.
   const gfx::Rect server_changed_bounds(gfx::Rect(0, 0, 200, 200));
   window_tree_client()->OnWindowBoundsChanged(
-      server_id(root_window()), original_bounds, server_changed_bounds);
+      server_id(root_window()), original_bounds, server_changed_bounds,
+      base::nullopt);
   EXPECT_EQ(new_bounds, root_window()->bounds());
 }
 
diff --git a/ui/aura/test/mus/test_window_tree.cc b/ui/aura/test/mus/test_window_tree.cc
index e9be6351..3c7af1bd 100644
--- a/ui/aura/test/mus/test_window_tree.cc
+++ b/ui/aura/test/mus/test_window_tree.cc
@@ -133,9 +133,11 @@
   OnChangeReceived(change_id);
 }
 
-void TestWindowTree::SetWindowBounds(uint32_t change_id,
-                                     uint32_t window_id,
-                                     const gfx::Rect& bounds) {
+void TestWindowTree::SetWindowBounds(
+    uint32_t change_id,
+    uint32_t window_id,
+    const gfx::Rect& bounds,
+    const base::Optional<cc::LocalSurfaceId>& local_surface_id) {
   OnChangeReceived(change_id, WindowTreeChangeType::BOUNDS);
 }
 
diff --git a/ui/aura/test/mus/test_window_tree.h b/ui/aura/test/mus/test_window_tree.h
index 92d05bac..c5910a5 100644
--- a/ui/aura/test/mus/test_window_tree.h
+++ b/ui/aura/test/mus/test_window_tree.h
@@ -116,9 +116,11 @@
       const std::unordered_map<std::string, std::vector<uint8_t>>& properties)
       override;
   void DeleteWindow(uint32_t change_id, uint32_t window_id) override;
-  void SetWindowBounds(uint32_t change_id,
-                       uint32_t window_id,
-                       const gfx::Rect& bounds) override;
+  void SetWindowBounds(
+      uint32_t change_id,
+      uint32_t window_id,
+      const gfx::Rect& bounds,
+      const base::Optional<cc::LocalSurfaceId>& local_surface_id) override;
   void SetClientArea(uint32_t window_id,
                      const gfx::Insets& insets,
                      const base::Optional<std::vector<gfx::Rect>>&
diff --git a/ui/aura/window_event_dispatcher.cc b/ui/aura/window_event_dispatcher.cc
index 02885e5..78ecee4d 100644
--- a/ui/aura/window_event_dispatcher.cc
+++ b/ui/aura/window_event_dispatcher.cc
@@ -455,7 +455,7 @@
   }
 
   ui::EventTarget* ancestor_with_targeter = event_target;
-  for (ui::EventTarget* ancestor = event_target->GetParentTarget(); ancestor;
+  for (ui::EventTarget* ancestor = event_target; ancestor;
        ancestor = ancestor->GetParentTarget()) {
     if (ancestor->GetEventTargeter())
       ancestor_with_targeter = ancestor;
diff --git a/ui/gfx/color_utils.cc b/ui/gfx/color_utils.cc
index e35d7b33..95dea09 100644
--- a/ui/gfx/color_utils.cc
+++ b/ui/gfx/color_utils.cc
@@ -11,6 +11,8 @@
 
 #include "base/logging.h"
 #include "base/numerics/safe_conversions.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/stringprintf.h"
 #include "build/build_config.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "ui/gfx/color_palette.h"
@@ -347,4 +349,17 @@
                      static_cast<int>(0.8f * SkColorGetA(text_color)));
 }
 
+std::string SkColorToRgbaString(SkColor color) {
+  // We convert the alpha using DoubleToString because StringPrintf will use
+  // locale specific formatters (e.g., use , instead of . in German).
+  return base::StringPrintf(
+      "rgba(%s,%s)", SkColorToRgbString(color).c_str(),
+      base::DoubleToString(SkColorGetA(color) / 255.0).c_str());
+}
+
+std::string SkColorToRgbString(SkColor color) {
+  return base::StringPrintf("%d,%d,%d", SkColorGetR(color), SkColorGetG(color),
+                            SkColorGetB(color));
+}
+
 }  // namespace color_utils
diff --git a/ui/gfx/color_utils.h b/ui/gfx/color_utils.h
index f6ba46a..eb95cbb 100644
--- a/ui/gfx/color_utils.h
+++ b/ui/gfx/color_utils.h
@@ -5,6 +5,8 @@
 #ifndef UI_GFX_COLOR_UTILS_H_
 #define UI_GFX_COLOR_UTILS_H_
 
+#include <string>
+
 #include "third_party/skia/include/core/SkColor.h"
 #include "ui/gfx/gfx_export.h"
 
@@ -138,6 +140,12 @@
 // surface.
 GFX_EXPORT SkColor DeriveDefaultIconColor(SkColor text_color);
 
+// Creates an rgba string for an SkColor. For example: 'rgba(255,0,255,0.5)'.
+GFX_EXPORT std::string SkColorToRgbaString(SkColor color);
+
+// Creates an rgb string for an SkColor. For example: '255,0,255'.
+GFX_EXPORT std::string SkColorToRgbString(SkColor color);
+
 }  // namespace color_utils
 
 #endif  // UI_GFX_COLOR_UTILS_H_
diff --git a/ui/gfx/color_utils_unittest.cc b/ui/gfx/color_utils_unittest.cc
index 367029f..3870dd3 100644
--- a/ui/gfx/color_utils_unittest.cc
+++ b/ui/gfx/color_utils_unittest.cc
@@ -166,4 +166,16 @@
   EXPECT_EQ(0U, SkColorGetA(AlphaBlend(fore, back, 255)));
 }
 
+TEST(ColorUtils, SkColorToRgbaString) {
+  SkColor color = SkColorSetARGB(153, 100, 150, 200);
+  std::string color_string = SkColorToRgbaString(color);
+  EXPECT_EQ(color_string, "rgba(100,150,200,.6)");
+}
+
+TEST(ColorUtils, SkColorToRgbString) {
+  SkColor color = SkColorSetARGB(200, 50, 100, 150);
+  std::string color_string = SkColorToRgbString(color);
+  EXPECT_EQ(color_string, "50,100,150");
+}
+
 }  // namespace color_utils
diff --git a/ui/message_center/views/custom_notification_view.cc b/ui/message_center/views/custom_notification_view.cc
index 90a946b..bb6a4e4 100644
--- a/ui/message_center/views/custom_notification_view.cc
+++ b/ui/message_center/views/custom_notification_view.cc
@@ -19,6 +19,9 @@
 
 namespace message_center {
 
+// static
+const char CustomNotificationView::kViewClassName[] = "CustomNotificationView";
+
 CustomNotificationView::CustomNotificationView(
     MessageCenterController* controller,
     const Notification& notification)
@@ -78,6 +81,10 @@
   return contents_view_delegate_->IsPinned();
 }
 
+const char* CustomNotificationView::GetClassName() const {
+  return kViewClassName;
+}
+
 void CustomNotificationView::UpdateControlButtonsVisibility() {
   if (contents_view_delegate_)
     contents_view_delegate_->UpdateControlButtonsVisibility();
diff --git a/ui/message_center/views/custom_notification_view.h b/ui/message_center/views/custom_notification_view.h
index 78cdbee..319bf1b5d 100644
--- a/ui/message_center/views/custom_notification_view.h
+++ b/ui/message_center/views/custom_notification_view.h
@@ -19,6 +19,8 @@
 // content of the notification.
 class MESSAGE_CENTER_EXPORT CustomNotificationView : public MessageView {
  public:
+  static const char kViewClassName[];
+
   CustomNotificationView(MessageCenterController* controller,
                          const Notification& notification);
   ~CustomNotificationView() override;
@@ -36,6 +38,7 @@
   void UpdateControlButtonsVisibility() override;
 
   // Overridden from views::View:
+  const char* GetClassName() const override;
   gfx::Size GetPreferredSize() const override;
   void Layout() override;
   bool HasFocus() const override;
diff --git a/ui/message_center/views/message_view.cc b/ui/message_center/views/message_view.cc
index 55502e9..7591a5bf 100644
--- a/ui/message_center/views/message_view.cc
+++ b/ui/message_center/views/message_view.cc
@@ -212,6 +212,10 @@
   event->SetHandled();
 }
 
+void MessageView::OnCloseButtonPressed() {
+  controller_->RemoveNotification(notification_id_, true);  // By user.
+}
+
 void MessageView::OnSlideOut() {
   controller_->RemoveNotification(notification_id_, true);  // By user.
 }
diff --git a/ui/message_center/views/message_view.h b/ui/message_center/views/message_view.h
index b165ae7..147e9941 100644
--- a/ui/message_center/views/message_view.h
+++ b/ui/message_center/views/message_view.h
@@ -55,6 +55,8 @@
   virtual bool IsPinned() const = 0;
   virtual void UpdateControlButtonsVisibility() = 0;
 
+  void OnCloseButtonPressed();
+
   // Overridden from views::View:
   void GetAccessibleNodeData(ui::AXNodeData* node_data) override;
   bool OnMousePressed(const ui::MouseEvent& event) override;
diff --git a/ui/message_center/views/notification_view.cc b/ui/message_center/views/notification_view.cc
index da750d9..d4dcb29 100644
--- a/ui/message_center/views/notification_view.cc
+++ b/ui/message_center/views/notification_view.cc
@@ -375,7 +375,7 @@
   if (close_button_ && sender == close_button_.get()) {
     // Warning: This causes the NotificationView itself to be deleted, so don't
     // do anything afterwards.
-    controller()->RemoveNotification(id, true /* by_user */);
+    OnCloseButtonPressed();
     return;
   }
 
diff --git a/ui/views/accessibility/native_view_accessibility.cc b/ui/views/accessibility/native_view_accessibility.cc
index 409ac5a..f2efa2e 100644
--- a/ui/views/accessibility/native_view_accessibility.cc
+++ b/ui/views/accessibility/native_view_accessibility.cc
@@ -4,6 +4,7 @@
 
 #include "ui/views/accessibility/native_view_accessibility.h"
 
+#include "base/memory/ptr_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "ui/events/event_utils.h"
 #include "ui/gfx/native_widget_types.h"
@@ -15,8 +16,11 @@
 
 #if !defined(PLATFORM_HAS_NATIVE_VIEW_ACCESSIBILITY_IMPL)
 // static
-NativeViewAccessibility* NativeViewAccessibility::Create(View* view) {
-  return new NativeViewAccessibility(view);
+std::unique_ptr<NativeViewAccessibility> NativeViewAccessibility::Create(
+    View* view) {
+  // Use WrapUnique over MakeUnique to invoke the protected constructor.
+  return base::WrapUnique<NativeViewAccessibility>(
+      new NativeViewAccessibility(view));
 }
 #endif  // !defined(PLATFORM_HAS_NATIVE_VIEW_ACCESSIBILITY_IMPL)
 
@@ -38,10 +42,6 @@
   return ax_node_ ? ax_node_->GetNativeViewAccessible() : nullptr;
 }
 
-void NativeViewAccessibility::Destroy() {
-  delete this;
-}
-
 void NativeViewAccessibility::NotifyAccessibilityEvent(ui::AXEvent event_type) {
   if (ax_node_)
     ax_node_->NotifyAccessibilityEvent(event_type);
diff --git a/ui/views/accessibility/native_view_accessibility.h b/ui/views/accessibility/native_view_accessibility.h
index df9880e..ec1e0db 100644
--- a/ui/views/accessibility/native_view_accessibility.h
+++ b/ui/views/accessibility/native_view_accessibility.h
@@ -5,6 +5,8 @@
 #ifndef UI_VIEWS_ACCESSIBILITY_NATIVE_VIEW_ACCESSIBILITY_H_
 #define UI_VIEWS_ACCESSIBILITY_NATIVE_VIEW_ACCESSIBILITY_H_
 
+#include <memory>
+
 #include "base/macros.h"
 #include "build/build_config.h"
 #include "ui/accessibility/ax_action_data.h"
@@ -40,14 +42,12 @@
     : public ui::AXPlatformNodeDelegate,
       public WidgetObserver {
  public:
-  static NativeViewAccessibility* Create(View* view);
+  static std::unique_ptr<NativeViewAccessibility> Create(View* view);
+
+  ~NativeViewAccessibility() override;
 
   gfx::NativeViewAccessible GetNativeObject();
 
-  // Call Destroy rather than deleting this, because the subclass may
-  // use reference counting.
-  virtual void Destroy();
-
   void NotifyAccessibilityEvent(ui::AXEvent event_type);
 
   // Focuses or unfocuses a View.
@@ -73,8 +73,7 @@
   void SetParentWidget(Widget* parent_widget);
 
  protected:
-  NativeViewAccessibility(View* view);
-  ~NativeViewAccessibility() override;
+  explicit NativeViewAccessibility(View* view);
 
   // Weak. Owns this.
   View* view_;
diff --git a/ui/views/accessibility/native_view_accessibility_auralinux.cc b/ui/views/accessibility/native_view_accessibility_auralinux.cc
index 5ee10f8..3f5b7de 100644
--- a/ui/views/accessibility/native_view_accessibility_auralinux.cc
+++ b/ui/views/accessibility/native_view_accessibility_auralinux.cc
@@ -5,9 +5,11 @@
 #include "ui/views/accessibility/native_view_accessibility_auralinux.h"
 
 #include <algorithm>
+#include <memory>
 #include <vector>
 
 #include "base/macros.h"
+#include "base/memory/ptr_util.h"
 #include "base/memory/singleton.h"
 #include "base/stl_util.h"
 #include "ui/accessibility/ax_action_data.h"
@@ -150,9 +152,10 @@
 }  // namespace
 
 // static
-NativeViewAccessibility* NativeViewAccessibility::Create(View* view) {
+std::unique_ptr<NativeViewAccessibility> NativeViewAccessibility::Create(
+    View* view) {
   AuraLinuxApplication::GetInstance()->RegisterWidget(view->GetWidget());
-  return new NativeViewAccessibilityAuraLinux(view);
+  return base::MakeUnique<NativeViewAccessibilityAuraLinux>(view);
 }
 
 NativeViewAccessibilityAuraLinux::NativeViewAccessibilityAuraLinux(View* view)
diff --git a/ui/views/accessibility/native_view_accessibility_mac.mm b/ui/views/accessibility/native_view_accessibility_mac.mm
index 68e58caa..337ef19 100644
--- a/ui/views/accessibility/native_view_accessibility_mac.mm
+++ b/ui/views/accessibility/native_view_accessibility_mac.mm
@@ -4,14 +4,18 @@
 
 #include "ui/views/accessibility/native_view_accessibility_mac.h"
 
+#include <memory>
+
+#include "base/memory/ptr_util.h"
 #include "ui/views/view.h"
 #include "ui/views/widget/widget.h"
 
 namespace views {
 
 // static
-NativeViewAccessibility* NativeViewAccessibility::Create(View* view) {
-  return new NativeViewAccessibilityMac(view);
+std::unique_ptr<NativeViewAccessibility> NativeViewAccessibility::Create(
+    View* view) {
+  return base::MakeUnique<NativeViewAccessibilityMac>(view);
 }
 
 NativeViewAccessibilityMac::NativeViewAccessibilityMac(View* view)
diff --git a/ui/views/accessibility/native_view_accessibility_unittest.cc b/ui/views/accessibility/native_view_accessibility_unittest.cc
index eecbff0..74a84ff 100644
--- a/ui/views/accessibility/native_view_accessibility_unittest.cc
+++ b/ui/views/accessibility/native_view_accessibility_unittest.cc
@@ -58,19 +58,15 @@
   void TearDown() override {
     if (!widget_->IsClosed())
       widget_->Close();
-    button_accessibility_->Destroy();
-    button_accessibility_ = NULL;
-    label_accessibility_->Destroy();
-    label_accessibility_ = NULL;
     ViewsTestBase::TearDown();
   }
 
  protected:
   views::Widget* widget_;
   TestButton* button_;
-  NativeViewAccessibility* button_accessibility_;
+  std::unique_ptr<NativeViewAccessibility> button_accessibility_;
   Label* label_;
-  NativeViewAccessibility* label_accessibility_;
+  std::unique_ptr<NativeViewAccessibility> label_accessibility_;
 };
 
 TEST_F(NativeViewAccessibilityTest, RoleShouldMatch) {
diff --git a/ui/views/accessibility/native_view_accessibility_win.cc b/ui/views/accessibility/native_view_accessibility_win.cc
index fee8d9ea..93910a1 100644
--- a/ui/views/accessibility/native_view_accessibility_win.cc
+++ b/ui/views/accessibility/native_view_accessibility_win.cc
@@ -6,9 +6,11 @@
 
 #include <oleacc.h>
 
+#include <memory>
 #include <set>
 #include <vector>
 
+#include "base/memory/ptr_util.h"
 #include "base/memory/singleton.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/win/scoped_comptr.h"
@@ -28,16 +30,15 @@
 namespace views {
 
 // static
-NativeViewAccessibility* NativeViewAccessibility::Create(View* view) {
-  return new NativeViewAccessibilityWin(view);
+std::unique_ptr<NativeViewAccessibility> NativeViewAccessibility::Create(
+    View* view) {
+  return base::MakeUnique<NativeViewAccessibilityWin>(view);
 }
 
 NativeViewAccessibilityWin::NativeViewAccessibilityWin(View* view)
-    : NativeViewAccessibility(view) {
-}
+    : NativeViewAccessibility(view) {}
 
-NativeViewAccessibilityWin::~NativeViewAccessibilityWin() {
-}
+NativeViewAccessibilityWin::~NativeViewAccessibilityWin() {}
 
 gfx::NativeViewAccessible NativeViewAccessibilityWin::GetParent() {
   IAccessible* parent = NativeViewAccessibility::GetParent();
diff --git a/ui/views/controls/label.cc b/ui/views/controls/label.cc
index 2d16942..0532230 100644
--- a/ui/views/controls/label.cc
+++ b/ui/views/controls/label.cc
@@ -467,10 +467,9 @@
         SkColorGetA(view->background()->get_color()) == SK_AlphaOPAQUE)
       break;
 
-    if (view->layer()) {
-      DCHECK(view->layer()->fills_bounds_opaquely())
-          << " Ancestor view has a non-opaque layer: " << view->GetClassName()
-          << " with ID " << view->id();
+    if (view->layer() && view->layer()->fills_bounds_opaquely()) {
+      DLOG(WARNING) << "Ancestor view has a non-opaque layer: "
+                    << view->GetClassName() << " with ID " << view->id();
       break;
     }
   }
diff --git a/ui/views/controls/tabbed_pane/tabbed_pane_unittest.cc b/ui/views/controls/tabbed_pane/tabbed_pane_unittest.cc
index 8761683..3a52876 100644
--- a/ui/views/controls/tabbed_pane/tabbed_pane_unittest.cc
+++ b/ui/views/controls/tabbed_pane/tabbed_pane_unittest.cc
@@ -158,33 +158,33 @@
 
   // Check the a11y information for each tab.
   for (int i = 0; i < kNumTabs; ++i) {
-    NativeViewAccessibility* nva = NativeViewAccessibility::Create(GetTabAt(i));
-    ui::AXNodeData data = nva->GetData();
+    ui::AXNodeData data =
+        NativeViewAccessibility::Create(GetTabAt(i))->GetData();
     SCOPED_TRACE(testing::Message() << "Tab at index: " << i);
     EXPECT_EQ(ui::AX_ROLE_TAB, data.role);
     EXPECT_EQ(DefaultTabTitle(), data.GetString16Attribute(ui::AX_ATTR_NAME));
     EXPECT_TRUE(data.HasStateFlag(ui::AX_STATE_SELECTABLE));
     EXPECT_EQ(i == 0, data.HasStateFlag(ui::AX_STATE_SELECTED));
-    nva->Destroy();
   }
 
   ui::AXActionData action;
   action.action = ui::AX_ACTION_SET_SELECTION;
   // Select the first tab.
-  NativeViewAccessibility* nva = NativeViewAccessibility::Create(GetTabAt(0));
-  nva->AccessibilityPerformAction(action);
+
+  NativeViewAccessibility::Create(GetTabAt(0))
+      ->AccessibilityPerformAction(action);
   EXPECT_EQ(0, tabbed_pane_->GetSelectedTabIndex());
-  nva->Destroy();
 
   // Select the second tab.
-  nva = NativeViewAccessibility::Create(GetTabAt(1));
+  std::unique_ptr<NativeViewAccessibility> nva =
+      NativeViewAccessibility::Create(GetTabAt(1));
   nva->AccessibilityPerformAction(action);
   EXPECT_EQ(1, tabbed_pane_->GetSelectedTabIndex());
   // Select the second tab again.
   nva->AccessibilityPerformAction(action);
   EXPECT_EQ(1, tabbed_pane_->GetSelectedTabIndex());
-  nva->Destroy();
 
+  nva.reset();
   widget->CloseNow();
 }
 
diff --git a/ui/views/examples/dialog_example.cc b/ui/views/examples/dialog_example.cc
index 637c6da..37e8770 100644
--- a/ui/views/examples/dialog_example.cc
+++ b/ui/views/examples/dialog_example.cc
@@ -245,6 +245,10 @@
   // Q: Do we need NonClientFrameView::GetWindowBoundsForClientBounds() here?
   // A: When DialogCientView properly feeds back sizes, we do not.
   widget->SetBoundsConstrained(preferred_bounds);
+
+  // For user-resizable dialogs, ensure the window manager enforces any new
+  // minimum size.
+  widget->OnSizeConstraintsChanged();
 }
 
 void DialogExample::ButtonPressed(Button* sender, const ui::Event& event) {
diff --git a/ui/views/view.cc b/ui/views/view.cc
index 897dacd..359ef56 100644
--- a/ui/views/view.cc
+++ b/ui/views/view.cc
@@ -145,8 +145,7 @@
       previous_focusable_view_(NULL),
       focus_behavior_(FocusBehavior::NEVER),
       context_menu_controller_(NULL),
-      drag_controller_(NULL),
-      native_view_accessibility_(NULL) {
+      drag_controller_(NULL) {
   SetTargetHandler(this);
 }
 
@@ -164,11 +163,6 @@
         delete child;
     }
   }
-
-  // Release ownership of the native accessibility object, but it's
-  // reference-counted on some platforms, so it may not be deleted right away.
-  if (native_view_accessibility_)
-    native_view_accessibility_->Destroy();
 }
 
 // Tree operations -------------------------------------------------------------
@@ -1427,7 +1421,7 @@
     native_view_accessibility_ = NativeViewAccessibility::Create(this);
   if (native_view_accessibility_)
     return native_view_accessibility_->GetNativeObject();
-  return NULL;
+  return nullptr;
 }
 
 void View::NotifyAccessibilityEvent(
diff --git a/ui/views/view.h b/ui/views/view.h
index 2d23890..d719730 100644
--- a/ui/views/view.h
+++ b/ui/views/view.h
@@ -1634,9 +1634,8 @@
 
   // Accessibility -------------------------------------------------------------
 
-  // Belongs to this view, but it's reference-counted on some platforms
-  // so we can't use a scoped_ptr. It's dereferenced in the destructor.
-  NativeViewAccessibility* native_view_accessibility_;
+  // The accessibility element used to represent this View.
+  std::unique_ptr<NativeViewAccessibility> native_view_accessibility_;
 
   // Observers -------------------------------------------------------------
 
diff --git a/ui/views/window/dialog_client_view.cc b/ui/views/window/dialog_client_view.cc
index f646639..5c10986 100644
--- a/ui/views/window/dialog_client_view.cc
+++ b/ui/views/window/dialog_client_view.cc
@@ -15,6 +15,7 @@
 #include "ui/views/controls/button/custom_button.h"
 #include "ui/views/controls/button/label_button.h"
 #include "ui/views/controls/button/md_text_button.h"
+#include "ui/views/layout/grid_layout.h"
 #include "ui/views/style/platform_style.h"
 #include "ui/views/views_delegate.h"
 #include "ui/views/widget/widget.h"
@@ -40,27 +41,35 @@
   return view && view->visible();
 }
 
-// Do the layout for a button.
-void LayoutButton(LabelButton* button,
-                  gfx::Rect* row_bounds,
-                  int button_height) {
-  if (!button)
-    return;
-
-  const gfx::Size size = button->GetPreferredSize();
-  row_bounds->set_width(row_bounds->width() - size.width());
-  DCHECK_LE(button_height, row_bounds->height());
-  button->SetBounds(
-      row_bounds->right(),
-      row_bounds->y() + (row_bounds->height() - button_height) / 2,
-      size.width(), button_height);
-  const int spacing =
-      ViewsDelegate::GetInstance()->GetDialogRelatedButtonHorizontalSpacing();
-  row_bounds->set_width(row_bounds->width() - spacing);
+// Returns the bounding box required to contain |size1| and |size2|, placed one
+// atop the other.
+gfx::Size GetBoundingSizeForVerticalStack(const gfx::Size& size1,
+                                          const gfx::Size& size2) {
+  return gfx::Size(std::max(size1.width(), size2.width()),
+                   size1.height() + size2.height());
 }
 
 }  // namespace
 
+// Simple container to bubble child view changes up the view hierarchy.
+class DialogClientView::ButtonRowContainer : public View {
+ public:
+  explicit ButtonRowContainer(DialogClientView* owner) : owner_(owner) {}
+
+  // View:
+  void ChildPreferredSizeChanged(View* child) override {
+    owner_->ChildPreferredSizeChanged(child);
+  }
+  void ChildVisibilityChanged(View* child) override {
+    owner_->ChildVisibilityChanged(child);
+  }
+
+ private:
+  DialogClientView* const owner_;
+
+  DISALLOW_COPY_AND_ASSIGN(ButtonRowContainer);
+};
+
 ///////////////////////////////////////////////////////////////////////////////
 // DialogClientView, public:
 
@@ -71,10 +80,11 @@
   // Doing this now ensures this accelerator will have lower priority than
   // one set by the contents view.
   AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE));
+  button_row_container_ = new ButtonRowContainer(this);
+  AddChildView(button_row_container_);
 }
 
-DialogClientView::~DialogClientView() {
-}
+DialogClientView::~DialogClientView() {}
 
 void DialogClientView::AcceptWindow() {
   // Only notify the delegate once. See |delegate_allowed_close_|'s comment.
@@ -93,8 +103,8 @@
 }
 
 void DialogClientView::UpdateDialogButtons() {
-  SetupViews();
-  SetupFocusChain();
+  SetupLayout();
+  InvalidateLayout();
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -120,90 +130,41 @@
 // DialogClientView, View overrides:
 
 gfx::Size DialogClientView::GetPreferredSize() const {
-  // Initialize the size to fit the buttons and extra view row.
-  gfx::Size size(
-      (ok_button_ ? ok_button_->GetPreferredSize().width() : 0) +
-          (cancel_button_ ? cancel_button_->GetPreferredSize().width() : 0) +
-          (cancel_button_ && ok_button_
-               ? ViewsDelegate::GetInstance()
-                     ->GetDialogRelatedButtonHorizontalSpacing()
-               : 0) +
-          (ShouldShow(extra_view_) ? extra_view_->GetPreferredSize().width()
-                                   : 0) +
-          GetExtraViewSpacing(),
-      0);
+  return GetBoundingSizeForVerticalStack(
+      ClientView::GetPreferredSize(),
+      button_row_container_->GetPreferredSize());
+}
 
-  int buttons_height = GetButtonsAndExtraViewRowHeight();
-  if (buttons_height != 0) {
-    size.Enlarge(0, buttons_height);
-    // Inset the buttons and extra view.
-    const gfx::Insets insets = GetButtonRowInsets();
-    size.Enlarge(insets.width(), insets.height());
-  }
+gfx::Size DialogClientView::GetMinimumSize() const {
+  return GetBoundingSizeForVerticalStack(
+      ClientView::GetMinimumSize(), button_row_container_->GetMinimumSize());
+}
 
-  // Increase the size as needed to fit the contents view.
-  // NOTE: The contents view is not inset on the top or side client view edges.
-  gfx::Size contents_size = contents_view()->GetPreferredSize();
-  size.Enlarge(0, contents_size.height());
-  size.set_width(std::max(size.width(), contents_size.width()));
+gfx::Size DialogClientView::GetMaximumSize() const {
+  constexpr int kUnconstrained = 0;
+  DCHECK(gfx::Size(kUnconstrained, kUnconstrained) ==
+         button_row_container_->GetMaximumSize());
+  gfx::Size max_size = ClientView::GetMaximumSize();
 
-  size.SetToMax(minimum_size_);
+  // If the height is constrained, add the button row height. Leave the width as
+  // it is (be it constrained or unconstrained).
+  if (max_size.height() != kUnconstrained)
+    max_size.Enlarge(0, button_row_container_->GetPreferredSize().height());
 
-  return size;
+  // Note not all constraints can be met. E.g. it's possible here for
+  // GetMinimumSize().width() to be larger than max_size.width() since the
+  // former includes the button row width, but the latter does not. It is up to
+  // the DialogDelegate to ensure its maximum size is reasonable for the buttons
+  // it wants, or leave it unconstrained.
+  return max_size;
 }
 
 void DialogClientView::Layout() {
-  gfx::Rect bounds = GetContentsBounds();
-
-  // Layout the row containing the buttons and the extra view.
-  if (has_dialog_buttons() || ShouldShow(extra_view_)) {
-    gfx::Insets button_row_insets = GetButtonRowInsets();
-    // Don't apply the top inset here because it's supposed to go above the
-    // buttons, not at the top of the dialog.
-    bounds.Inset(button_row_insets.left(), 0, button_row_insets.right(),
-                 button_row_insets.bottom());
-    const int height = GetButtonsAndExtraViewRowHeight();
-    gfx::Rect row_bounds(bounds.x(), bounds.bottom() - height,
-                         bounds.width(), height);
-    // If the |extra_view_| is a also button, then the |button_height| is the
-    // maximum height of the three buttons, otherwise it is the maximum height
-    // of the ok and cancel buttons.
-    const int button_height =
-        CustomButton::AsCustomButton(extra_view_) ? height : GetButtonHeight();
-    if (kIsOkButtonOnLeftSide) {
-      LayoutButton(cancel_button_, &row_bounds, button_height);
-      LayoutButton(ok_button_, &row_bounds, button_height);
-    } else {
-      LayoutButton(ok_button_, &row_bounds, button_height);
-      LayoutButton(cancel_button_, &row_bounds, button_height);
-    }
-    if (extra_view_) {
-      int custom_padding = 0;
-      if (has_dialog_buttons() &&
-          GetDialogDelegate()->GetExtraViewPadding(&custom_padding)) {
-        // The padding between buttons applied in LayoutButton() will already
-        // have accounted for some of the distance here.
-        custom_padding -= ViewsDelegate::GetInstance()
-                              ->GetDialogRelatedButtonHorizontalSpacing();
-        row_bounds.set_width(row_bounds.width() - custom_padding);
-      }
-      row_bounds.set_width(std::min(row_bounds.width(),
-                                    extra_view_->GetPreferredSize().width()));
-      extra_view_->SetBoundsRect(row_bounds);
-    }
-
-    if (height > 0) {
-      // Inset to the top of the buttons, plus their top padding, in order to
-      // exclude that area from the content view's bounds.
-      bounds.Inset(0, 0, 0, height + button_row_insets.top());
-    }
-  }
-
-  // Layout the contents view to the top and side edges of the contents bounds.
-  // NOTE: The local insets do not apply to the contents view sides or top.
-  const gfx::Rect contents_bounds = GetContentsBounds();
-  contents_view()->SetBounds(contents_bounds.x(), contents_bounds.y(),
-      contents_bounds.width(), bounds.bottom() - contents_bounds.y());
+  button_row_container_->SetSize(
+      gfx::Size(width(), button_row_container_->GetHeightForWidth(width())));
+  button_row_container_->SetY(height() - button_row_container_->height());
+  if (contents_view())
+    contents_view()->SetSize(gfx::Size(width(), button_row_container_->y()));
 }
 
 bool DialogClientView::AcceleratorPressed(const ui::Accelerator& accelerator) {
@@ -217,23 +178,31 @@
     const ViewHierarchyChangedDetails& details) {
   View* const child = details.child;
 
-  // Dialogs must add children to contents_view(), not client_view().
-  if (details.is_add && details.parent == this) {
-    DCHECK(child == contents_view() || child == ok_button_ ||
-           child == cancel_button_ || child == extra_view_);
+  ClientView::ViewHierarchyChanged(details);
+
+  if (details.is_add) {
+    if (child == this)
+      UpdateDialogButtons();
+    return;
   }
 
-  ClientView::ViewHierarchyChanged(details);
-  if (details.is_add && child == this) {
-    UpdateDialogButtons();
-  } else if (!details.is_add) {
-    if (child == ok_button_)
-      ok_button_ = nullptr;
-    else if (child == cancel_button_)
-      cancel_button_ = nullptr;
-    else if (child == extra_view_)
-      extra_view_ = nullptr;
-  }
+  if (details.parent != button_row_container_)
+    return;
+
+  // SetupViews() removes all children, managing data members itself.
+  if (preserve_button_row_data_members_)
+    return;
+
+  // Otherwise, this should only happen during teardown. Ensure there are no
+  // references to deleted Views.
+  button_row_container_->SetLayoutManager(nullptr);
+
+  if (child == ok_button_)
+    ok_button_ = nullptr;
+  else if (child == cancel_button_)
+    cancel_button_ = nullptr;
+  else if (child == extra_view_)
+    extra_view_ = nullptr;
 }
 
 void DialogClientView::OnNativeThemeChanged(const ui::NativeTheme* theme) {
@@ -276,91 +245,56 @@
 }
 
 void DialogClientView::ChildVisibilityChanged(View* child) {
+  // Showing or hiding |extra_view_| can alter which columns have linked sizes.
+  if (child == extra_view_)
+    UpdateDialogButtons();
   ChildPreferredSizeChanged(child);
 }
 
-LabelButton* DialogClientView::CreateDialogButton(ui::DialogButton type) {
-  const base::string16 title = GetDialogDelegate()->GetDialogButtonLabel(type);
-  LabelButton* button = nullptr;
-
-  const bool is_default =
-      GetDialogDelegate()->GetDefaultDialogButton() == type &&
-      (type != ui::DIALOG_BUTTON_CANCEL ||
-       PlatformStyle::kDialogDefaultButtonCanBeCancel);
-
-  // The default button is always blue in Harmony.
-  if (is_default && (ui::MaterialDesignController::IsSecondaryUiMaterial() ||
-                     GetDialogDelegate()->ShouldDefaultButtonBeBlue())) {
-    button = MdTextButton::CreateSecondaryUiBlueButton(this, title);
-  } else {
-    button = MdTextButton::CreateSecondaryUiButton(this, title);
+void DialogClientView::UpdateDialogButton(LabelButton** member,
+                                          ui::DialogButton type) {
+  DialogDelegate* const delegate = GetDialogDelegate();
+  if (!(delegate->GetDialogButtons() & type)) {
+    delete *member;
+    *member = nullptr;
+    return;
   }
 
-  const int minimum_width =
-      ViewsDelegate::GetInstance()->GetDialogButtonMinimumWidth();
-  button->SetMinSize(gfx::Size(minimum_width, 0));
+  if (!*member) {
+    // In theory, this should only need to assign a newly constructed Button to
+    // |*member|. DialogDelegate::UpdateButton(), and any overrides of that,
+    // should be responsible for the rest. TODO(tapted): When there is only
+    // MdTextButton, make it so. Note that some overrides may not always update
+    // the title (they should). See http://crbug.com/697303 .
+    const base::string16 title = delegate->GetDialogButtonLabel(type);
+    LabelButton* button = nullptr;
 
-  button->SetGroup(kButtonGroup);
-  return button;
-}
+    const bool is_default = delegate->GetDefaultDialogButton() == type &&
+                            (type != ui::DIALOG_BUTTON_CANCEL ||
+                             PlatformStyle::kDialogDefaultButtonCanBeCancel);
 
-int DialogClientView::GetButtonHeight() const {
-  return std::max(
-      ok_button_ ? ok_button_->GetPreferredSize().height() : 0,
-      cancel_button_ ? cancel_button_->GetPreferredSize().height() : 0);
-}
+    // The default button is always blue in Harmony.
+    if (is_default && (ui::MaterialDesignController::IsSecondaryUiMaterial() ||
+                       delegate->ShouldDefaultButtonBeBlue())) {
+      button = MdTextButton::CreateSecondaryUiBlueButton(this, title);
+    } else {
+      button = MdTextButton::CreateSecondaryUiButton(this, title);
+    }
 
-int DialogClientView::GetExtraViewHeight() const {
-  return ShouldShow(extra_view_) ? extra_view_->GetPreferredSize().height() : 0;
-}
+    const int minimum_width =
+        ViewsDelegate::GetInstance()->GetDialogButtonMinimumWidth();
+    button->SetMinSize(gfx::Size(minimum_width, 0));
 
-int DialogClientView::GetButtonsAndExtraViewRowHeight() const {
-  return std::max(GetExtraViewHeight(), GetButtonHeight());
-}
+    button->SetGroup(kButtonGroup);
 
-gfx::Insets DialogClientView::GetButtonRowInsets() const {
-  if (GetButtonsAndExtraViewRowHeight() == 0)
-    return gfx::Insets();
-
-  // Some subclasses of DialogClientView, in order to do their own layout, set
-  // button_row_insets_ to gfx::Insets(). To avoid breaking behavior of those
-  // dialogs, supplying 0 for the top inset of the row falls back to
-  // ViewsDelegate::GetRelatedControlVerticalSpacing.
-  // TODO(bsep): The top inset should never be 0 when harmony is enabled.
-  const int top = button_row_insets_.top() == 0
-                      ? ViewsDelegate::GetInstance()
-                            ->GetDialogRelatedControlVerticalSpacing()
-                      : button_row_insets_.top();
-  return gfx::Insets(top, button_row_insets_.left(),
-                     button_row_insets_.bottom(), button_row_insets_.right());
-}
-
-void DialogClientView::SetupFocusChain() {
-  // Create a vector of child views in the order of intended focus.
-  std::vector<View*> child_views;
-  child_views.push_back(contents_view());
-  child_views.push_back(extra_view_);
-  if (kIsOkButtonOnLeftSide) {
-    child_views.push_back(ok_button_);
-    child_views.push_back(cancel_button_);
-  } else {
-    child_views.push_back(cancel_button_);
-    child_views.push_back(ok_button_);
+    *member = button;
   }
 
-  // Remove all null views from the vector.
-  child_views.erase(
-      std::remove(child_views.begin(), child_views.end(), nullptr),
-      child_views.end());
-
-  // Setup focus by reordering views. It is not safe to use SetNextFocusableView
-  // since child views may be added externally to this view.
-  for (size_t i = 0; i < child_views.size(); i++)
-    ReorderChildView(child_views[i], i);
+  delegate->UpdateButton(*member, type);
 }
 
 int DialogClientView::GetExtraViewSpacing() const {
-  if (!ShouldShow(extra_view_) || !has_dialog_buttons())
+  if (!ShouldShow(extra_view_) || !(ok_button_ || cancel_button_))
     return 0;
 
   int extra_view_padding = 0;
@@ -371,41 +305,120 @@
       ->GetDialogRelatedButtonHorizontalSpacing();
 }
 
+std::array<View*, DialogClientView::kNumButtons>
+DialogClientView::GetButtonRowViews() {
+  View* first = ShouldShow(extra_view_) ? extra_view_ : nullptr;
+  View* second = cancel_button_;
+  View* third = ok_button_;
+  if (kIsOkButtonOnLeftSide)
+    std::swap(second, third);
+  return {{first, second, third}};
+}
+
+void DialogClientView::SetupLayout() {
+  GridLayout* layout = new GridLayout(button_row_container_);
+  layout->set_minimum_size(minimum_size_);
+
+  // Clobber any existing LayoutManager since it has weak references to child
+  // Views which may be removed by SetupViews().
+  button_row_container_->SetLayoutManager(layout);
+  SetupViews();
+  const std::array<View*, kNumButtons> views = GetButtonRowViews();
+
+  // Visibility changes on |extra_view_| must be observed to re-Layout. However,
+  // when hidden it's not included in the button row (it can't influence layout)
+  // and it can't be added to |button_row_container_| (GridLayout complains).
+  // So add it, hidden, to |this| so it can be observed.
+  if (extra_view_ && !views[0])
+    AddChildView(extra_view_);
+
+  if (std::count(views.begin(), views.end(), nullptr) == kNumButtons)
+    return;
+
+  gfx::Insets insets = button_row_insets_;
+  // Support dialogs that clear |button_row_insets_| to do their own layout.
+  // They expect GetDialogRelatedControlVerticalSpacing() in this case.
+  // TODO(tapted): Remove this under Harmony.
+  if (insets.top() == 0) {
+    const int top =
+        ViewsDelegate::GetInstance()->GetDialogRelatedControlVerticalSpacing();
+    insets.Set(top, insets.left(), insets.bottom(), insets.right());
+  }
+
+  // The |resize_percent| constants. There's only one stretchy column (padding
+  // to the left of ok/cancel buttons).
+  constexpr float kFixed = 0.f;
+  constexpr float kStretchy = 1.f;
+
+  // Button row is [ extra <pad+stretchy> second <pad> third ]. Ensure the <pad>
+  // column is zero width if there isn't a button on either side.
+  // GetExtraViewSpacing() handles <pad+stretchy>.
+  const int button_spacing =
+      (ok_button_ && cancel_button_)
+          ? ViewsDelegate::GetInstance()
+                ->GetDialogRelatedButtonHorizontalSpacing()
+          : 0;
+
+  constexpr int kButtonRowId = 0;
+  ColumnSet* column_set = layout->AddColumnSet(kButtonRowId);
+
+  // Rather than giving |button_row_container_| a Border, incorporate the insets
+  // into the layout. This simplifies min/max size calculations.
+  column_set->AddPaddingColumn(kFixed, insets.left());
+  column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, kFixed,
+                        GridLayout::USE_PREF, 0, 0);
+  column_set->AddPaddingColumn(kStretchy, GetExtraViewSpacing());
+  column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, kFixed,
+                        GridLayout::USE_PREF, 0, 0);
+  column_set->AddPaddingColumn(kFixed, button_spacing);
+  column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, kFixed,
+                        GridLayout::USE_PREF, 0, 0);
+  column_set->AddPaddingColumn(kFixed, insets.right());
+
+  // Track which columns to link sizes under MD.
+  constexpr int kViewToColumnIndex[] = {1, 3, 5};
+  int link[] = {-1, -1, -1};
+  size_t link_index = 0;
+
+  layout->StartRowWithPadding(kFixed, kButtonRowId, kFixed, insets.top());
+  for (size_t view_index = 0; view_index < kNumButtons; ++view_index) {
+    if (views[view_index]) {
+      layout->AddView(views[view_index]);
+      link[link_index++] = kViewToColumnIndex[view_index];
+    } else {
+      layout->SkipColumns(1);
+    }
+  }
+
+  if (ui::MaterialDesignController::IsSecondaryUiMaterial()) {
+    // Only link the extra view column if it is a button.
+    if (views[0] && !CustomButton::AsCustomButton(views[0]))
+      column_set->LinkColumnSizes(link[1], link[2], -1);
+    else
+      column_set->LinkColumnSizes(link[0], link[1], link[2], -1);
+  }
+  layout->AddPaddingRow(kFixed, insets.bottom());
+}
+
 void DialogClientView::SetupViews() {
-  const int buttons = GetDialogDelegate()->GetDialogButtons();
-
-  if (buttons & ui::DIALOG_BUTTON_OK) {
-    if (!ok_button_) {
-      ok_button_ = CreateDialogButton(ui::DIALOG_BUTTON_OK);
-      AddChildView(ok_button_);
-    }
-
-    GetDialogDelegate()->UpdateButton(ok_button_, ui::DIALOG_BUTTON_OK);
-  } else if (ok_button_) {
-    delete ok_button_;
-    ok_button_ = nullptr;
+  {
+    base::AutoReset<bool> auto_reset(&preserve_button_row_data_members_, true);
+    button_row_container_->RemoveAllChildViews(false /* delete children */);
+    // If SetupLayout() "stored" a hidden |extra_view_| in |this|, ensure it can
+    // be re-added to the layout when becoming visible.
+    if (extra_view_)
+      RemoveChildView(extra_view_);
   }
 
-  if (buttons & ui::DIALOG_BUTTON_CANCEL) {
-    if (!cancel_button_) {
-      cancel_button_ = CreateDialogButton(ui::DIALOG_BUTTON_CANCEL);
-      AddChildView(cancel_button_);
-    }
-
-    GetDialogDelegate()->UpdateButton(cancel_button_, ui::DIALOG_BUTTON_CANCEL);
-  } else if (cancel_button_) {
-    delete cancel_button_;
-    cancel_button_ = nullptr;
-  }
+  UpdateDialogButton(&ok_button_, ui::DIALOG_BUTTON_OK);
+  UpdateDialogButton(&cancel_button_, ui::DIALOG_BUTTON_CANCEL);
 
   if (extra_view_)
     return;
 
   extra_view_ = GetDialogDelegate()->CreateExtraView();
-  if (extra_view_) {
+  if (extra_view_)
     extra_view_->SetGroup(kButtonGroup);
-    AddChildView(extra_view_);
-  }
 }
 
 }  // namespace views
diff --git a/ui/views/window/dialog_client_view.h b/ui/views/window/dialog_client_view.h
index 36028128..ff184b87 100644
--- a/ui/views/window/dialog_client_view.h
+++ b/ui/views/window/dialog_client_view.h
@@ -51,6 +51,9 @@
 
   // View implementation:
   gfx::Size GetPreferredSize() const override;
+  gfx::Size GetMinimumSize() const override;
+  gfx::Size GetMaximumSize() const override;
+
   void Layout() override;
   bool AcceleratorPressed(const ui::Accelerator& accelerator) override;
   void ViewHierarchyChanged(
@@ -67,7 +70,11 @@
   void set_minimum_size(const gfx::Size& size) { minimum_size_ = size; }
 
  private:
-  bool has_dialog_buttons() const { return ok_button_ || cancel_button_; }
+  enum {
+    // The number of buttons that DialogClientView can support.
+    kNumButtons = 3
+  };
+  class ButtonRowContainer;
 
   // Returns the DialogDelegate for the window.
   DialogDelegate* GetDialogDelegate() const;
@@ -76,34 +83,25 @@
   void ChildPreferredSizeChanged(View* child) override;
   void ChildVisibilityChanged(View* child) override;
 
-  // Create a dialog button of the appropriate type.
-  LabelButton* CreateDialogButton(ui::DialogButton type);
-
-  // Update |button|'s text and enabled state according to the delegate's state.
-  void UpdateButton(LabelButton* button, ui::DialogButton type);
-
-  // Returns the height of the buttons.
-  int GetButtonHeight() const;
-
-  // Returns the height of the extra view.
-  int GetExtraViewHeight() const;
-
-  // Returns the height of the row containing the buttons and the extra view.
-  int GetButtonsAndExtraViewRowHeight() const;
-
-  // Returns the insets for the buttons and extra view, including the vertical
-  // padding between them and the contents view.
-  gfx::Insets GetButtonRowInsets() const;
-
-  // Sets up the focus chain for the child views. This is required since the
-  // delegate may choose to add/remove views at any time.
-  void SetupFocusChain();
+  // Creates, deletes, or updates the appearance of the button of type |type|
+  // (which must be pointed to by |member|).  Which action is chosen is based on
+  // whether DialogDelegate::GetDialogButtons() includes |type|, and whether
+  // |member| points to a button that already exists.
+  void UpdateDialogButton(LabelButton** member, ui::DialogButton type);
 
   // Returns the spacing between the extra view and the ok/cancel buttons. 0 if
   // no extra view. Otherwise uses GetExtraViewPadding() or the default padding.
   int GetExtraViewSpacing() const;
 
+  // Returns Views in the button row, as they should appear in the layout. If
+  // a View should not appear, it will be null.
+  std::array<View*, kNumButtons> GetButtonRowViews();
+
+  // Installs and configures the LayoutManager for |button_row_container_|.
+  void SetupLayout();
+
   // Creates or deletes any buttons that are required. Updates data members.
+  // After calling this, no button row Views will be in the view hierarchy.
   void SetupViews();
 
   // How much to inset the button row.
@@ -120,12 +118,18 @@
   // The extra view shown in the row of buttons; may be NULL.
   View* extra_view_ = nullptr;
 
+  // Container view for the button row.
+  ButtonRowContainer* button_row_container_ = nullptr;
+
   // True if we've notified the delegate the window is closing and the delegate
   // allowed the close. In some situations it's possible to get two closes (see
   // http://crbug.com/71940). This is used to avoid notifying the delegate
   // twice, which can have bad consequences.
   bool delegate_allowed_close_ = false;
 
+  // When true, prevents ViewHierarchyChanged() from clearing out data members.
+  bool preserve_button_row_data_members_ = false;
+
   DISALLOW_COPY_AND_ASSIGN(DialogClientView);
 };
 
diff --git a/ui/views/window/dialog_client_view_unittest.cc b/ui/views/window/dialog_client_view_unittest.cc
index e4d7eeb..a8d3d8d 100644
--- a/ui/views/window/dialog_client_view_unittest.cc
+++ b/ui/views/window/dialog_client_view_unittest.cc
@@ -7,6 +7,7 @@
 #include "base/macros.h"
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
+#include "ui/base/test/material_design_controller_test_api.h"
 #include "ui/base/ui_base_types.h"
 #include "ui/views/controls/button/label_button.h"
 #include "ui/views/style/platform_style.h"
@@ -43,6 +44,9 @@
   }
 
   // DialogDelegateView:
+  gfx::Size GetPreferredSize() const override { return preferred_size_; }
+  gfx::Size GetMinimumSize() const override { return min_size_; }
+  gfx::Size GetMaximumSize() const override { return max_size_; }
   ClientView* CreateClientView(Widget* widget) override {
     client_view_ = new DialogClientView(widget, this);
     return client_view_;
@@ -63,6 +67,11 @@
   }
 
   int GetDialogButtons() const override { return dialog_buttons_; }
+  base::string16 GetDialogButtonLabel(ui::DialogButton button) const override {
+    return button == ui::DIALOG_BUTTON_CANCEL && !cancel_label_.empty()
+               ? cancel_label_
+               : DialogDelegate::GetDialogButtonLabel(button);
+  }
 
  protected:
   gfx::Rect GetUpdatedClientBounds() {
@@ -102,7 +111,15 @@
   void SetExtraViewPadding(int padding) {
     DCHECK(!extra_view_padding_);
     extra_view_padding_.reset(new int(padding));
-    client_view_->Layout();
+    client_view_->UpdateDialogButtons();
+  }
+
+  void SetSizeConstraints(const gfx::Size& min_size,
+                          const gfx::Size& preferred_size,
+                          const gfx::Size& max_size) {
+    min_size_ = min_size;
+    preferred_size_ = preferred_size;
+    max_size_ = max_size;
   }
 
   View* FocusableViewAfter(View* view) {
@@ -112,6 +129,12 @@
                                                    dont_loop);
   }
 
+  // Set a longer than normal Cancel label so that the minimum button width is
+  // exceeded.
+  void SetLongCancelLabel() {
+    cancel_label_ = base::ASCIIToUTF16("Cancel Cancel Cancel");
+  }
+
   DialogClientView* client_view() { return client_view_; }
 
  private:
@@ -129,6 +152,12 @@
 
   std::unique_ptr<int> extra_view_padding_;
 
+  gfx::Size preferred_size_;
+  gfx::Size min_size_;
+  gfx::Size max_size_;
+
+  base::string16 cancel_label_;  // If set, the label for the Cancel button.
+
   DISALLOW_COPY_AND_ASSIGN(DialogClientViewTest);
 };
 
@@ -188,24 +217,27 @@
   const bool kIsOkButtonOnLeftSide = false;
 #endif
 
+  GetContentsView()->SetFocusBehavior(View::FocusBehavior::ALWAYS);
   // Initially the dialog client view only contains the content view.
-  EXPECT_EQ(nullptr, GetContentsView()->GetNextFocusableView());
+  EXPECT_EQ(GetContentsView(), FocusableViewAfter(GetContentsView()));
 
   // Add OK and cancel buttons.
   SetDialogButtons(ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL);
 
   if (kIsOkButtonOnLeftSide) {
     EXPECT_EQ(client_view()->ok_button(),
-              GetContentsView()->GetNextFocusableView());
+              FocusableViewAfter(GetContentsView()));
     EXPECT_EQ(client_view()->cancel_button(),
-              client_view()->ok_button()->GetNextFocusableView());
-    EXPECT_EQ(nullptr, client_view()->cancel_button()->GetNextFocusableView());
+              FocusableViewAfter(client_view()->ok_button()));
+    EXPECT_EQ(GetContentsView(),
+              FocusableViewAfter(client_view()->cancel_button()));
   } else {
     EXPECT_EQ(client_view()->cancel_button(),
-              GetContentsView()->GetNextFocusableView());
+              FocusableViewAfter(GetContentsView()));
     EXPECT_EQ(client_view()->ok_button(),
-              client_view()->cancel_button()->GetNextFocusableView());
-    EXPECT_EQ(nullptr, client_view()->ok_button()->GetNextFocusableView());
+              FocusableViewAfter(client_view()->cancel_button()));
+    EXPECT_EQ(GetContentsView(),
+              FocusableViewAfter(client_view()->ok_button()));
   }
 
   // Add extra view and remove OK button.
@@ -214,14 +246,15 @@
   SetExtraView(extra_view);
   SetDialogButtons(ui::DIALOG_BUTTON_CANCEL);
 
-  EXPECT_EQ(extra_view, GetContentsView()->GetNextFocusableView());
-  EXPECT_EQ(client_view()->cancel_button(), extra_view->GetNextFocusableView());
-  EXPECT_EQ(nullptr, client_view()->cancel_button()->GetNextFocusableView());
+  EXPECT_EQ(extra_view, FocusableViewAfter(GetContentsView()));
+  EXPECT_EQ(client_view()->cancel_button(), FocusableViewAfter(extra_view));
+  EXPECT_EQ(GetContentsView(), FocusableViewAfter(client_view()));
 
   // Add a dummy view to the contents view. Consult the FocusManager for the
   // traversal order since it now spans different levels of the view hierarchy.
   View* dummy_view = new StaticSizedView(gfx::Size(200, 200));
   dummy_view->SetFocusBehavior(View::FocusBehavior::ALWAYS);
+  GetContentsView()->SetFocusBehavior(View::FocusBehavior::NEVER);
   GetContentsView()->AddChildView(dummy_view);
   EXPECT_EQ(dummy_view, FocusableViewAfter(client_view()->cancel_button()));
   EXPECT_EQ(extra_view, FocusableViewAfter(dummy_view));
@@ -248,31 +281,128 @@
 
   EXPECT_LT(GetContentsView()->bounds().bottom(),
             client_view()->bounds().bottom());
-  gfx::Size no_extra_view_size = client_view()->bounds().size();
+  const gfx::Size no_extra_view_size = client_view()->bounds().size();
 
   View* extra_view = new StaticSizedView(gfx::Size(200, 200));
   SetExtraView(extra_view);
   CheckContentsIsSetToPreferredSize();
   EXPECT_GT(client_view()->bounds().height(), no_extra_view_size.height());
-  int width_of_dialog = client_view()->bounds().width();
-  int width_of_extra_view = extra_view->bounds().width();
+  const int width_of_dialog_small_padding = client_view()->width();
 
   // Try with an adjusted padding for the extra view.
   SetExtraViewPadding(250);
   CheckContentsIsSetToPreferredSize();
-  EXPECT_GT(client_view()->bounds().width(), width_of_dialog);
+  EXPECT_GT(client_view()->bounds().width(), width_of_dialog_small_padding);
 
-  // Visibility of extra view is respected.
+  const gfx::Size with_extra_view_size = client_view()->size();
+  EXPECT_NE(no_extra_view_size, with_extra_view_size);
+
+  // Hiding the extra view removes it as well as the extra padding.
   extra_view->SetVisible(false);
   CheckContentsIsSetToPreferredSize();
-  EXPECT_EQ(no_extra_view_size.height(), client_view()->bounds().height());
-  EXPECT_EQ(no_extra_view_size.width(), client_view()->bounds().width());
+  EXPECT_EQ(no_extra_view_size, client_view()->size());
 
-  // Try with a reduced-size dialog.
+  // Making it visible again adds it all back.
   extra_view->SetVisible(true);
-  client_view()->SetBoundsRect(gfx::Rect(gfx::Point(0, 0), no_extra_view_size));
-  client_view()->Layout();
-  EXPECT_GT(width_of_extra_view, extra_view->bounds().width());
+  CheckContentsIsSetToPreferredSize();
+  EXPECT_EQ(with_extra_view_size, client_view()->size());
+
+  // Leave |extra_view| hidden. It should still have a parent, to ensure it is
+  // owned by a View hierarchy and gets deleted.
+  extra_view->SetVisible(false);
+  EXPECT_TRUE(extra_view->parent());
+}
+
+// Ensure the minimum, maximum and preferred sizes of the contents view are
+// respected by the client view, and that the client view includes the button
+// row in its minimum and preferred size calculations.
+TEST_F(DialogClientViewTest, MinMaxPreferredSize) {
+  SetDialogButtons(ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL);
+  const gfx::Size buttons_size = client_view()->GetPreferredSize();
+  EXPECT_FALSE(buttons_size.IsEmpty());
+
+  // When the contents view has no preference, just fit the buttons. The
+  // maximum size should be unconstrained in both directions.
+  EXPECT_EQ(buttons_size, client_view()->GetMinimumSize());
+  EXPECT_EQ(gfx::Size(), client_view()->GetMaximumSize());
+
+  // Ensure buttons are between these widths, for the constants below.
+  EXPECT_LT(20, buttons_size.width());
+  EXPECT_GT(300, buttons_size.width());
+
+  // With no buttons, client view should match the contents view.
+  SetDialogButtons(ui::DIALOG_BUTTON_NONE);
+  SetSizeConstraints(gfx::Size(10, 15), gfx::Size(20, 25), gfx::Size(300, 350));
+  EXPECT_EQ(gfx::Size(10, 15), client_view()->GetMinimumSize());
+  EXPECT_EQ(gfx::Size(20, 25), client_view()->GetPreferredSize());
+  EXPECT_EQ(gfx::Size(300, 350), client_view()->GetMaximumSize());
+
+  // With buttons, size should increase vertically only.
+  SetDialogButtons(ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL);
+  EXPECT_EQ(gfx::Size(buttons_size.width(), 15 + buttons_size.height()),
+            client_view()->GetMinimumSize());
+  EXPECT_EQ(gfx::Size(buttons_size.width(), 25 + buttons_size.height()),
+            client_view()->GetPreferredSize());
+  EXPECT_EQ(gfx::Size(300, 350 + buttons_size.height()),
+            client_view()->GetMaximumSize());
+
+  // If the contents view gets bigger, it should take over the width.
+  SetSizeConstraints(gfx::Size(400, 450), gfx::Size(500, 550),
+                     gfx::Size(600, 650));
+  EXPECT_EQ(gfx::Size(400, 450 + buttons_size.height()),
+            client_view()->GetMinimumSize());
+  EXPECT_EQ(gfx::Size(500, 550 + buttons_size.height()),
+            client_view()->GetPreferredSize());
+  EXPECT_EQ(gfx::Size(600, 650 + buttons_size.height()),
+            client_view()->GetMaximumSize());
+}
+
+// Ensure button widths are linked under MD.
+TEST_F(DialogClientViewTest, LinkedWidths) {
+  ui::test::MaterialDesignControllerTestAPI md_test_api(
+      ui::MaterialDesignController::MATERIAL_NORMAL);
+  md_test_api.SetSecondaryUiMaterial(true);
+  SetLongCancelLabel();
+
+  SetDialogButtons(ui::DIALOG_BUTTON_OK);
+  CheckContentsIsSetToPreferredSize();
+  const int ok_button_only_width = client_view()->ok_button()->width();
+
+  SetDialogButtons(ui::DIALOG_BUTTON_CANCEL);
+  CheckContentsIsSetToPreferredSize();
+  const int cancel_button_width = client_view()->cancel_button()->width();
+
+  // Ensure the single buttons have different preferred widths when alone, and
+  // that the Cancel button is bigger (so that it dominates the size).
+  EXPECT_GT(cancel_button_width, ok_button_only_width);
+
+  SetDialogButtons(ui::DIALOG_BUTTON_CANCEL | ui::DIALOG_BUTTON_OK);
+  CheckContentsIsSetToPreferredSize();
+
+  // OK button should now match the bigger, cancel button.
+  EXPECT_EQ(cancel_button_width, client_view()->ok_button()->width());
+
+  // But not under non-MD.
+  md_test_api.SetSecondaryUiMaterial(false);
+  client_view()->UpdateDialogButtons();
+  CheckContentsIsSetToPreferredSize();
+  EXPECT_EQ(ok_button_only_width, client_view()->ok_button()->width());
+  md_test_api.SetSecondaryUiMaterial(true);
+
+  // The extra view should also match, if it's a button.
+  LabelButton* extra_button = new LabelButton(nullptr, base::string16());
+  SetExtraView(extra_button);
+  CheckContentsIsSetToPreferredSize();
+  EXPECT_EQ(cancel_button_width, extra_button->width());
+
+  // Remove |extra_button| from the View hierarchy so that it can be replaced.
+  delete extra_button;
+
+  // Non-buttons should always be sized to their preferred size.
+  View* boring_view = new StaticSizedView(gfx::Size(20, 20));
+  SetExtraView(boring_view);
+  CheckContentsIsSetToPreferredSize();
+  EXPECT_EQ(20, boring_view->width());
 }
 
 }  // namespace views
diff --git a/ui/webui/resources/cr_elements/policy/cr_policy_indicator_behavior.js b/ui/webui/resources/cr_elements/policy/cr_policy_indicator_behavior.js
index 6ebec5e..2ad6059 100644
--- a/ui/webui/resources/cr_elements/policy/cr_policy_indicator_behavior.js
+++ b/ui/webui/resources/cr_elements/policy/cr_policy_indicator_behavior.js
@@ -12,6 +12,7 @@
  * Strings required for policy indicators. These must be set at runtime.
  * Chrome OS only strings may be undefined.
  * @type {{
+ *   controlledSettingExtension: string,
  *   controlledSettingPolicy: string,
  *   controlledSettingRecommendedMatches: string,
  *   controlledSettingRecommendedDiffers: string,
@@ -79,8 +80,7 @@
    * @private
    */
   getIndicatorVisible_: function(type) {
-    return type != CrPolicyIndicatorType.NONE &&
-        type != CrPolicyIndicatorType.EXTENSION;
+    return type != CrPolicyIndicatorType.NONE;
   },
 
   /**
@@ -89,26 +89,22 @@
    * @private
    */
   getIndicatorIcon_: function(type) {
-    var icon = '';
     switch (type) {
       case CrPolicyIndicatorType.EXTENSION:
+        return 'cr:extension';
       case CrPolicyIndicatorType.NONE:
-        return icon;
+        return '';
       case CrPolicyIndicatorType.PRIMARY_USER:
-        icon = 'cr:group';
-        break;
+        return 'cr:group';
       case CrPolicyIndicatorType.OWNER:
-        icon = 'cr:person';
-        break;
+        return 'cr:person';
       case CrPolicyIndicatorType.USER_POLICY:
       case CrPolicyIndicatorType.DEVICE_POLICY:
       case CrPolicyIndicatorType.RECOMMENDED:
-        icon = 'cr20:domain';
-        break;
+        return 'cr20:domain';
       default:
         assertNotReached();
     }
-    return icon;
   },
 
   /**
@@ -123,6 +119,8 @@
     if (!CrPolicyStrings)
       return '';  // Tooltips may not be defined, e.g. in OOBE.
     switch (type) {
+      case CrPolicyIndicatorType.EXTENSION:
+        return CrPolicyStrings.controlledSettingExtension;
       case CrPolicyIndicatorType.PRIMARY_USER:
         return CrPolicyStrings.controlledSettingShared.replace('$1', name);
       case CrPolicyIndicatorType.OWNER:
diff --git a/ui/webui/resources/cr_elements/policy/cr_policy_pref_behavior.js b/ui/webui/resources/cr_elements/policy/cr_policy_pref_behavior.js
index ad393b9..d153e0a 100644
--- a/ui/webui/resources/cr_elements/policy/cr_policy_pref_behavior.js
+++ b/ui/webui/resources/cr_elements/policy/cr_policy_pref_behavior.js
@@ -8,21 +8,35 @@
 
 /** @polymerBehavior */
 var CrPolicyPrefBehavior = {
+  properties: {
+    /**
+     * Showing that an extension is controlling a pref is sometimes done with a
+     * different UI (e.g. extension-controlled-indicator). In  those cases,
+     * avoid showing an (extra) indicator here.
+     * @public
+     */
+    ignoreExtensions: Boolean,
+  },
+
   /**
+   * Is the |pref| controlled by something that prevents user control of the
+   * preference.
    * @return {boolean} True if |this.pref| is controlled by an enforced policy.
    */
-  isPrefPolicyControlled: function() {
-    return (
-        this.pref.enforcement == chrome.settingsPrivate.Enforcement.ENFORCED &&
-        this.pref.controlledBy !=
-            chrome.settingsPrivate.ControlledBy.EXTENSION);
+  isPrefEnforced: function() {
+    if (this.ignoreExtensions &&
+        this.pref.controlledBy ==
+            chrome.settingsPrivate.ControlledBy.EXTENSION) {
+      return false;
+    }
+    return this.pref.enforcement == chrome.settingsPrivate.Enforcement.ENFORCED;
   },
 
   /**
    * @return {boolean} True if |this.pref| has a recommended or enforced policy.
    */
   hasPrefPolicyIndicator: function() {
-    return this.isPrefPolicyControlled() ||
+    return this.isPrefEnforced() ||
         this.pref.enforcement == chrome.settingsPrivate.Enforcement.RECOMMENDED;
   },
 };
diff --git a/ui/webui/resources/cr_elements/policy/cr_policy_pref_indicator.js b/ui/webui/resources/cr_elements/policy/cr_policy_pref_indicator.js
index 532b0763..99d5b08 100644
--- a/ui/webui/resources/cr_elements/policy/cr_policy_pref_indicator.js
+++ b/ui/webui/resources/cr_elements/policy/cr_policy_pref_indicator.js
@@ -48,6 +48,8 @@
       return CrPolicyIndicatorType.RECOMMENDED;
     if (enforcement == chrome.settingsPrivate.Enforcement.ENFORCED) {
       switch (controlledBy) {
+        case chrome.settingsPrivate.ControlledBy.EXTENSION:
+          return CrPolicyIndicatorType.EXTENSION;
         case chrome.settingsPrivate.ControlledBy.PRIMARY_USER:
           return CrPolicyIndicatorType.PRIMARY_USER;
         case chrome.settingsPrivate.ControlledBy.OWNER: