diff --git a/AUTHORS b/AUTHORS
index 4100e723..75487640 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -392,6 +392,7 @@
 Kirk Shoop <kirk.shoop@microsoft.com>
 Kihwang Kim <pwangkk@gmail.com>
 Klemen Forstnerič <klemen.forstneric@gmail.com>
+Konrad Dzwinel <kdzwinel@gmail.com>
 Krishna Chaitanya <krish.botta@samsung.com>
 Kristof Kosztyo <kkosztyo.u-szeged@partner.samsung.com>
 Krzysztof Czech <k.czech@samsung.com>
diff --git a/DEPS b/DEPS
index 434a7de..31e0cee 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': 'bbab477b49e2aed0f257206ce457814c953d574b',
+  'skia_revision': 'b399e38518c7c28e94579ce382e64fdf0697a7e9',
   # 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': '35e713ce9a5629d09b38019e0e5725bf43d018dd',
+  'v8_revision': '642e2c8722ff4d846c295047dc0f6a58ceea7e35',
   # 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': '6814f49aa83916aea14bea2a1e78dac455436713',
+  'pdfium_revision': '8df02348924f66e14131aa378abc6c6ea7a352b6',
   # 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.
@@ -96,7 +96,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling catapult
   # and whatever else without interference from each other.
-  'catapult_revision': '19565fdb148afc5fc752516f395f715f5d27c1f1',
+  'catapult_revision': 'c69690acc34b8be0d85596bc5ad40fce7502817a',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -201,7 +201,7 @@
     Var('chromium_git') + '/webm/libvpx.git' + '@' +  'd7f1d60c51b47f6d22be919362caad09469a058b',
 
   'src/third_party/ffmpeg':
-    Var('chromium_git') + '/chromium/third_party/ffmpeg.git' + '@' + '26be2ced90769f25f83b9a613fe3b3e47c1ce4c6',
+    Var('chromium_git') + '/chromium/third_party/ffmpeg.git' + '@' + 'f309edd7828e3ea500c2891187d15926690ddd27',
 
   'src/third_party/usrsctp/usrsctplib':
     Var('chromium_git') + '/external/github.com/sctplab/usrsctp' + '@' + '7f9228152ab3d70e6848cc9c67389a0d4218740e',
diff --git a/android_webview/java/src/org/chromium/android_webview/AwAutofillClient.java b/android_webview/java/src/org/chromium/android_webview/AwAutofillClient.java
index 65781e4..7bf412e 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwAutofillClient.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwAutofillClient.java
@@ -4,6 +4,7 @@
 
 package org.chromium.android_webview;
 
+import android.graphics.Color;
 import android.view.View;
 import android.view.ViewGroup;
 
@@ -64,7 +65,8 @@
                     public void deleteSuggestion(int listIndex) { }
                 });
         }
-        mAutofillPopup.filterAndShow(suggestions, isRtl);
+        mAutofillPopup.filterAndShow(suggestions, isRtl, Color.TRANSPARENT /* backgroundColor */,
+                Color.TRANSPARENT /* dividerColor */, 0 /* dropdownItemHeight */);
     }
 
     @CalledByNative
@@ -89,8 +91,9 @@
     @CalledByNative
     private static void addToAutofillSuggestionArray(AutofillSuggestion[] array, int index,
             String name, String label, int uniqueId) {
-        array[index] =
-                new AutofillSuggestion(name, label, DropdownItem.NO_ICON, uniqueId, false, false);
+        array[index] = new AutofillSuggestion(name, label, DropdownItem.NO_ICON,
+                false /* isIconAtLeft */, uniqueId, false /* isDeletable */,
+                false /* isMultilineLabel */, false /* isBoldLabel */);
     }
 
     private native void nativeDismissed(long nativeAwAutofillClient);
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/PlatformMediaCodecTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/PlatformMediaCodecTest.java
index e5a0567..42942e8 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/PlatformMediaCodecTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/PlatformMediaCodecTest.java
@@ -4,7 +4,9 @@
 
 package org.chromium.android_webview.test;
 
-import org.chromium.base.test.util.DisabledTest;
+import android.test.suitebuilder.annotation.MediumTest;
+
+import org.chromium.base.test.util.Feature;
 import org.chromium.content.browser.ContentViewCore;
 import org.chromium.content.browser.test.util.DOMUtils;
 import org.chromium.content_public.browser.WebContents;
@@ -28,11 +30,8 @@
         enableJavaScriptOnUiThread(mTestContainerView.getAwContents());
     }
 
-    /*
     @MediumTest
     @Feature({"AndroidWebView"})
-    */
-    @DisabledTest(message = "crbug.com/620890")
     public void testCanPlayPlatformMediaCodecs() throws Throwable {
         loadUrlSync(mTestContainerView.getAwContents(), mContentsClient.getOnPageFinishedHelper(),
                 "file:///android_asset/platform-media-codec-test.html");
diff --git a/ash/common/accelerators/accelerator_table.cc b/ash/common/accelerators/accelerator_table.cc
index 4181c1dc..00a1a32e 100644
--- a/ash/common/accelerators/accelerator_table.cc
+++ b/ash/common/accelerators/accelerator_table.cc
@@ -341,6 +341,7 @@
     DISABLE_CAPS_LOCK,
     KEYBOARD_BRIGHTNESS_DOWN,
     KEYBOARD_BRIGHTNESS_UP,
+    SHOW_IME_MENU_BUBBLE,
     TOGGLE_CAPS_LOCK,
     TOGGLE_HIGH_CONTRAST,
     TOGGLE_SPOKEN_FEEDBACK,
diff --git a/ash/resources/BUILD.gn b/ash/resources/BUILD.gn
index 1454da5..57aeab68 100644
--- a/ash/resources/BUILD.gn
+++ b/ash/resources/BUILD.gn
@@ -6,6 +6,7 @@
 import("//tools/grit/repack.gni")
 import("//ui/base/ui_features.gni")
 
+assert(is_chromeos)
 assert(enable_hidpi)
 
 grit("resources") {
@@ -27,7 +28,10 @@
 
     sources = [
       "$root_gen_dir/ash/resources/ash_resources_${percent}_percent.pak",
+      "$root_gen_dir/ui/app_list/resources/app_list_resources_${percent}_percent.pak",
+      "$root_gen_dir/ui/chromeos/resources/ui_chromeos_resources_${percent}_percent.pak",
       "$root_gen_dir/ui/resources/ui_resources_${percent}_percent.pak",
+      "$root_gen_dir/ui/views/resources/views_resources_${percent}_percent.pak",
     ]
 
     if (percent == "100") {
@@ -40,34 +44,20 @@
 
     deps = [
       "//ash/resources",
+      "//ui/app_list/resources",
+      "//ui/chromeos/resources",
       "//ui/resources",
+      "//ui/views/resources",
     ]
 
     if (defined(invoker.deps)) {
       deps += invoker.deps
     }
 
-    if (toolkit_views) {
-      deps += [
-        "//ui/app_list/resources",
-        "//ui/views/resources",
-      ]
-      sources += [
-        "$root_gen_dir/ui/app_list/resources/app_list_resources_${percent}_percent.pak",
-        "$root_gen_dir/ui/views/resources/views_resources_${percent}_percent.pak",
-      ]
-
-      if (percent == "100") {
-        # TODO(msw): This seems bad, but follows repack_ui_test_pak's example.
-        deps += [ "//third_party/WebKit/public:resources_grit" ]
-        sources +=
-            [ "$root_gen_dir/blink/public/resources/blink_resources.pak" ]
-      }
-    }
-
-    if (is_chromeos) {
-      sources += [ "$root_gen_dir/ui/chromeos/resources/ui_chromeos_resources_${percent}_percent.pak" ]
-      deps += [ "//ui/chromeos/resources" ]
+    if (percent == "100") {
+      # TODO(msw): This seems bad, but follows repack_ui_test_pak's example.
+      deps += [ "//third_party/WebKit/public:resources_grit" ]
+      sources += [ "$root_gen_dir/blink/public/resources/blink_resources.pak" ]
     }
   }
 }
diff --git a/base/metrics/statistics_recorder.cc b/base/metrics/statistics_recorder.cc
index 6b1b0bf..4828450 100644
--- a/base/metrics/statistics_recorder.cc
+++ b/base/metrics/statistics_recorder.cc
@@ -16,7 +16,6 @@
 #include "base/metrics/persistent_histogram_allocator.h"
 #include "base/stl_util.h"
 #include "base/strings/stringprintf.h"
-#include "base/synchronization/lock.h"
 #include "base/values.h"
 
 namespace {
@@ -59,10 +58,10 @@
 StatisticsRecorder::HistogramIterator&
 StatisticsRecorder::HistogramIterator::operator++() {
   const HistogramMap::iterator histograms_end = histograms_->end();
-  if (iter_ == histograms_end || lock_ == NULL)
+  if (iter_ == histograms_end)
     return *this;
 
-  base::AutoLock auto_lock(*lock_);
+  base::AutoLock auto_lock(lock_.Get());
 
   for (;;) {
     ++iter_;
@@ -79,13 +78,12 @@
 }
 
 StatisticsRecorder::~StatisticsRecorder() {
-  DCHECK(lock_);
   DCHECK(histograms_);
   DCHECK(ranges_);
 
   // Clean out what this object created and then restore what existed before.
   Reset();
-  base::AutoLock auto_lock(*lock_);
+  base::AutoLock auto_lock(lock_.Get());
   histograms_ = existing_histograms_.release();
   callbacks_ = existing_callbacks_.release();
   ranges_ = existing_ranges_.release();
@@ -110,31 +108,26 @@
 
 // static
 bool StatisticsRecorder::IsActive() {
-  if (lock_ == NULL)
-    return false;
-  base::AutoLock auto_lock(*lock_);
-  return NULL != histograms_;
+  base::AutoLock auto_lock(lock_.Get());
+  return histograms_ != nullptr;
 }
 
 // static
 HistogramBase* StatisticsRecorder::RegisterOrDeleteDuplicate(
     HistogramBase* histogram) {
-  // As per crbug.com/79322 the histograms are intentionally leaked, so we need
-  // to annotate them. Because ANNOTATE_LEAKING_OBJECT_PTR may be used only once
-  // for an object, the duplicates should not be annotated.
-  // Callers are responsible for not calling RegisterOrDeleteDuplicate(ptr)
-  // twice if (lock_ == NULL) || (!histograms_).
-  if (lock_ == NULL) {
-    ANNOTATE_LEAKING_OBJECT_PTR(histogram);  // see crbug.com/79322
-    return histogram;
-  }
-
-  HistogramBase* histogram_to_delete = NULL;
-  HistogramBase* histogram_to_return = NULL;
+  HistogramBase* histogram_to_delete = nullptr;
+  HistogramBase* histogram_to_return = nullptr;
   {
-    base::AutoLock auto_lock(*lock_);
-    if (histograms_ == NULL) {
+    base::AutoLock auto_lock(lock_.Get());
+    if (!histograms_) {
       histogram_to_return = histogram;
+
+      // As per crbug.com/79322 the histograms are intentionally leaked, so we
+      // need to annotate them. Because ANNOTATE_LEAKING_OBJECT_PTR may be used
+      // only once for an object, the duplicates should not be annotated.
+      // Callers are responsible for not calling RegisterOrDeleteDuplicate(ptr)
+      // twice |if (!histograms_)|.
+      ANNOTATE_LEAKING_OBJECT_PTR(histogram);  // see crbug.com/79322
     } else {
       const std::string& name = histogram->histogram_name();
       HistogramMap::iterator it = histograms_->find(name);
@@ -175,13 +168,8 @@
   DCHECK(ranges->HasValidChecksum());
   std::unique_ptr<const BucketRanges> ranges_deleter;
 
-  if (lock_ == NULL) {
-    ANNOTATE_LEAKING_OBJECT_PTR(ranges);
-    return ranges;
-  }
-
-  base::AutoLock auto_lock(*lock_);
-  if (ranges_ == NULL) {
+  base::AutoLock auto_lock(lock_.Get());
+  if (!ranges_) {
     ANNOTATE_LEAKING_OBJECT_PTR(ranges);
     return ranges;
   }
@@ -278,10 +266,8 @@
 
 // static
 void StatisticsRecorder::GetHistograms(Histograms* output) {
-  if (lock_ == NULL)
-    return;
-  base::AutoLock auto_lock(*lock_);
-  if (histograms_ == NULL)
+  base::AutoLock auto_lock(lock_.Get());
+  if (!histograms_)
     return;
 
   for (const auto& entry : *histograms_) {
@@ -292,10 +278,8 @@
 // static
 void StatisticsRecorder::GetBucketRanges(
     std::vector<const BucketRanges*>* output) {
-  if (lock_ == NULL)
-    return;
-  base::AutoLock auto_lock(*lock_);
-  if (ranges_ == NULL)
+  base::AutoLock auto_lock(lock_.Get());
+  if (!ranges_)
     return;
 
   for (const auto& entry : *ranges_) {
@@ -312,15 +296,13 @@
   // will acquire the lock at that time.
   ImportGlobalPersistentHistograms();
 
-  if (lock_ == NULL)
-    return NULL;
-  base::AutoLock auto_lock(*lock_);
-  if (histograms_ == NULL)
-    return NULL;
+  base::AutoLock auto_lock(lock_.Get());
+  if (!histograms_)
+    return nullptr;
 
   HistogramMap::iterator it = histograms_->find(name);
   if (histograms_->end() == it)
-    return NULL;
+    return nullptr;
   return it->second;
 }
 
@@ -332,7 +314,7 @@
 
   HistogramMap::iterator iter_begin;
   {
-    base::AutoLock auto_lock(*lock_);
+    base::AutoLock auto_lock(lock_.Get());
     iter_begin = histograms_->begin();
   }
   return HistogramIterator(iter_begin, include_persistent);
@@ -342,7 +324,7 @@
 StatisticsRecorder::HistogramIterator StatisticsRecorder::end() {
   HistogramMap::iterator iter_end;
   {
-    base::AutoLock auto_lock(*lock_);
+    base::AutoLock auto_lock(lock_.Get());
     iter_end = histograms_->end();
   }
   return HistogramIterator(iter_end, true);
@@ -350,19 +332,18 @@
 
 // static
 void StatisticsRecorder::InitLogOnShutdown() {
-  if (lock_ == nullptr)
+  if (!histograms_)
     return;
-  base::AutoLock auto_lock(*lock_);
+
+  base::AutoLock auto_lock(lock_.Get());
   g_statistics_recorder_.Get().InitLogOnShutdownWithoutLock();
 }
 
 // static
 void StatisticsRecorder::GetSnapshot(const std::string& query,
                                      Histograms* snapshot) {
-  if (lock_ == NULL)
-    return;
-  base::AutoLock auto_lock(*lock_);
-  if (histograms_ == NULL)
+  base::AutoLock auto_lock(lock_.Get());
+  if (!histograms_)
     return;
 
   for (const auto& entry : *histograms_) {
@@ -376,10 +357,8 @@
     const std::string& name,
     const StatisticsRecorder::OnSampleCallback& cb) {
   DCHECK(!cb.is_null());
-  if (lock_ == NULL)
-    return false;
-  base::AutoLock auto_lock(*lock_);
-  if (histograms_ == NULL)
+  base::AutoLock auto_lock(lock_.Get());
+  if (!histograms_)
     return false;
 
   if (ContainsKey(*callbacks_, name))
@@ -395,10 +374,8 @@
 
 // static
 void StatisticsRecorder::ClearCallback(const std::string& name) {
-  if (lock_ == NULL)
-    return;
-  base::AutoLock auto_lock(*lock_);
-  if (histograms_ == NULL)
+  base::AutoLock auto_lock(lock_.Get());
+  if (!histograms_)
     return;
 
   callbacks_->erase(name);
@@ -412,10 +389,8 @@
 // static
 StatisticsRecorder::OnSampleCallback StatisticsRecorder::FindCallback(
     const std::string& name) {
-  if (lock_ == NULL)
-    return OnSampleCallback();
-  base::AutoLock auto_lock(*lock_);
-  if (histograms_ == NULL)
+  base::AutoLock auto_lock(lock_.Get());
+  if (!histograms_)
     return OnSampleCallback();
 
   auto callback_iterator = callbacks_->find(name);
@@ -425,10 +400,7 @@
 
 // static
 size_t StatisticsRecorder::GetHistogramCount() {
-  if (!lock_)
-    return 0;
-
-  base::AutoLock auto_lock(*lock_);
+  base::AutoLock auto_lock(lock_.Get());
   if (!histograms_)
     return 0;
   return histograms_->size();
@@ -449,7 +421,7 @@
 // static
 void StatisticsRecorder::UninitializeForTesting() {
   // Stop now if it's never been initialized.
-  if (lock_ == NULL || histograms_ == NULL)
+  if (!histograms_)
     return;
 
   // Get the global instance and destruct it. It's held in static memory so
@@ -465,7 +437,7 @@
 
 // static
 void StatisticsRecorder::ImportGlobalPersistentHistograms() {
-  if (lock_ == NULL)
+  if (!histograms_)
     return;
 
   // Import histograms from known persistent storage. Histograms could have
@@ -481,17 +453,7 @@
 // of main(), and hence it is not thread safe.  It initializes globals to
 // provide support for all future calls.
 StatisticsRecorder::StatisticsRecorder() {
-  if (lock_ == NULL) {
-    // This will leak on purpose. It's the only way to make sure we won't race
-    // against the static uninitialization of the module while one of our
-    // static methods relying on the lock get called at an inappropriate time
-    // during the termination phase. Since it's a static data member, we will
-    // leak one per process, which would be similar to the instance allocated
-    // during static initialization and released only on  process termination.
-    lock_ = new base::Lock;
-  }
-
-  base::AutoLock auto_lock(*lock_);
+  base::AutoLock auto_lock(lock_.Get());
 
   existing_histograms_.reset(histograms_);
   existing_callbacks_.reset(callbacks_);
@@ -513,23 +475,18 @@
 
 // static
 void StatisticsRecorder::Reset() {
-  // If there's no lock then there is nothing to reset.
-  if (!lock_)
-    return;
 
   std::unique_ptr<HistogramMap> histograms_deleter;
   std::unique_ptr<CallbackMap> callbacks_deleter;
   std::unique_ptr<RangesMap> ranges_deleter;
-  // We don't delete lock_ on purpose to avoid having to properly protect
-  // against it going away after we checked for NULL in the static methods.
   {
-    base::AutoLock auto_lock(*lock_);
+    base::AutoLock auto_lock(lock_.Get());
     histograms_deleter.reset(histograms_);
     callbacks_deleter.reset(callbacks_);
     ranges_deleter.reset(ranges_);
-    histograms_ = NULL;
-    callbacks_ = NULL;
-    ranges_ = NULL;
+    histograms_ = nullptr;
+    callbacks_ = nullptr;
+    ranges_ = nullptr;
   }
   // We are going to leak the histograms and the ranges.
 }
@@ -543,12 +500,13 @@
 
 
 // static
-StatisticsRecorder::HistogramMap* StatisticsRecorder::histograms_ = NULL;
+StatisticsRecorder::HistogramMap* StatisticsRecorder::histograms_ = nullptr;
 // static
-StatisticsRecorder::CallbackMap* StatisticsRecorder::callbacks_ = NULL;
+StatisticsRecorder::CallbackMap* StatisticsRecorder::callbacks_ = nullptr;
 // static
-StatisticsRecorder::RangesMap* StatisticsRecorder::ranges_ = NULL;
+StatisticsRecorder::RangesMap* StatisticsRecorder::ranges_ = nullptr;
 // static
-base::Lock* StatisticsRecorder::lock_ = NULL;
+base::LazyInstance<base::Lock>::Leaky StatisticsRecorder::lock_ =
+    LAZY_INSTANCE_INITIALIZER;
 
 }  // namespace base
diff --git a/base/metrics/statistics_recorder.h b/base/metrics/statistics_recorder.h
index b4dae87..6deddae 100644
--- a/base/metrics/statistics_recorder.h
+++ b/base/metrics/statistics_recorder.h
@@ -25,11 +25,11 @@
 #include "base/macros.h"
 #include "base/metrics/histogram_base.h"
 #include "base/strings/string_piece.h"
+#include "base/synchronization/lock.h"
 
 namespace base {
 
 class BucketRanges;
-class Lock;
 
 class BASE_EXPORT StatisticsRecorder {
  public:
@@ -230,8 +230,11 @@
   static CallbackMap* callbacks_;
   static RangesMap* ranges_;
 
-  // Lock protects access to above maps.
-  static base::Lock* lock_;
+  // Lock protects access to above maps. This is a LazyInstance to avoid races
+  // when the above methods are used before Initialize(). Previously each method
+  // would do |if (!lock_) return;| which would race with
+  // |lock_ = new Lock;| in StatisticsRecorder(). http://crbug.com/672852.
+  static base::LazyInstance<base::Lock>::Leaky lock_;
 
   DISALLOW_COPY_AND_ASSIGN(StatisticsRecorder);
 };
diff --git a/base/numerics/safe_conversions_impl.h b/base/numerics/safe_conversions_impl.h
index 33d86bc..c4d96365 100644
--- a/base/numerics/safe_conversions_impl.h
+++ b/base/numerics/safe_conversions_impl.h
@@ -54,7 +54,7 @@
 template <typename T>
 constexpr T SafeUnsignedAbsImpl(T value, T sign_mask) {
   static_assert(!std::is_signed<T>::value, "Types must be unsigned.");
-  return (value + sign_mask) ^ sign_mask;
+  return (value ^ sign_mask) - sign_mask;
 }
 
 template <typename T,
diff --git a/build/android/resource_sizes.py b/build/android/resource_sizes.py
index 56e5a496..6df35fd 100755
--- a/build/android/resource_sizes.py
+++ b/build/android/resource_sizes.py
@@ -184,7 +184,8 @@
     return len(self._zip_infos)
 
   def FindByPattern(self, pattern):
-    return next(i for i in self._zip_infos if re.match(pattern, i.filename))
+    return next((i for i in self._zip_infos if re.match(pattern, i.filename)),
+                None)
 
   def FindLargest(self):
     return max(self._zip_infos, key=lambda i: i.file_size)
@@ -366,6 +367,9 @@
   print 'Total uncompressed size: %s' % _FormatBytes(total_file_size)
   print
 
+  if not paks:
+    return
+
   # Output the table of details about all pak files.
   print '%25s%11s%21s%21s' % (
       'FILENAME', 'RESOURCES', 'COMPRESSED SIZE', 'UNCOMPRESSED SIZE')
diff --git a/build/config/BUILD.gn b/build/config/BUILD.gn
index 6cb4134..17e1a61 100644
--- a/build/config/BUILD.gn
+++ b/build/config/BUILD.gn
@@ -136,9 +136,6 @@
   if (!enable_nacl) {
     defines += [ "DISABLE_NACL" ]
   }
-  if (enable_rlz) {
-    defines += [ "ENABLE_RLZ" ]
-  }
   if (enable_wayland_server) {
     defines += [ "ENABLE_WAYLAND_SERVER=1" ]
   }
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
index fae310a..f3a6962 100644
--- a/build/config/compiler/BUILD.gn
+++ b/build/config/compiler/BUILD.gn
@@ -840,6 +840,11 @@
     }
 
     cflags += [
+      # Assume UTF-8 by default to avoid code page dependencies.
+      "/utf-8",
+    ]
+
+    cflags += [
       # Warnings permanently disabled:
 
       # C4091: 'typedef ': ignored on left of 'X' when no variable is
@@ -1070,9 +1075,6 @@
 config("chromium_code") {
   if (is_win) {
     cflags = [ "/W4" ]  # Warning level 4.
-
-    # Assume UTF-8 by default to avoid code page dependencies.
-    cflags += [ "/utf-8" ]
   } else {
     cflags = [ "-Wall" ]
     if (treat_warnings_as_errors) {
diff --git a/build/config/features.gni b/build/config/features.gni
index 9128af4..44fa391 100644
--- a/build/config/features.gni
+++ b/build/config/features.gni
@@ -79,11 +79,6 @@
 
 # Additional dependent variables -----------------------------------------------
 
-# Whether we are using the rlz library or not.  Platforms like Android send
-# rlz codes for searches but do not use the library.
-enable_rlz_support = is_win || is_mac || is_ios || is_chromeos
-enable_rlz = is_chrome_branded && enable_rlz_support
-
 # Chrome OS: whether to also build the upcoming version of
 # ChromeVox, which can then be enabled via a command-line switch.
 enable_chromevox_next = false
diff --git a/cc/output/overlay_candidate.cc b/cc/output/overlay_candidate.cc
index b528488..64ee2a5 100644
--- a/cc/output/overlay_candidate.cc
+++ b/cc/output/overlay_candidate.cc
@@ -335,4 +335,9 @@
 OverlayCandidateList& OverlayCandidateList::operator=(
     OverlayCandidateList&& other) = default;
 
+void OverlayCandidateList::AddPromotionHint(const OverlayCandidate& candidate) {
+  promotion_hint_info_map_[candidate.resource_id] =
+      candidate.display_rect.origin();
+}
+
 }  // namespace cc
diff --git a/cc/output/overlay_candidate.h b/cc/output/overlay_candidate.h
index 68d62e3..e35299ded 100644
--- a/cc/output/overlay_candidate.h
+++ b/cc/output/overlay_candidate.h
@@ -5,6 +5,7 @@
 #ifndef CC_OUTPUT_OVERLAY_CANDIDATE_H_
 #define CC_OUTPUT_OVERLAY_CANDIDATE_H_
 
+#include <map>
 #include <vector>
 
 #include "cc/base/cc_export.h"
@@ -114,9 +115,15 @@
   OverlayCandidateList& operator=(const OverlayCandidateList&);
   OverlayCandidateList& operator=(OverlayCandidateList&&);
 
+  // [id] == origin of candidate's |display_rect| for all promotable resources.
+  using PromotionHintInfoMap = std::map<ResourceId, gfx::PointF>;
+
   // For android, this provides a set of resources that could be promoted to
   // overlay, if one backs them with a SurfaceView.
-  ResourceIdSet promotable_resource_hints_;
+  PromotionHintInfoMap promotion_hint_info_map_;
+
+  // Helper to insert |candidate| into |promotion_hint_info_|.
+  void AddPromotionHint(const OverlayCandidate& candidate);
 };
 
 }  // namespace cc
diff --git a/cc/output/overlay_processor.cc b/cc/output/overlay_processor.cc
index 472b0c2..88523d6 100644
--- a/cc/output/overlay_processor.cc
+++ b/cc/output/overlay_processor.cc
@@ -24,7 +24,7 @@
       : resource_provider_(resource_provider), candidates_(candidates) {}
   ~SendPromotionHintsBeforeReturning() {
     resource_provider_->SendPromotionHints(
-        candidates_->promotable_resource_hints_);
+        candidates_->promotion_hint_info_map_);
   }
 
  private:
diff --git a/cc/output/overlay_strategy_underlay.cc b/cc/output/overlay_strategy_underlay.cc
index e509189..e08c40d 100644
--- a/cc/output/overlay_strategy_underlay.cc
+++ b/cc/output/overlay_strategy_underlay.cc
@@ -52,14 +52,14 @@
       // we can only promote a single quad.  Otherwise, somebody might try to
       // back one of the promotable quads with a SurfaceView, and either it or
       // |candidate| would have to fall back to a texture.
-      candidate_list->promotable_resource_hints_.clear();
-      candidate_list->promotable_resource_hints_.insert(candidate.resource_id);
+      candidate_list->promotion_hint_info_map_.clear();
+      candidate_list->AddPromotionHint(candidate);
       return true;
     } else {
       // If |candidate| should get a promotion hint, then rememeber that now.
-      candidate_list->promotable_resource_hints_.insert(
-          new_candidate_list.promotable_resource_hints_.begin(),
-          new_candidate_list.promotable_resource_hints_.end());
+      candidate_list->promotion_hint_info_map_.insert(
+          new_candidate_list.promotion_hint_info_map_.begin(),
+          new_candidate_list.promotion_hint_info_map_.end());
     }
   }
 
diff --git a/cc/resources/resource_provider.cc b/cc/resources/resource_provider.cc
index b5ee7a99..6547109 100644
--- a/cc/resources/resource_provider.cc
+++ b/cc/resources/resource_provider.cc
@@ -1677,18 +1677,30 @@
 
 #if defined(OS_ANDROID)
 void ResourceProvider::SendPromotionHints(
-    const ResourceIdSet& promotable_hints) {
+    const OverlayCandidateList::PromotionHintInfoMap& promotion_hints) {
+  GLES2Interface* gl = ContextGL();
+  if (!gl)
+    return;
+
   for (const auto& id : wants_promotion_hints_set_) {
+    const ResourceMap::iterator it = resources_.find(id);
+    if (it == resources_.end())
+      continue;
+
+    if (it->second.marked_for_deletion)
+      continue;
+
     const Resource* resource = LockForRead(id);
     DCHECK(resource->wants_promotion_hint);
 
     // Insist that this is backed by a GPU texture.
     if (IsGpuResourceType(resource->type)) {
       DCHECK(resource->gl_id);
-      // TODO(liberato): Here we would either construct a set to send all at
-      // once, or send the promotion hint individually to resource->gl_id, based
-      // on whether promtable_hints.count(it->first) > 0 .
-      // crbug.com/671357
+      auto iter = promotion_hints.find(id);
+      bool promotable = iter != promotion_hints.end();
+      gl->OverlayPromotionHintCHROMIUM(resource->gl_id, promotable,
+                                       promotable ? iter->second.x() : 0,
+                                       promotable ? iter->second.y() : 0);
     }
     UnlockForRead(id);
   }
diff --git a/cc/resources/resource_provider.h b/cc/resources/resource_provider.h
index 5d7ae6f..a9834ca 100644
--- a/cc/resources/resource_provider.h
+++ b/cc/resources/resource_provider.h
@@ -208,10 +208,11 @@
 
 #if defined(OS_ANDROID)
   // Send an overlay promotion hint to all resources that requested it via
-  // |want_promotion_hint|.  |promotable_hints| contains all the resources that
-  // should be told that they're promotable.  Others will be told that they're
-  // not promotable right now.
-  void SendPromotionHints(const ResourceIdSet& promotable_hints);
+  // |wants_promotion_hints_set_|.  |promotable_hints| contains all the
+  // resources that should be told that they're promotable.  Others will be told
+  // that they're not promotable right now.
+  void SendPromotionHints(
+      const OverlayCandidateList::PromotionHintInfoMap& promotion_hints);
 #endif
 
   // The following lock classes are part of the ResourceProvider API and are
diff --git a/cc/tiles/picture_layer_tiling.cc b/cc/tiles/picture_layer_tiling.cc
index 74804dc..d582cb86 100644
--- a/cc/tiles/picture_layer_tiling.cc
+++ b/cc/tiles/picture_layer_tiling.cc
@@ -156,17 +156,14 @@
     SetLiveTilesRect(pending_twin->live_tiles_rect());
   }
 
-  if (tiles_.empty()) {
-    tiles_.swap(pending_twin->tiles_);
-    all_tiles_done_ = pending_twin->all_tiles_done_;
-  } else {
-    while (!pending_twin->tiles_.empty()) {
-      auto pending_iter = pending_twin->tiles_.begin();
-      tiles_[pending_iter->first] = std::move(pending_iter->second);
-      pending_twin->tiles_.erase(pending_iter);
-    }
-    all_tiles_done_ &= pending_twin->all_tiles_done_;
+  while (!pending_twin->tiles_.empty()) {
+    auto pending_iter = pending_twin->tiles_.begin();
+    pending_iter->second->set_tiling(this);
+    tiles_[pending_iter->first] = std::move(pending_iter->second);
+    pending_twin->tiles_.erase(pending_iter);
   }
+  all_tiles_done_ &= pending_twin->all_tiles_done_;
+
   DCHECK(pending_twin->tiles_.empty());
   pending_twin->all_tiles_done_ = true;
 
@@ -323,7 +320,7 @@
   tile_rect.set_size(tiling_data_.max_texture_size());
   gfx::Rect enclosing_layer_rect = gfx::ScaleToEnclosingRect(
       tile_rect, 1.f / raster_scales_.width(), 1.f / raster_scales_.height());
-  return Tile::CreateInfo(i, j, enclosing_layer_rect, tile_rect,
+  return Tile::CreateInfo(this, i, j, enclosing_layer_rect, tile_rect,
                           raster_scales_);
 }
 
diff --git a/cc/tiles/picture_layer_tiling_unittest.cc b/cc/tiles/picture_layer_tiling_unittest.cc
index 3291a33e..a861e87 100644
--- a/cc/tiles/picture_layer_tiling_unittest.cc
+++ b/cc/tiles/picture_layer_tiling_unittest.cc
@@ -1062,5 +1062,32 @@
   VerifyTilesExactlyCoverRect(dest_scale, gfx::Rect(10001, 2));
 }
 
+TEST_F(PictureLayerTilingIteratorTest, TilesStoreTilings) {
+  gfx::Size bounds(200, 200);
+  Initialize(gfx::Size(100, 100), 1.f, bounds);
+  SetLiveRectAndVerifyTiles(gfx::Rect(bounds));
+
+  // Get all tiles and ensure they are associated with |tiling_|.
+  std::vector<Tile*> tiles = tiling_->AllTilesForTesting();
+  EXPECT_TRUE(tiles.size());
+  for (const auto* tile : tiles) {
+    EXPECT_EQ(tile->tiling(), tiling_.get());
+  }
+
+  // Create an active tiling, transfer tiles to that tiling, and ensure that
+  // the tiles have their tiling updated.
+  scoped_refptr<FakeRasterSource> raster_source =
+      FakeRasterSource::CreateFilled(bounds);
+  auto active_tiling = TestablePictureLayerTiling::Create(
+      ACTIVE_TREE, 1.f, raster_source, &client_, LayerTreeSettings());
+  active_tiling->set_resolution(HIGH_RESOLUTION);
+
+  active_tiling->TakeTilesAndPropertiesFrom(tiling_.get(),
+                                            Region(gfx::Rect(bounds)));
+  for (const auto* tile : tiles) {
+    EXPECT_EQ(tile->tiling(), active_tiling.get());
+  }
+}
+
 }  // namespace
 }  // namespace cc
diff --git a/cc/tiles/tile.cc b/cc/tiles/tile.cc
index 1ed26bb4..0dbee11 100644
--- a/cc/tiles/tile.cc
+++ b/cc/tiles/tile.cc
@@ -23,6 +23,7 @@
            int source_frame_number,
            int flags)
     : tile_manager_(tile_manager),
+      tiling_(info.tiling),
       content_rect_(info.content_rect),
       enclosing_layer_rect_(info.enclosing_layer_rect),
       raster_scales_(info.raster_scales),
diff --git a/cc/tiles/tile.h b/cc/tiles/tile.h
index 8da46d6..aecd220b2 100644
--- a/cc/tiles/tile.h
+++ b/cc/tiles/tile.h
@@ -17,6 +17,7 @@
 
 namespace cc {
 
+class PictureLayerTiling;
 class TileManager;
 
 class CC_EXPORT Tile {
@@ -28,18 +29,21 @@
 
   class CC_EXPORT CreateInfo {
    public:
+    const PictureLayerTiling* tiling;
     int tiling_i_index;
     int tiling_j_index;
     gfx::Rect enclosing_layer_rect;
     gfx::Rect content_rect;
     gfx::SizeF raster_scales;
 
-    CreateInfo(int tiling_i_index,
+    CreateInfo(const PictureLayerTiling* tiling,
+               int tiling_i_index,
                int tiling_j_index,
                const gfx::Rect& enclosing_layer_rect,
                const gfx::Rect& content_rect,
                const gfx::SizeF& raster_scales)
-        : tiling_i_index(tiling_i_index),
+        : tiling(tiling),
+          tiling_i_index(tiling_i_index),
           tiling_j_index(tiling_j_index),
           enclosing_layer_rect(enclosing_layer_rect),
           content_rect(content_rect),
@@ -113,6 +117,9 @@
     return is_solid_color_analysis_performed_;
   }
 
+  const PictureLayerTiling* tiling() const { return tiling_; }
+  void set_tiling(const PictureLayerTiling* tiling) { tiling_ = tiling; }
+
  private:
   friend class TileManager;
   friend class FakeTileManager;
@@ -127,6 +134,7 @@
   ~Tile();
 
   TileManager* const tile_manager_;
+  const PictureLayerTiling* tiling_;
   const gfx::Rect content_rect_;
   const gfx::Rect enclosing_layer_rect_;
   const gfx::SizeF raster_scales_;
diff --git a/cc/tiles/tile_manager.cc b/cc/tiles/tile_manager.cc
index 08796a3..5a9d737 100644
--- a/cc/tiles/tile_manager.cc
+++ b/cc/tiles/tile_manager.cc
@@ -1071,7 +1071,10 @@
   // have to iterate the queue to check whether the required tiles are ready to
   // draw.
   for (; !raster_priority_queue->IsEmpty(); raster_priority_queue->Pop()) {
-    if (!raster_priority_queue->Top().tile()->draw_info().IsReadyToDraw())
+    const auto& prioritized_tile = raster_priority_queue->Top();
+    // TODO(vmpstr): Check to debug crbug.com/622080. Remove when fixed.
+    CHECK_EQ(prioritized_tile.priority().priority_bin, TilePriority::NOW);
+    if (!prioritized_tile.tile()->draw_info().IsReadyToDraw())
       return false;
   }
 
diff --git a/chrome/android/java/AndroidManifest.xml b/chrome/android/java/AndroidManifest.xml
index 019ff6dd..02ecd0d 100644
--- a/chrome/android/java/AndroidManifest.xml
+++ b/chrome/android/java/AndroidManifest.xml
@@ -847,7 +847,7 @@
             {{sandboxed_service_extra_flags|default('')}} />
         {% endfor %}
 
-        {% set num_privileged_services = 20 %}
+        {% set num_privileged_services = 3 %}
         <meta-data android:name="org.chromium.content.browser.NUM_PRIVILEGED_SERVICES"
             android:value="{{ num_privileged_services }}"/>
         {% for i in range(num_privileged_services) %}
diff --git a/chrome/android/java/res/layout/history_header.xml b/chrome/android/java/res/layout/history_header.xml
new file mode 100644
index 0000000..3b9e28b
--- /dev/null
+++ b/chrome/android/java/res/layout/history_header.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical" >
+
+    <TextView
+        android:id="@+id/signed_in_not_synced"
+        style="@style/PrivacyDisclaimerText" />
+
+   <TextView
+        android:id="@+id/signed_in_synced"
+        style="@style/PrivacyDisclaimerText" />
+
+   <TextView
+        android:id="@+id/other_forms_of_browsing_history"
+        style="@style/PrivacyDisclaimerText"  />
+
+    <Button
+        android:id="@+id/clear_browsing_data_button"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="16dp"
+        style="@style/ButtonCompatBorderless"
+        android:paddingTop="16dp"
+        android:paddingBottom="16dp"
+        android:paddingStart="16dp"
+        android:paddingEnd="16dp"
+        android:gravity="center_vertical|start"
+        android:text="@string/open_clear_browsing_data_dialog_button"
+        android:textAllCaps="true"
+        android:textColor="@color/light_active_color"
+        android:textSize="16sp" />
+</LinearLayout>
\ No newline at end of file
diff --git a/chrome/android/java/res/values-v17/styles.xml b/chrome/android/java/res/values-v17/styles.xml
index a7605df..4c19ba9 100644
--- a/chrome/android/java/res/values-v17/styles.xml
+++ b/chrome/android/java/res/values-v17/styles.xml
@@ -582,6 +582,15 @@
         <item name="android:textColor">@android:color/white</item>
         <item name="android:textSize">20sp</item>
     </style>
+    <style name="PrivacyDisclaimerText">
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:layout_marginTop">16dp</item>
+        <item name="android:paddingStart">16dp</item>
+        <item name="android:paddingEnd">16dp</item>
+        <item name="android:textSize">16sp</item>
+        <item name="android:visibility">gone</item>
+    </style>
 
     <!-- New tab page RecyclerView overscroll color -->
     <style name="NewTabPageRecyclerView">
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeApplication.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeApplication.java
index d28f6f49..ad559ad 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeApplication.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeApplication.java
@@ -60,6 +60,7 @@
 import org.chromium.chrome.browser.tabmodel.document.DocumentTabModelSelector;
 import org.chromium.chrome.browser.tabmodel.document.StorageDelegate;
 import org.chromium.chrome.browser.tabmodel.document.TabDelegate;
+import org.chromium.chrome.browser.webapps.GooglePlayWebApkInstallDelegate;
 import org.chromium.components.signin.AccountManagerDelegate;
 import org.chromium.components.signin.SystemAccountManagerDelegate;
 import org.chromium.content.app.ContentApplication;
@@ -391,8 +392,13 @@
         return null;
     }
 
+    /** Returns the singleton instance of GooglePlayWebApkInstallDelegate. */
+    public GooglePlayWebApkInstallDelegate getGooglePlayWebApkInstallDelegate() {
+        return null;
+    }
+
     /**
-     * Returns the Singleton instance of the DocumentTabModelSelector.
+     * Returns the singleton instance of the DocumentTabModelSelector.
      * TODO(dfalcantara): Find a better place for this once we differentiate between activity and
      *                    application-level TabModelSelectors.
      * @return The DocumentTabModelSelector for the application.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
index 853aabd..2a09616 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -369,7 +369,7 @@
             ChromePreferenceManager preferenceManager = ChromePreferenceManager.getInstance(this);
             // Promos can only be shown when we start with ACTION_MAIN intent and
             // after FRE is complete.
-            if (!mIntentWithEffect && FirstRunStatus.getFirstRunFlowComplete(this)) {
+            if (!mIntentWithEffect && FirstRunStatus.getFirstRunFlowComplete()) {
                 // Only show promos on the second oppurtunity. This is because we show FRE on the
                 // first oppurtunity, and we don't want to show such content back to back.
                 if (preferenceManager.getPromosSkippedOnFirstStart()) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/EmbedContentViewActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/EmbedContentViewActivity.java
index b6f5918..73601036 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/EmbedContentViewActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/EmbedContentViewActivity.java
@@ -86,7 +86,7 @@
     @Override
     public boolean onCreateOptionsMenu(Menu menu) {
         boolean retVal = super.onCreateOptionsMenu(menu);
-        if (!FirstRunStatus.getFirstRunFlowComplete(this)) return retVal;
+        if (!FirstRunStatus.getFirstRunFlowComplete()) return retVal;
         return true;
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillKeyboardAccessoryBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillKeyboardAccessoryBridge.java
index a01f2f7..a2109ba 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillKeyboardAccessoryBridge.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillKeyboardAccessoryBridge.java
@@ -144,13 +144,15 @@
      *                 empty too.
      * @param iconId The resource ID for the icon associated with the suggestion, or 0 for no icon.
      * @param suggestionId Identifier for the suggestion type.
+     * @param isDeletable Whether the item can be deleted by the user.
      */
     @CalledByNative
     private static void addToAutofillSuggestionArray(AutofillSuggestion[] array, int index,
-            String label, String sublabel, int iconId, int suggestionId, boolean deletable) {
+            String label, String sublabel, int iconId, int suggestionId, boolean isDeletable) {
         int drawableId = iconId == 0 ? DropdownItem.NO_ICON : ResourceId.mapToDrawableId(iconId);
-        array[index] =
-                new AutofillSuggestion(label, sublabel, drawableId, suggestionId, deletable, false);
+        array[index] = new AutofillSuggestion(label, sublabel, drawableId,
+                false /* isIconAtStart */, suggestionId, isDeletable, false /* isMultilineLabel */,
+                false /* isBoldLabel */);
     }
 
     private native void nativeViewDismissed(long nativeAutofillKeyboardAccessoryView);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillPopupBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillPopupBridge.java
index 8266579..b5adb643 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillPopupBridge.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillPopupBridge.java
@@ -92,10 +92,19 @@
     /**
      * Shows an Autofill popup with specified suggestions.
      * @param suggestions Autofill suggestions to be displayed.
+     * @param isRtl @code true if right-to-left text.
+     * @param backgroundColor popup background color, or {@code Color.TRANSPARENT} if not specified
+     * in experiment.
+     * @param dividerColor color for divider between popup items, or {@code Color.TRANSPARENT} if
+     * not specified in experiment.
+     * @param dropdownItemHeight height of each dropdown item in dimension independent pixel units,
+     * 0 if not specified in experiment.
      */
     @CalledByNative
-    private void show(AutofillSuggestion[] suggestions, boolean isRtl) {
-        if (mAutofillPopup != null) mAutofillPopup.filterAndShow(suggestions, isRtl);
+    private void show(AutofillSuggestion[] suggestions, boolean isRtl, int backgroundColor,
+            int dividerColor, int dropdownItemHeight) {
+        if (mAutofillPopup != null) mAutofillPopup.filterAndShow(suggestions, isRtl,
+                backgroundColor, dividerColor, dropdownItemHeight);
     }
 
     @CalledByNative
@@ -122,17 +131,20 @@
      * @param label First line of the suggestion.
      * @param sublabel Second line of the suggestion.
      * @param iconId The resource ID for the icon associated with the suggestion, or 0 for no icon.
+     * @param isIconAtStart {@code true} if {@param iconId} is displayed before {@param label}.
      * @param suggestionId Identifier for the suggestion type.
-     * @param deletable Whether this item is deletable.
+     * @param isDeletable Whether the item can be deleted by the user.
      * @param isLabelMultiline Whether the label should be should over multiple lines.
+     * @param isLabelBold true if {@param label} should be displayed in {@code Typeface.BOLD},
+     * false if {@param label} should be displayed in {@code Typeface.NORMAL}.
      */
     @CalledByNative
     private static void addToAutofillSuggestionArray(AutofillSuggestion[] array, int index,
-            String label, String sublabel, int iconId, int suggestionId, boolean deletable,
-            boolean isLabelMultiline) {
+            String label, String sublabel, int iconId, boolean isIconAtStart,
+            int suggestionId, boolean isDeletable, boolean isLabelMultiline, boolean isLabelBold) {
         int drawableId = iconId == 0 ? DropdownItem.NO_ICON : ResourceId.mapToDrawableId(iconId);
-        array[index] = new AutofillSuggestion(
-                label, sublabel, drawableId, suggestionId, deletable, isLabelMultiline);
+        array[index] = new AutofillSuggestion(label, sublabel, drawableId, isIconAtStart,
+                suggestionId, isDeletable, isLabelMultiline, isLabelBold);
     }
 
     private native void nativeSuggestionSelected(long nativeAutofillPopupViewAndroid,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadHistoryAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadHistoryAdapter.java
index 43f99ff..3dbf079 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadHistoryAdapter.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadHistoryAdapter.java
@@ -340,6 +340,7 @@
         mRegularDownloadItems.filter(mFilter, mFilteredItems);
         mIncognitoDownloadItems.filter(mFilter, mFilteredItems);
         mOfflinePageItems.filter(mFilter, mFilteredItems);
+        clear(false);
         loadItems(mFilteredItems);
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java
index 0f669c0..9b4b03b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java
@@ -260,7 +260,7 @@
         UmaUtils.recordForegroundStartTime();
         stopProgressionIfNotAcceptedTermsOfService();
         if (!mFreProperties.getBoolean(EXTRA_USE_FRE_FLOW_SEQUENCER)) {
-            if (FirstRunStatus.getFirstRunFlowComplete(this)) {
+            if (FirstRunStatus.getFirstRunFlowComplete()) {
                 // This is a parallel flow that needs to be refreshed/re-fired.
                 // Signal the FRE flow completion and re-launch the original intent.
                 completeFirstRunExperience();
@@ -403,7 +403,7 @@
         // If default is true then it corresponds to opt-out and false corresponds to opt-in.
         UmaUtils.recordMetricsReportingDefaultOptIn(!DEFAULT_METRICS_AND_CRASH_REPORTING);
         sGlue.acceptTermsOfService(allowCrashUpload);
-        FirstRunStatus.setSkipWelcomePage(FirstRunActivity.this, true);
+        FirstRunStatus.setSkipWelcomePage(true);
         flushPersistentData();
         stopProgressionIfNotAcceptedTermsOfService();
         jumpToPage(mPager.getCurrentItem() + 1);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java
index 452f352b..84a67b82 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java
@@ -86,7 +86,7 @@
 
     @VisibleForTesting
     protected boolean isFirstRunFlowComplete() {
-        return FirstRunStatus.getFirstRunFlowComplete(mActivity);
+        return FirstRunStatus.getFirstRunFlowComplete();
     }
 
     @VisibleForTesting
@@ -263,13 +263,13 @@
                 fromIntent != null && TextUtils.equals(fromIntent.getAction(), Intent.ACTION_MAIN);
         if (!fromChromeIcon && ToSAckedReceiver.checkAnyUserHasSeenToS(context)) return null;
 
-        final boolean baseFreComplete = FirstRunStatus.getFirstRunFlowComplete(context);
+        final boolean baseFreComplete = FirstRunStatus.getFirstRunFlowComplete();
         if (!baseFreComplete) {
             if (forLightweightFre
                     && CommandLine.getInstance().hasSwitch(
                                ChromeSwitches.ENABLE_LIGHTWEIGHT_FIRST_RUN_EXPERIENCE)) {
-                if (!FirstRunStatus.shouldSkipWelcomePage(context)
-                        && !FirstRunStatus.getLightweightFirstRunFlowComplete(context)) {
+                if (!FirstRunStatus.shouldSkipWelcomePage()
+                        && !FirstRunStatus.getLightweightFirstRunFlowComplete()) {
                     return createLightweightFirstRunIntent(context, fromChromeIcon);
                 }
             } else {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunSignInProcessor.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunSignInProcessor.java
index 47d230ac..b5237c5 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunSignInProcessor.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunSignInProcessor.java
@@ -58,7 +58,7 @@
         SigninManager signinManager = SigninManager.get(activity.getApplicationContext());
         signinManager.onFirstRunCheckDone();
 
-        boolean firstRunFlowComplete = FirstRunStatus.getFirstRunFlowComplete(activity);
+        boolean firstRunFlowComplete = FirstRunStatus.getFirstRunFlowComplete();
         // We skip signin and the FRE if
         // - FRE is disabled, or
         // - FRE hasn't been completed, but the user has already seen the ToS in the Setup Wizard.
@@ -129,7 +129,7 @@
         Log.e(TAG, "Attempt to pass-through without completed FRE");
 
         // Things went wrong -- we want the user to go through the full FRE.
-        FirstRunStatus.setFirstRunFlowComplete(activity, false);
+        FirstRunStatus.setFirstRunFlowComplete(false);
         setFirstRunFlowSignInComplete(activity, false);
         setFirstRunFlowSignInAccountName(activity, null);
         setFirstRunFlowSignInSetup(activity, false);
@@ -207,7 +207,7 @@
      * @param data Resulting FRE properties bundle
      */
     public static void finalizeFirstRunFlowState(Context context, Bundle data) {
-        FirstRunStatus.setFirstRunFlowComplete(context, true);
+        FirstRunStatus.setFirstRunFlowComplete(true);
         setFirstRunFlowSignInAccountName(context,
                     data.getString(FirstRunActivity.RESULT_SIGNIN_ACCOUNT_NAME));
         setFirstRunFlowSignInSetup(
@@ -221,7 +221,7 @@
     public static void updateSigninManagerFirstRunCheckDone(Context context) {
         SigninManager manager = SigninManager.get(context);
         if (manager.isSignInAllowed()) return;
-        if (!FirstRunStatus.getFirstRunFlowComplete(context)) return;
+        if (!FirstRunStatus.getFirstRunFlowComplete()) return;
         if (!getFirstRunFlowSignInComplete(context)) return;
         manager.onFirstRunCheckDone();
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunStatus.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunStatus.java
index e62fdea0..7558603 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunStatus.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunStatus.java
@@ -4,8 +4,6 @@
 
 package org.chromium.chrome.browser.firstrun;
 
-import android.content.Context;
-
 import org.chromium.base.ContextUtils;
 
 /**
@@ -21,10 +19,9 @@
 
     /**
      * Sets the "main First Run Experience flow complete" preference.
-     * @param context Any context
      * @param isComplete Whether the main First Run Experience flow is complete
      */
-    public static void setFirstRunFlowComplete(Context context, boolean isComplete) {
+    public static void setFirstRunFlowComplete(boolean isComplete) {
         ContextUtils.getAppSharedPreferences()
                 .edit()
                 .putBoolean(FIRST_RUN_FLOW_COMPLETE, isComplete)
@@ -35,35 +32,38 @@
      * Returns whether the main First Run Experience flow is complete.
      * Note: that might NOT include "intro"/"what's new" pages, but it always
      * includes ToS and Sign In pages if necessary.
-     * @param context Any context
      */
-    public static boolean getFirstRunFlowComplete(Context context) {
+    public static boolean getFirstRunFlowComplete() {
         return ContextUtils.getAppSharedPreferences()
                 .getBoolean(FIRST_RUN_FLOW_COMPLETE, false);
     }
 
+    // TODO(tedchoc): Remove once downstream callers migrate to non-param version.
+    public static boolean getFirstRunFlowComplete(
+            @SuppressWarnings("unused") android.content.Context context) {
+        return getFirstRunFlowComplete();
+    }
+
     /**
     * Sets the preference to skip the welcome page from the main First Run Experience.
-    * @param context Any context
-    * @param isSkip Whether the welcome page should be skpped
+     * @param isSkip Whether the welcome page should be skpped
     */
-    public static void setSkipWelcomePage(Context context, boolean isSkip) {
+    public static void setSkipWelcomePage(boolean isSkip) {
         ContextUtils.getAppSharedPreferences().edit().putBoolean(SKIP_WELCOME_PAGE, isSkip).apply();
     }
 
     /**
     * Checks whether the welcome page should be skipped from the main First Run Experience.
     */
-    public static boolean shouldSkipWelcomePage(Context context) {
+    public static boolean shouldSkipWelcomePage() {
         return ContextUtils.getAppSharedPreferences().getBoolean(SKIP_WELCOME_PAGE, false);
     }
 
     /**
      * Sets the "lightweight First Run Experience flow complete" preference.
-     * @param context Any context
      * @param isComplete Whether the lightweight First Run Experience flow is complete
      */
-    public static void setLightweightFirstRunFlowComplete(Context context, boolean isComplete) {
+    public static void setLightweightFirstRunFlowComplete(boolean isComplete) {
         ContextUtils.getAppSharedPreferences()
                 .edit()
                 .putBoolean(LIGHTWEIGHT_FIRST_RUN_FLOW_COMPLETE, isComplete)
@@ -72,9 +72,8 @@
 
     /**
      * Returns whether the "lightweight First Run Experience flow" is complete.
-     * @param context Any context
      */
-    public static boolean getLightweightFirstRunFlowComplete(Context context) {
+    public static boolean getLightweightFirstRunFlowComplete() {
         return ContextUtils.getAppSharedPreferences().getBoolean(
                 LIGHTWEIGHT_FIRST_RUN_FLOW_COMPLETE, false);
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/LightweightFirstRunActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/LightweightFirstRunActivity.java
index a0cba00a..9e03c148 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/LightweightFirstRunActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/LightweightFirstRunActivity.java
@@ -78,7 +78,7 @@
 
     @Override
     public void completeFirstRunExperience() {
-        FirstRunStatus.setLightweightFirstRunFlowComplete(LightweightFirstRunActivity.this, true);
+        FirstRunStatus.setLightweightFirstRunFlowComplete(true);
         Intent intent = new Intent();
         intent.putExtras(mFreProperties);
         finishAllTheActivities(getLocalClassName(), Activity.RESULT_OK, intent);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ToSAndUMAFirstRunFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ToSAndUMAFirstRunFragment.java
index 870b82b9..b44518a 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ToSAndUMAFirstRunFragment.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ToSAndUMAFirstRunFragment.java
@@ -104,6 +104,6 @@
 
     @Override
     public boolean shouldSkipPageOnCreate(Context appContext) {
-        return FirstRunStatus.shouldSkipWelcomePage(appContext);
+        return FirstRunStatus.shouldSkipWelcomePage();
     }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/history/BrowsingHistoryBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/history/BrowsingHistoryBridge.java
index 3bf3d55b..f044d02 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/history/BrowsingHistoryBridge.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/history/BrowsingHistoryBridge.java
@@ -30,6 +30,14 @@
          * via this method.
          */
         public void onHistoryDeleted();
+
+        /**
+         * Called after querying history to indicate whether other forms of browsing history were
+         * found.
+         * @param hasOtherForms Whether other forms of browsing history were found.
+         * @param hasSyncedResults Whether synced results were found.
+         */
+        public void hasOtherFormsOfBrowsingData(boolean hasOtherForms, boolean hasSyncedResults);
     }
 
     private final BrowsingHistoryObserver mObserver;
@@ -114,6 +122,11 @@
         mObserver.onHistoryDeleted();
     }
 
+    @CalledByNative
+    public void hasOtherFormsOfBrowsingData(boolean hasOtherForms, boolean hasSyncedResults) {
+        mObserver.hasOtherFormsOfBrowsingData(hasOtherForms, hasSyncedResults);
+    }
+
     private native long nativeInit(Profile profile);
     private native void nativeDestroy(long nativeBrowsingHistoryBridge);
     private native void nativeQueryHistory(long nativeBrowsingHistoryBridge,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryAdapter.java
index 5ad87ce..6d53e979 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryAdapter.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryAdapter.java
@@ -5,28 +5,48 @@
 package org.chromium.chrome.browser.history;
 
 import android.support.v7.widget.RecyclerView.ViewHolder;
+import android.text.SpannableString;
+import android.text.method.LinkMovementMethod;
 import android.view.LayoutInflater;
 import android.view.View;
+import android.view.View.OnClickListener;
 import android.view.ViewGroup;
+import android.widget.TextView;
 
+import org.chromium.base.ContextUtils;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.history.BrowsingHistoryBridge.BrowsingHistoryObserver;
 import org.chromium.chrome.browser.widget.DateDividedAdapter;
 import org.chromium.chrome.browser.widget.selection.SelectableItemViewHolder;
 import org.chromium.chrome.browser.widget.selection.SelectionDelegate;
+import org.chromium.components.signin.ChromeSigninController;
+import org.chromium.ui.text.NoUnderlineClickableSpan;
+import org.chromium.ui.text.SpanApplier;
 
 import java.util.List;
+import java.util.Locale;
 
 /**
  * Bridges the user's browsing history and the UI used to display it.
  */
 public class HistoryAdapter extends DateDividedAdapter implements BrowsingHistoryObserver {
     private static final String EMPTY_QUERY = "";
+    private static final String LEARN_MORE_LINK =
+            "https://support.google.com/chrome/?p=sync_history&amp;hl="
+                    + Locale.getDefault().toString();
+    private static final String GOOGLE_HISTORY_LINK = "history.google.com";
 
     private final SelectionDelegate<HistoryItem> mSelectionDelegate;
     private final BrowsingHistoryBridge mBridge;
     private final HistoryManager mManager;
 
+    private TextView mSignedInNotSyncedTextView;
+    private TextView mSignedInSyncedTextView;
+    private TextView mOtherFormsOfBrowsingHistoryTextView;
+
+    private boolean mHasOtherFormsOfBrowsingData;
+    private boolean mHasSyncedData;
+    private boolean mHeaderInflated;
     private boolean mDestroyed;
 
     public HistoryAdapter(SelectionDelegate<HistoryItem> delegate, HistoryManager manager) {
@@ -101,7 +121,11 @@
         // destroyed to avoid unnecessary work.
         if (mDestroyed) return;
 
-        loadItems(items);
+        clear(true);
+        if (items.size() > 0) {
+            addHeader();
+            loadItems(items);
+        }
     }
 
     @Override
@@ -111,4 +135,69 @@
         //                    This currently removes all items and re-issues a query.
         initialize();
     }
+
+    @Override
+    public void hasOtherFormsOfBrowsingData(boolean hasOtherForms, boolean hasSyncedResults) {
+        mHasOtherFormsOfBrowsingData = hasOtherForms;
+        mHasSyncedData = hasSyncedResults;
+        setPrivacyDisclaimerVisibility();
+    }
+
+    @Override
+    protected HeaderViewHolder createHeader(ViewGroup parent) {
+        ViewGroup v = (ViewGroup) LayoutInflater.from(parent.getContext()).inflate(
+                R.layout.history_header, parent, false);
+        mHeaderInflated = true;
+
+        View cbdButton = v.findViewById(R.id.clear_browsing_data_button);
+        cbdButton.setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                mManager.openClearBrowsingDataPreference();
+            }
+        });
+
+        mSignedInNotSyncedTextView = (TextView) v.findViewById(R.id.signed_in_not_synced);
+        setPrivacyDisclaimerText(mSignedInNotSyncedTextView,
+                R.string.android_history_no_synced_results, LEARN_MORE_LINK);
+
+        mSignedInSyncedTextView = (TextView) v.findViewById(R.id.signed_in_synced);
+        setPrivacyDisclaimerText(mSignedInSyncedTextView,
+                R.string.android_history_has_synced_results, LEARN_MORE_LINK);
+
+        mOtherFormsOfBrowsingHistoryTextView = (TextView) v.findViewById(
+                R.id.other_forms_of_browsing_history);
+        setPrivacyDisclaimerText(mOtherFormsOfBrowsingHistoryTextView,
+                R.string.android_history_other_forms_of_history, GOOGLE_HISTORY_LINK);
+
+        setPrivacyDisclaimerVisibility();
+
+        return new HeaderViewHolder(v);
+    }
+
+    private void setPrivacyDisclaimerText(TextView view, int stringId, final  String url) {
+        NoUnderlineClickableSpan link = new NoUnderlineClickableSpan() {
+            @Override
+            public void onClick(View view) {
+                mManager.openUrl(url, null, true);
+            }
+        };
+        SpannableString spannable = SpanApplier.applySpans(
+                view.getResources().getString(stringId),
+                new SpanApplier.SpanInfo("<link>", "</link>", link));
+        view.setText(spannable);
+        view.setMovementMethod(LinkMovementMethod.getInstance());
+    }
+
+    private void setPrivacyDisclaimerVisibility() {
+        if (!mHeaderInflated) return;
+
+        boolean isSignedIn =
+                ChromeSigninController.get(ContextUtils.getApplicationContext()).isSignedIn();
+        mSignedInNotSyncedTextView.setVisibility(
+                !mHasSyncedData && isSignedIn ? View.VISIBLE : View.GONE);
+        mSignedInSyncedTextView.setVisibility(mHasSyncedData ? View.VISIBLE : View.GONE);
+        mOtherFormsOfBrowsingHistoryTextView.setVisibility(
+                mHasOtherFormsOfBrowsingData ? View.VISIBLE : View.GONE);
+    }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryItem.java b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryItem.java
index 8649a27..55263e1e 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryItem.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryItem.java
@@ -85,7 +85,7 @@
      * Navigates a tab to this item's URL.
      */
     public void open() {
-        if (mManager != null) mManager.openItem(mUrl, null, false);
+        if (mManager != null) mManager.openUrl(mUrl, null, false);
     }
 
     /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManager.java b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManager.java
index f2738ad..8a662f0 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManager.java
@@ -17,6 +17,8 @@
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.IntentHandler;
 import org.chromium.chrome.browser.document.ChromeLauncherActivity;
+import org.chromium.chrome.browser.preferences.PreferencesLauncher;
+import org.chromium.chrome.browser.preferences.privacy.ClearBrowsingDataPreferences;
 import org.chromium.chrome.browser.util.IntentUtils;
 import org.chromium.chrome.browser.widget.TintedDrawable;
 import org.chromium.chrome.browser.widget.selection.SelectableListLayout;
@@ -114,14 +116,14 @@
     }
 
     /**
-     * Open the history item.
-     * @param url The URL of the history item.
-     * @param isIncognito Whether to open the history item in an incognito tab. If null, the tab
+     * Open the provided url.
+     * @param url The url to open.
+     * @param isIncognito Whether to open the url in an incognito tab. If null, the tab
      *                    will open in the current tab model.
      * @param createNewTab Whether a new tab should be created. If false, the item will clobber the
      *                     the current tab.
      */
-    public void openItem(String url, Boolean isIncognito, boolean createNewTab) {
+    public void openUrl(String url, Boolean isIncognito, boolean createNewTab) {
         // Construct basic intent.
         Intent viewIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
         viewIntent.putExtra(Browser.EXTRA_APPLICATION_ID,
@@ -151,9 +153,18 @@
         IntentHandler.startActivityForTrustedIntent(viewIntent, mActivity);
     }
 
+    /**
+     * Opens the clear browsing data preference.
+     */
+    public void openClearBrowsingDataPreference() {
+        Intent intent = PreferencesLauncher.createIntentForSettingsPage(mActivity,
+                ClearBrowsingDataPreferences.class.getName());
+        IntentUtils.safeStartActivity(mActivity, intent);
+    }
+
     private void openItemsInNewTabs(List<HistoryItem> items, boolean isIncognito) {
         for (HistoryItem item : items) {
-            openItem(item.getUrl(), isIncognito, true);
+            openUrl(item.getUrl(), isIncognito, true);
         }
     }
 }
\ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java
index 450ca24..461fd50 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java
@@ -68,7 +68,7 @@
     private final Intent mEnterVRIntent;
 
     private boolean mVrAvailable;
-    private boolean mDaydreamReadyDevice;
+    private boolean mCardboardSupportOnly;
     private Boolean mVrShellEnabled;
 
     private VrClassesBuilder mVrClassesBuilder;
@@ -90,30 +90,42 @@
     public VrShellDelegate(ChromeTabbedActivity activity) {
         mActivity = activity;
 
-        mVrAvailable = createVrClassesBuilder() && isVrCoreCompatible() && createVrDaydreamApi()
-                && mVrDaydreamApi.isDaydreamReadyDevice();
-        if (mVrAvailable) {
-            mEnterVRIntent = mVrDaydreamApi.createVrIntent(
-                    new ComponentName(mActivity, VR_ACTIVITY_ALIAS));
+        // TODO(bshe): refactor code so that mCardboardSupportOnly does not depend on mVrAvailable
+        // and mVrAvailable does not depend on createVrDaydreamApi.
+        mVrAvailable = createVrClassesBuilder() && isVrCoreCompatible() && createVrDaydreamApi();
+        // Make sure mVrDaydreamApi is created as createVrDaydreamApi might not get called above.
+        if (mVrDaydreamApi == null) createVrDaydreamApi();
+        // Only Cardboard mode is supported on non-daydream devices.
+        mCardboardSupportOnly = !mVrDaydreamApi.isDaydreamReadyDevice();
+
+        if (mVrAvailable && !mCardboardSupportOnly) {
+            mEnterVRIntent =
+                    mVrDaydreamApi.createVrIntent(new ComponentName(mActivity, VR_ACTIVITY_ALIAS));
         } else {
             mEnterVRIntent = null;
         }
-        mTabObserver = new EmptyTabObserver() {
-            @Override
-            public void onContentChanged(Tab tab) {
-                if (tab.getNativePage() != null || tab.isShowingSadTab()) {
-                    // For now we don't handle native pages. crbug.com/661609
-                    shutdownVR(false, true);
+        if (mVrAvailable) {
+            mTabObserver = new EmptyTabObserver() {
+                @Override
+                public void onContentChanged(Tab tab) {
+                    if (tab.getNativePage() != null || tab.isShowingSadTab()) {
+                        // For now we don't handle native pages. crbug.com/661609.
+                        shutdownVR(false, !mCardboardSupportOnly /* showTransition */);
+                    }
                 }
-            }
 
-            @Override
-            public void onWebContentsSwapped(Tab tab, boolean didStartLoad, boolean didFinishLoad) {
-                // TODO(mthiesse): Update the native WebContents pointer and compositor. This
-                // doesn't seem to get triggered in VR Shell currently, but that's likely to change
-                // when we have omnibar navigation.
-            }
-        };
+                @Override
+                public void onWebContentsSwapped(
+                        Tab tab, boolean didStartLoad, boolean didFinishLoad) {
+                    // TODO(mthiesse): Update the native WebContents pointer and compositor. This
+                    // doesn't seem to get triggered in VR Shell currently, but that's likely to
+                    // change
+                    // when we have omnibar navigation.
+                }
+            };
+        } else {
+            mTabObserver = null;
+        }
     }
 
     /**
@@ -149,7 +161,8 @@
      * Handle a VR intent, entering VR in the process unless we're unable to.
      */
     public void enterVRFromIntent(Intent intent) {
-        if (!mVrAvailable) return;
+        // Vr Intent is only used on Daydream devices.
+        if (!mVrAvailable || mCardboardSupportOnly) return;
         assert isVrIntent(intent);
         if (mListeningForWebVrActivateBeforePause && !mRequestedWebVR) {
             nativeDisplayActivate(mNativeVrShellDelegate);
@@ -269,7 +282,7 @@
         if (mInVr) return ENTER_VR_NOT_NECESSARY;
         if (!canEnterVR(mActivity.getActivityTab())) return ENTER_VR_CANCELLED;
 
-        if (!mVrDaydreamApi.isDaydreamCurrentViewer()) {
+        if (mCardboardSupportOnly || !mVrDaydreamApi.isDaydreamCurrentViewer()) {
             // Avoid using launchInVr which would trigger DON flow regardless current viewer type
             // due to the lack of support for unexported activities.
             return enterVR() ? ENTER_VR_SUCCEEDED : ENTER_VR_CANCELLED;
@@ -283,10 +296,16 @@
     private boolean exitWebVR() {
         if (!mInVr) return false;
         mVrShell.setWebVrModeEnabledOnUI(false);
-        // TODO(bajones): Once VR Shell can be invoked outside of WebVR this
-        // should no longer exit the shell outright. Need a way to determine
-        // how VrShell was created.
-        shutdownVR(false, !isVrShellEnabled());
+        if (mCardboardSupportOnly) {
+            // Transition screen is not available for Cardboard only (non-Daydream) devices.
+            // TODO(bshe): Fix this once b/33490788 is fixed.
+            shutdownVR(false, false);
+        } else {
+            // TODO(bajones): Once VR Shell can be invoked outside of WebVR this
+            // should no longer exit the shell outright. Need a way to determine
+            // how VrShell was created.
+            shutdownVR(false, !isVrShellEnabled());
+        }
         return true;
     }
 
@@ -300,7 +319,8 @@
      */
     public void maybeResumeVR() {
         if (!mVrAvailable) return;
-        if (isVrShellEnabled() || mListeningForWebVrActivateBeforePause) {
+        if ((isVrShellEnabled() || mListeningForWebVrActivateBeforePause)
+                && !mCardboardSupportOnly) {
             registerDaydreamIntent();
         }
         // If this is still set, it means the user backed out of the DON flow, and we won't be
@@ -334,7 +354,7 @@
             } finally {
                 StrictMode.setThreadPolicy(oldPolicy);
             }
-        } else if (mVrDaydreamApi.isDaydreamCurrentViewer()
+        } else if (!mCardboardSupportOnly && mVrDaydreamApi.isDaydreamCurrentViewer()
                 && mLastVRExit + REENTER_VR_TIMEOUT_MS > SystemClock.uptimeMillis()) {
             enterVRIfNecessary();
         }
@@ -345,16 +365,19 @@
      */
     public void maybePauseVR() {
         if (!mVrAvailable) return;
-        unregisterDaydreamIntent();
 
-        // When the active web page has a vrdisplayactivate event handler,
-        // mListeningForWebVrActivate should be set to true, which means a vrdisplayactive event
-        // should be fired once DON flow finished. However, DON flow will pause our activity, which
-        // makes the active page becomes invisible. And the event fires before the active page
-        // becomes visible again after DON finished. So here we remember the value of
-        // mListeningForWebVrActivity before pause and use this value to decide if vrdisplayactivate
-        // event should be dispatched in enterVRFromIntent.
-        mListeningForWebVrActivateBeforePause = mListeningForWebVrActivate;
+        if (!mCardboardSupportOnly) {
+            unregisterDaydreamIntent();
+
+            // When the active web page has a vrdisplayactivate event handler,
+            // mListeningForWebVrActivate should be set to true, which means a vrdisplayactive event
+            // should be fired once DON flow finished. However, DON flow will pause our activity,
+            // which makes the active page becomes invisible. And the event fires before the active
+            // page becomes visible again after DON finished. So here we remember the value of
+            // mListeningForWebVrActivity before pause and use this value to decide if
+            // vrdisplayactivate event should be dispatched in enterVRFromIntent.
+            mListeningForWebVrActivateBeforePause = mListeningForWebVrActivate;
+        }
         if (mNonPresentingGvrContext != null) {
             mNonPresentingGvrContext.pause();
         }
@@ -422,7 +445,9 @@
 
     @CalledByNative
     private void setListeningForWebVrActivate(boolean listening) {
-        if (!mVrAvailable) return;
+        // Non-Daydream devices may not have the concept of display activate. So disable
+        // mListeningForWebVrActivate for them.
+        if (!mVrAvailable || mCardboardSupportOnly) return;
         mListeningForWebVrActivate = listening;
         if (listening) {
             registerDaydreamIntent();
@@ -548,10 +573,13 @@
      * @return Whether or not VR Shell is currently enabled.
      */
     public boolean isVrShellEnabled() {
+        // Disable VR Shell for Cardboard only (non-Daydream) devices.
+        // TODO(amp|bshe): Investigate if removing LibraryLoader.isInitialized from the check is
+        // possible.
+        if (!mVrAvailable || mCardboardSupportOnly || !LibraryLoader.isInitialized()) {
+            return false;
+        }
         if (mVrShellEnabled == null) {
-            if (!LibraryLoader.isInitialized()) {
-                return false;
-            }
             mVrShellEnabled = ChromeFeatureList.isEnabled(ChromeFeatureList.VR_SHELL);
         }
         return mVrShellEnabled;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/ChromeWebApkHost.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/ChromeWebApkHost.java
index 1cba919..e315d325 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/ChromeWebApkHost.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/ChromeWebApkHost.java
@@ -10,6 +10,7 @@
 import android.os.StrictMode;
 import android.provider.Settings;
 import android.support.v7.app.AlertDialog;
+import android.text.TextUtils;
 
 import org.chromium.base.CommandLine;
 import org.chromium.base.ContextUtils;
@@ -20,12 +21,16 @@
 import org.chromium.chrome.browser.ChromeSwitches;
 import org.chromium.chrome.browser.ChromeVersionInfo;
 import org.chromium.chrome.browser.preferences.ChromePreferenceManager;
+import org.chromium.components.variations.VariationsAssociatedData;
 import org.chromium.webapk.lib.client.WebApkValidator;
 
 /**
  * Contains functionality needed for Chrome to host WebAPKs.
  */
 public class ChromeWebApkHost {
+    /** Flag to enable installing WebAPKs using Google Play. */
+    private static final String PLAY_INSTALL = "play_install";
+
     private static final String TAG = "ChromeWebApkHost";
 
     private static Boolean sEnabledForTesting;
@@ -44,15 +49,21 @@
         return isEnabledInPrefs();
     }
 
+    /** Return whether installing WebAPKs using Google Play is enabled. */
+    public static boolean canUseGooglePlayToInstallWebApk() {
+        if (!isEnabled()) return false;
+        return TextUtils.equals(VariationsAssociatedData.getVariationParamValue(
+                ChromeFeatureList.WEBAPKS, PLAY_INSTALL), "true");
+    }
+
     @CalledByNative
     private static boolean areWebApkEnabled() {
         return ChromeWebApkHost.isEnabled();
     }
 
     /**
-     * Check the cached value to figure out if the feature is enabled. We have
-     * to use the cached value because native library may not yet been loaded.
-     *
+     * Check the cached value to figure out if the feature is enabled. We have to use the cached
+     * value because native library may not yet been loaded.
      * @return Whether the feature is enabled.
      */
     private static boolean isEnabledInPrefs() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/GooglePlayWebApkInstallDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/GooglePlayWebApkInstallDelegate.java
new file mode 100644
index 0000000..5bcfc29
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/GooglePlayWebApkInstallDelegate.java
@@ -0,0 +1,54 @@
+// 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.
+
+package org.chromium.chrome.browser.webapps;
+
+import android.support.annotation.IntDef;
+
+import org.chromium.base.Callback;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Defines an interface for installing WebAPKs via Google Play.
+ */
+public interface GooglePlayWebApkInstallDelegate {
+    /**
+     * The app state transitions provided by Google Play during download and installation process.
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({INVALID, DOWNLOAD_PENDING, DOWNLOADING, DOWNLOAD_CANCELLED, DOWNLOAD_ERROR,
+             INSTALLING, INSTALL_ERROR, INSTALLED})
+    public @interface InstallerPackageEvent {}
+    public static final int INVALID = -1;
+    public static final int DOWNLOAD_PENDING = 0;
+    public static final int DOWNLOADING = 1;
+    public static final int DOWNLOAD_CANCELLED = 2;
+    public static final int DOWNLOAD_ERROR = 3;
+    public static final int INSTALLING = 4;
+    public static final int INSTALL_ERROR = 5;
+    public static final int INSTALLED = 6;
+
+    /**
+     * Uses Google Play to install WebAPK asynchronously.
+     * @param packageName The package name of WebAPK to install.
+     * @param version The version of WebAPK to install.
+     * @param title The title of the WebAPK to display during installation.
+     * @param token The token from WebAPK Minter Server.
+     * @param url The start URL of the WebAPK to install.
+     * @param callback The callback to invoke when the install is either completed or failed.
+     * @return True if the install was started. A "true" value does not guarantee that the install
+     *         succeeds.
+     */
+    boolean installAsync(String packageName, int version, String title, String token,
+            String url, Callback<Boolean> callback);
+
+    /**
+     * Calls the callback once the installation either succeeded or failed.
+     * @param packageName The package name of WebAPK for the installation.
+     * @param event The result of the install.
+     */
+    void onGotInstallEvent(String packageName, @InstallerPackageEvent int event);
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInstaller.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInstaller.java
index 2b3a2c9..149a3e2c 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInstaller.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInstaller.java
@@ -13,9 +13,11 @@
 
 import org.chromium.base.ApplicationState;
 import org.chromium.base.ApplicationStatus;
+import org.chromium.base.Callback;
 import org.chromium.base.ContentUriUtils;
 import org.chromium.base.ContextUtils;
 import org.chromium.base.annotations.CalledByNative;
+import org.chromium.chrome.browser.ChromeApplication;
 import org.chromium.chrome.browser.ShortcutHelper;
 import org.chromium.chrome.browser.banners.InstallerDelegate;
 import org.chromium.chrome.browser.util.IntentUtils;
@@ -45,8 +47,13 @@
     /** Weak pointer to the native WebApkInstaller. */
     private long mNativePointer;
 
+    /** Talks to Google Play to install WebAPKs. */
+    private GooglePlayWebApkInstallDelegate mGooglePlayWebApkInstallDelegate;
+
     private WebApkInstaller(long nativePtr) {
         mNativePointer = nativePtr;
+        ChromeApplication application = (ChromeApplication) ContextUtils.getApplicationContext();
+        mGooglePlayWebApkInstallDelegate = application.getGooglePlayWebApkInstallDelegate();
     }
 
     @CalledByNative
@@ -55,8 +62,16 @@
     }
 
     @CalledByNative
+    private boolean hasGooglePlayWebApkInstallDelegate() {
+        return mGooglePlayWebApkInstallDelegate != null;
+    }
+
+    @CalledByNative
     private void destroy() {
-        ApplicationStatus.unregisterApplicationStateListener(mListener);
+        if (mListener != null) {
+            ApplicationStatus.unregisterApplicationStateListener(mListener);
+        }
+        mListener = null;
         mNativePointer = 0;
     }
 
@@ -86,7 +101,67 @@
     }
 
     /**
-     * Send intent to Android to show prompt and install downloaded WebAPK.
+     * Installs a WebAPK from Google Play and monitors the installation.
+     * @param packageName The package name of the WebAPK to install.
+     * @param version The version of WebAPK to install.
+     * @param title The title of the WebAPK to display during installation.
+     * @param token The token from WebAPK Server.
+     * @param url The start URL of the WebAPK to install.
+     * @return True if the install was started. A "true" return value does not guarantee that the
+     *         install succeeds.
+     */
+    @CalledByNative
+    private boolean installWebApkFromGooglePlayAsync(String packageName, int version, String title,
+            String token, String url) {
+        if (mGooglePlayWebApkInstallDelegate == null) return false;
+
+        Callback<Boolean> callback = new Callback<Boolean>() {
+            @Override
+            public void onResult(Boolean success) {
+                if (mNativePointer != 0) {
+                    nativeOnInstallFinished(mNativePointer, success);
+                }
+            }
+        };
+        return mGooglePlayWebApkInstallDelegate.installAsync(packageName, version, title, token,
+                url, callback);
+    }
+
+    /**
+     * Updates a WebAPK.
+     * @param filePath File to update.
+     * @return True if the update was started. A "true" return value does not guarantee that the
+     *         update succeeds.
+     */
+    @CalledByNative
+    private boolean updateAsyncFromNative(String filePath) {
+        mIsInstall = false;
+        return installDownloadedWebApk(filePath);
+    }
+
+    /**
+     * Updates a WebAPK using Google Play.
+     * @param packageName The package name of the WebAPK to install.
+     * @param version The version of WebAPK to install.
+     * @param title The title of the WebAPK to display during installation.
+     * @param token The token from WebAPK Server.
+     * @param url The start URL of the WebAPK to install.
+     * @return True if the update was started. A "true" return value does not guarantee that the
+     *         update succeeds.
+     */
+    @CalledByNative
+    private boolean updateAsyncFromGooglePlay(String packageName, int version, String title,
+            String token, String url) {
+        if (mGooglePlayWebApkInstallDelegate == null) return false;
+
+        // TODO(hanxi):crbug.com/634499. Adds a callback to show an infobar after the update
+        // succeeded.
+        return mGooglePlayWebApkInstallDelegate.installAsync(packageName, version, title, token,
+                url, null);
+    }
+
+    /**
+     * Sends intent to Android to show prompt and install downloaded WebAPK.
      * @param filePath File to install.
      */
     private boolean installDownloadedWebApk(String filePath) {
@@ -132,18 +207,6 @@
         }
     }
 
-    /**
-     * Updates a WebAPK.
-     * @param filePath File to update.
-     * @return True if the update was started. A "true" return value does not guarantee that the
-     *         update succeeds.
-     */
-    @CalledByNative
-    private boolean updateAsyncFromNative(String filePath) {
-        mIsInstall = false;
-        return installDownloadedWebApk(filePath);
-    }
-
     private ApplicationStatus.ApplicationStateListener createApplicationStateListener() {
         return new ApplicationStatus.ApplicationStateListener() {
             @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/DateDividedAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/DateDividedAdapter.java
index 003498df..82b34141 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/widget/DateDividedAdapter.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/DateDividedAdapter.java
@@ -105,6 +105,12 @@
         }
     }
 
+    protected static class HeaderViewHolder extends RecyclerView.ViewHolder {
+        public HeaderViewHolder(View itemView) {
+            super(itemView);
+        }
+    }
+
     /**
      * A bucket of items with the same date.
      */
@@ -116,16 +122,16 @@
         private int mIndex;
 
         private boolean mIsSorted;
+        private boolean mIsListHeader;
 
-        public ItemGroup(TimedItem item) {
-            mDate = new Date(item.getTimestamp());
-            mItems.add(item);
+        public ItemGroup(long timestamp) {
+            mDate = new Date(timestamp);
             mIsSorted = true;
         }
 
         public void addItem(TimedItem item) {
             mItems.add(item);
-            mIsSorted = false;
+            mIsSorted = mItems.size() == 1;
         }
 
         public void removeItem(TimedItem item) {
@@ -161,13 +167,15 @@
          * @return The size of this group.
          */
         public int size() {
+            if (mIsListHeader) return 1;
+
             // Plus 1 to account for the date header.
             return mItems.size() + 1;
         }
 
         public TimedItem getItemAt(int index) {
-            // 0 is allocated to the date header.
-            if (index == 0) return null;
+            // 0 is allocated to the date header. The list header has no items.
+            if (index == 0 || mIsListHeader) return null;
 
             sortIfNeeded();
             return mItems.get(index - 1);
@@ -203,10 +211,12 @@
     private static final AsyncTask<Void, Void, Calendar> sCal1 = createCalendar();
     private static final AsyncTask<Void, Void, Calendar> sCal2 = createCalendar();
 
+    public static final int TYPE_HEADER = -1;
     public static final int TYPE_DATE = 0;
     public static final int TYPE_NORMAL = 1;
 
     private int mSize;
+    private boolean mHasListHeader;
     private SortedSet<ItemGroup> mGroups = new TreeSet<>(new Comparator<ItemGroup>() {
         @Override
         public int compare(ItemGroup lhs, ItemGroup rhs) {
@@ -221,6 +231,14 @@
     protected abstract ViewHolder createViewHolder(ViewGroup parent);
 
     /**
+     * Creates a {@link HeaderViewHolder} in the given parent.
+     * @see #onCreateViewHolder(ViewGroup, int)
+     */
+    protected HeaderViewHolder createHeader(ViewGroup parent) {
+        return null;
+    }
+
+    /**
      * Binds the {@link ViewHolder} with the given {@link TimedItem}.
      * @see #onBindViewHolder(ViewHolder, int)
      */
@@ -233,15 +251,10 @@
     protected abstract int getTimedItemViewResId();
 
     /**
-     * Loads a list of {@link TimedItem}s to this adapter. Any previous data will be removed.
+     * Loads a list of {@link TimedItem}s to this adapter. Previous data will not be removed. Call
+     * {@link #clear(boolean)} to remove previous items.
      */
     public void loadItems(List<? extends TimedItem> timedItems) {
-        mSize = 0;
-
-        // Unset the positions of all items in the list.
-        for (ItemGroup group : mGroups) group.resetPosition();
-        mGroups.clear();
-
         for (TimedItem timedItem : timedItems) {
             Date date = new Date(timedItem.getTimestamp());
             boolean found = false;
@@ -256,7 +269,9 @@
             if (!found) {
                 // Create a new ItemGroup with the date for the new item. This increases the
                 // size by two because we add new views for the date and the item itself.
-                mGroups.add(new ItemGroup(timedItem));
+                ItemGroup newGroup = new ItemGroup(timedItem.getTimestamp());
+                newGroup.addItem(timedItem);
+                mGroups.add(newGroup);
                 mSize += 2;
             }
         }
@@ -272,12 +287,32 @@
     }
 
     /**
-     * Removes all items from this adapter.
+     * Adds a header as the first group in this adapter.
      */
-    public void clear() {
+    public void addHeader() {
+        assert mSize == 0;
+
+        ItemGroup header = new ItemGroup(Long.MAX_VALUE);
+        header.mIsListHeader = true;
+
+        mGroups.add(header);
+        mSize++;
+        mHasListHeader = true;
+    }
+
+    /**
+     * Removes all items from this adapter.
+     * @param notifyDataSetChanged Whether to notify that the data set has been changed.
+     */
+    public void clear(boolean notifyDataSetChanged) {
         mSize = 0;
+        mHasListHeader = false;
+
+        // Unset the positions of all items in the list.
+        for (ItemGroup group : mGroups) group.resetPosition();
         mGroups.clear();
-        notifyDataSetChanged();
+
+        if (notifyDataSetChanged) notifyDataSetChanged();
     }
 
     @Override
@@ -289,8 +324,8 @@
     }
 
     /**
-     * Gets the item at the given position. For date headers, {@link TimedItem} will be null; for
-     * normal items, {@link Date} will be null.
+     * Gets the item at the given position. For date headers and the list header, {@link TimedItem}
+     * will be null; for normal items, {@link Date} will be null.
      */
     public Pair<Date, TimedItem> getItemAt(int position) {
         Pair<ItemGroup, Integer> pair = getGroupAt(position);
@@ -301,7 +336,13 @@
     @Override
     public final int getItemViewType(int position) {
         Pair<ItemGroup, Integer> pair = getGroupAt(position);
-        return pair.second == 0 ? TYPE_DATE : TYPE_NORMAL;
+        if (pair.second == TYPE_HEADER) {
+            return TYPE_HEADER;
+        } else if (pair.second == 0) {
+            return TYPE_DATE;
+        } else {
+            return TYPE_NORMAL;
+        }
     }
 
     @Override
@@ -311,7 +352,10 @@
                     getTimedItemViewResId(), parent, false));
         } else if (viewType == TYPE_NORMAL) {
             return createViewHolder(parent);
+        } else if (viewType == TYPE_HEADER) {
+            return createHeader(parent);
         }
+        assert false;
         return null;
     }
 
@@ -320,7 +364,7 @@
         Pair<Date, TimedItem> pair = getItemAt(position);
         if (holder instanceof DateViewHolder) {
             ((DateViewHolder) holder).setDate(pair.first);
-        } else {
+        } else if (!(holder instanceof HeaderViewHolder)) {
             bindViewHolderForTimedItem(holder, pair.second);
         }
     }
@@ -335,6 +379,10 @@
      */
     protected Pair<ItemGroup, Integer> getGroupAt(int position) {
         // TODO(ianwen): Optimize the performance if the number of groups becomes too large.
+        if (mHasListHeader && position == 0) {
+            return new Pair<>(mGroups.first(), TYPE_HEADER);
+        }
+
         int i = position;
         for (ItemGroup group : mGroups) {
             if (i >= group.size()) {
diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd
index 381b9a8..0a89154 100644
--- a/chrome/android/java/strings/android_chrome_strings.grd
+++ b/chrome/android/java/strings/android_chrome_strings.grd
@@ -537,6 +537,18 @@
       <message name="IDS_CLEAR_BROWSING_DATA_IMPORTANT_DIALOG_BUTTON" desc="The text of the button to perform the clear action in the dialog presenting the user with 'important' sites that they can exclude from clearing.">
         Clear
       </message>
+      <message name="IDS_OPEN_CLEAR_BROWSING_DATA_DIALOG_BUTTON" desc="Title of the button that will open the clear browsing data dialog.">
+        Clear browsing data…
+      </message>
+      <message name="IDS_ANDROID_HISTORY_NO_SYNCED_RESULTS" desc="The notification at the top of the history page indicating that it does not include visits from other devices.">
+        Showing history from this device. <ph name="BEGIN_LINK">&lt;link&gt;</ph>Learn more<ph name="END_LINK">&lt;/link&gt;</ph>.
+      </message>
+      <message name="IDS_ANDROID_HISTORY_HAS_SYNCED_RESULTS" desc="The notification at the top of the history page indicating that it is showing visits synced from other devices.">
+        Showing history from your signed-in devices. <ph name="BEGIN_LINK">&lt;link&gt;</ph>Learn more<ph name="END_LINK">&lt;/link&gt;</ph>.
+      </message>
+      <message name="IDS_ANDROID_HISTORY_OTHER_FORMS_OF_HISTORY" desc="The notification at the top of the history page indicating that deleting Chrome browsing history will not delete other forms of history stored at Google My Activity.">
+        Your Google Account may have other forms of browsing history at <ph name="BEGIN_LINK">&lt;link&gt;</ph>history.google.com<ph name="END_LINK">&lt;/link&gt;</ph>.
+      </message>
 
       <message name="IDS_USAGE_AND_CRASH_REPORTS_TITLE" desc="Title for 'Usage and crash reports' preference">
         Usage and crash reports
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni
index 6ee404fe..c132208c 100644
--- a/chrome/android/java_sources.gni
+++ b/chrome/android/java_sources.gni
@@ -1031,6 +1031,7 @@
   "java/src/org/chromium/chrome/browser/webapps/ChromeWebApkHost.java",
   "java/src/org/chromium/chrome/browser/webapps/FullScreenActivity.java",
   "java/src/org/chromium/chrome/browser/webapps/FullScreenDelegateFactory.java",
+  "java/src/org/chromium/chrome/browser/webapps/GooglePlayWebApkInstallDelegate.java",
   "java/src/org/chromium/chrome/browser/webapps/WebApkActivity.java",
   "java/src/org/chromium/chrome/browser/webapps/WebApkActivity0.java",
   "java/src/org/chromium/chrome/browser/webapps/WebApkActivity1.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillTest.java
index 3fa8f6b..3a73a3c 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillTest.java
@@ -4,6 +4,7 @@
 
 package org.chromium.chrome.browser.autofill;
 
+import android.graphics.Color;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.view.View;
 
@@ -67,7 +68,9 @@
 
                 mWindowAndroid = new ActivityWindowAndroid(activity);
                 mAutofillPopup = new AutofillPopup(activity, anchorView, mMockAutofillCallback);
-                mAutofillPopup.filterAndShow(new AutofillSuggestion[0], false);
+                mAutofillPopup.filterAndShow(new AutofillSuggestion[0], false /* isRtl */,
+                        Color.TRANSPARENT /* backgroundColor */,
+                        Color.TRANSPARENT /* dividerColor */, 0 /* dropdownItemHeight */);
             }
         });
     }
@@ -107,21 +110,24 @@
     private AutofillSuggestion[] createTwoAutofillSuggestionArray() {
         return new AutofillSuggestion[] {
                 new AutofillSuggestion("Sherlock Holmes", "221B Baker Street", DropdownItem.NO_ICON,
-                        42, false, false),
-                new AutofillSuggestion(
-                        "Arthur Dent", "West Country", DropdownItem.NO_ICON, 43, false, false),
+                        false, 42, false, false, false),
+                new AutofillSuggestion("Arthur Dent", "West Country", DropdownItem.NO_ICON,
+                        false, 43, false, false, false),
         };
     }
 
     private AutofillSuggestion[] createFiveAutofillSuggestionArray() {
         return new AutofillSuggestion[] {
                 new AutofillSuggestion("Sherlock Holmes", "221B Baker Street", DropdownItem.NO_ICON,
-                        42, false, false),
-                new AutofillSuggestion(
-                        "Arthur Dent", "West Country", DropdownItem.NO_ICON, 43, false, false),
-                new AutofillSuggestion("Arthos", "France", DropdownItem.NO_ICON, 44, false, false),
-                new AutofillSuggestion("Porthos", "France", DropdownItem.NO_ICON, 45, false, false),
-                new AutofillSuggestion("Aramis", "France", DropdownItem.NO_ICON, 46, false, false),
+                        false, 42, false, false, false),
+                new AutofillSuggestion("Arthur Dent", "West Country", DropdownItem.NO_ICON,
+                        false, 43, false, false, false),
+                new AutofillSuggestion("Arthos", "France", DropdownItem.NO_ICON,
+                        false, 44, false, false, false),
+                new AutofillSuggestion("Porthos", "France", DropdownItem.NO_ICON,
+                        false, 45, false, false, false),
+                new AutofillSuggestion("Aramis", "France", DropdownItem.NO_ICON,
+                        false, 46, false, false, false),
         };
     }
 
@@ -130,7 +136,9 @@
         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
             @Override
             public void run() {
-                mAutofillPopup.filterAndShow(suggestions, false);
+                mAutofillPopup.filterAndShow(suggestions, false /* isRtl */,
+                        Color.TRANSPARENT /* backgroundColor */,
+                        Color.TRANSPARENT /* dividerColor */, 0 /* dropdownItemHeight */);
             }
         });
         CriteriaHelper.pollInstrumentationThread(new Criteria() {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageSavePageLaterEvaluationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageSavePageLaterEvaluationTest.java
index 5382500a..c7f087e 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageSavePageLaterEvaluationTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageSavePageLaterEvaluationTest.java
@@ -119,6 +119,7 @@
         ThreadUtils.runOnUiThread(new Runnable() {
             @Override
             public void run() {
+                assert mBridge != null;
                 mBridge.getRequestsInQueue(new Callback<SavePageRequest[]>() {
                     @Override
                     public void onResult(SavePageRequest[] results) {
@@ -481,6 +482,9 @@
             Log.e(TAG, e.getMessage(), e);
             fail(String.format(
                     "Config file %s is not found, aborting the test.", CONFIG_FILE_PATH));
+        } catch (NumberFormatException e) {
+            Log.e(TAG, e.getMessage(), e);
+            fail("Error parsing config file, aborting test.");
         } finally {
             if (inputStream != null) {
                 inputStream.close();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestIncompleteContactDetailsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestIncompleteContactDetailsTest.java
index 850d402..5cc6612a 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestIncompleteContactDetailsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestIncompleteContactDetailsTest.java
@@ -8,6 +8,7 @@
 import android.test.suitebuilder.annotation.MediumTest;
 
 import org.chromium.base.test.util.Feature;
+import org.chromium.base.test.util.FlakyTest;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.autofill.AutofillTestHelper;
 import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile;
@@ -40,7 +41,11 @@
     }
 
     /** Attempt to update the contact information with invalid data and cancel the transaction. */
-    @MediumTest
+    /*
+     * @MediumTest
+     * Bug=crbug.com/673299
+     */
+    @FlakyTest
     @Feature({"Payments"})
     public void testEditIncompleteContactAndCancel()
             throws InterruptedException, ExecutionException, TimeoutException {
diff --git a/chrome/app/chrome_main.cc b/chrome/app/chrome_main.cc
index 57dfdaf..4e69259 100644
--- a/chrome/app/chrome_main.cc
+++ b/chrome/app/chrome_main.cc
@@ -94,6 +94,7 @@
         *base::CommandLine::ForCurrentProcess();
     if (command_line.HasSwitch("mash"))
       return MashMain();
+    WaitForMashDebuggerIfNecessary();
   }
 #endif  // BUILDFLAG(ENABLE_PACKAGE_MASH_SERVICES)
 
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp
index 7f16b62..d8f0e647 100644
--- a/chrome/app/chromeos_strings.grdp
+++ b/chrome/app/chromeos_strings.grdp
@@ -2164,6 +2164,9 @@
   <message name="IDS_KIOSK_APPS_BUTTON" desc="Text shown on a button that brings up the kiosk apps menu on login screen">
     Apps
   </message>
+  <message name="IDS_LOCK_SCREEN_TASK_MANAGER_NAME" desc="The name of the lock screen as it appears in the task manager. This will be prefixed with another string, such as 'Extension: ' (see IDS_TASK_MANAGER_EXTENSION_PREFIX)">
+    Lock Screen
+  </message>
   <message name="IDS_LOGIN_USER_ADDING_BANNER" desc="Text shown on a banner in user adding screen.">
     Add an account to multiple sign-in. All signed-in accounts can be accessed without a password, so this feature should only be used with trusted accounts.
   </message>
diff --git a/chrome/app/mash/mash_runner.cc b/chrome/app/mash/mash_runner.cc
index ddcb260..acd09ca 100644
--- a/chrome/app/mash/mash_runner.cc
+++ b/chrome/app/mash/mash_runner.cc
@@ -5,6 +5,8 @@
 #include "chrome/app/mash/mash_runner.h"
 
 #include "base/at_exit.h"
+#include "base/base_paths.h"
+#include "base/base_switches.h"
 #include "base/bind.h"
 #include "base/command_line.h"
 #include "base/debug/debugger.h"
@@ -13,7 +15,9 @@
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
 #include "base/message_loop/message_loop.h"
+#include "base/path_service.h"
 #include "base/process/launch.h"
+#include "base/process/process.h"
 #include "base/run_loop.h"
 #include "base/task_scheduler/task_scheduler.h"
 #include "base/threading/sequenced_worker_pool.h"
@@ -34,6 +38,7 @@
 #include "services/service_manager/public/cpp/service_context.h"
 #include "services/service_manager/public/cpp/standalone_service/standalone_service.h"
 #include "services/service_manager/public/interfaces/service_factory.mojom.h"
+#include "services/service_manager/runner/common/client_util.h"
 #include "services/service_manager/runner/common/switches.h"
 #include "services/service_manager/runner/init.h"
 #include "services/service_manager/standalone/context.h"
@@ -94,8 +99,9 @@
       base::CommandLine* command_line) override {
     if (target.name() == kChromeMashServiceName ||
         target.name() == content::mojom::kBrowserServiceName) {
-      command_line->SetProgram(
-          base::CommandLine::ForCurrentProcess()->GetProgram());
+      base::FilePath exe_path;
+      base::PathService::Get(base::FILE_EXE, &exe_path);
+      command_line->SetProgram(exe_path);
     }
     if (target.name() != content::mojom::kBrowserServiceName) {
       // If running anything other than the browser process, launch a mash
@@ -239,3 +245,23 @@
   MashRunner mash_runner;
   return mash_runner.Run();
 }
+
+void WaitForMashDebuggerIfNecessary() {
+  if (!service_manager::ServiceManagerIsRemote())
+    return;
+
+  const base::CommandLine* command_line =
+      base::CommandLine::ForCurrentProcess();
+  const std::string service_name =
+      command_line->GetSwitchValueASCII(switches::kProcessServiceName);
+  if (service_name !=
+      command_line->GetSwitchValueASCII(switches::kWaitForDebugger)) {
+    return;
+  }
+
+  // Include the pid as logging may not have been initialized yet (the pid
+  // printed out by logging is wrong).
+  LOG(WARNING) << "waiting for debugger to attach for service " << service_name
+               << " pid=" << base::Process::Current().Pid();
+  base::debug::WaitForDebugger(120, true);
+}
diff --git a/chrome/app/mash/mash_runner.h b/chrome/app/mash/mash_runner.h
index 813daa0e..bf0bf5fd 100644
--- a/chrome/app/mash/mash_runner.h
+++ b/chrome/app/mash/mash_runner.h
@@ -40,4 +40,8 @@
 
 int MashMain();
 
+// Called if the command line isn't mash to potentially wait for a debugger
+// to attach.
+void WaitForMashDebuggerIfNecessary();
+
 #endif  // CHROME_APP_MASH_MASH_RUNNER_H_
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp
index 098a818..57ad06f 100644
--- a/chrome/app/settings_strings.grdp
+++ b/chrome/app/settings_strings.grdp
@@ -86,6 +86,15 @@
     <message name="IDS_SETTINGS_ABOUT_PAGE_UNSTABLE_WARNING_TITLE" desc="The title of the warning about switching to developer (unstable) channel.">
       Warning: you are switching to developer channel
     </message>
+    <message name="IDS_SETTINGS_ABOUT_PAGE_DIALOG_CHANNEL_STABLE" desc="The stable option in the channel select.">
+      Stable
+    </message>
+    <message name="IDS_SETTINGS_ABOUT_PAGE_DIALOG_CHANNEL_BETA" desc="The beta option in the channel select.">
+      Beta
+    </message>
+    <message name="IDS_SETTINGS_ABOUT_PAGE_DIALOG_CHANNEL_DEV" desc="The development option in the channel select.">
+      Developer - unstable
+    </message>
   </if>
   <if expr="not chromeos">
     <message name="IDS_SETTINGS_ABOUT_PAGE_RELAUNCH" desc="The label for the relaunch button that relaunches the browser once update is complete">
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index f59ef26..49460e6 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -15,6 +15,7 @@
 import("//net/features.gni")
 import("//ppapi/features/features.gni")
 import("//printing/features/features.gni")
+import("//rlz/features/features.gni")
 import("//sandbox/features.gni")
 import("//third_party/protobuf/proto_library.gni")
 import("//ui/base/ui_features.gni")
@@ -1510,6 +1511,7 @@
     "//net:net_with_v8",
     "//ppapi/features",
     "//printing/features",
+    "//rlz/features",
     "//services/image_decoder/public/cpp",
     "//services/service_manager/public/cpp",
     "//skia",
@@ -4209,6 +4211,8 @@
     # "Safe Browsing Basic" files used for safe browsing in full mode
     # (safe_browsing=1) and mobile (=2)
     sources += [
+      "safe_browsing/certificate_reporting_service_test_utils.cc",
+      "safe_browsing/certificate_reporting_service_test_utils.h",
       "safe_browsing/mock_permission_report_sender.cc",
       "safe_browsing/mock_permission_report_sender.h",
     ]
diff --git a/chrome/browser/android/contextualsearch/contextual_search_delegate.cc b/chrome/browser/android/contextualsearch/contextual_search_delegate.cc
index 3002395..d847c10 100644
--- a/chrome/browser/android/contextualsearch/contextual_search_delegate.cc
+++ b/chrome/browser/android/contextualsearch/contextual_search_delegate.cc
@@ -136,10 +136,13 @@
 
   // Add Chrome experiment state to the request headers.
   net::HttpRequestHeaders headers;
+  // Note: It's fine to pass in |is_signed_in| false, which does not affect
+  // transmission of experiment ids coming from the variations server.
+  bool is_signed_in = false;
   variations::AppendVariationHeaders(
       search_term_fetcher_->GetOriginalURL(),
       false,  // Impossible to be incognito at this point.
-      false, &headers);
+      false, is_signed_in, &headers);
   search_term_fetcher_->SetExtraRequestHeaders(headers.ToString());
 
   SetDiscourseContextAndAddToHeader(*context_);
diff --git a/chrome/browser/android/history/browsing_history_bridge.cc b/chrome/browser/android/history/browsing_history_bridge.cc
index 9db2b17..220fe9f 100644
--- a/chrome/browser/android/history/browsing_history_bridge.cc
+++ b/chrome/browser/android/history/browsing_history_bridge.cc
@@ -43,7 +43,11 @@
 
   history::QueryOptions options;
   options.max_count = kMaxQueryCount;
-  options.end_time = base::Time::FromJavaTime(j_query_end_time);
+  if (j_query_end_time == 0) {
+    options.end_time = base::Time();
+  } else {
+    options.end_time = base::Time::FromJavaTime(j_query_end_time);
+  }
   options.duplicate_policy = history::QueryOptions::REMOVE_DUPLICATES_PER_DAY;
 
   browsing_history_service_->QueryHistory(
@@ -138,7 +142,9 @@
 
 void BrowsingHistoryBridge::HasOtherFormsOfBrowsingHistory(
     bool has_other_forms, bool has_synced_results) {
-  // TODO(twellington): implement
+  JNIEnv* env = base::android::AttachCurrentThread();
+  Java_BrowsingHistoryBridge_hasOtherFormsOfBrowsingData(
+      env, j_history_service_obj_.obj(), has_other_forms, has_synced_results);
 }
 
 bool RegisterBrowsingHistoryBridge(JNIEnv* env) {
diff --git a/chrome/browser/android/metrics/uma_session_stats.cc b/chrome/browser/android/metrics/uma_session_stats.cc
index d2ce89b..c318ddb 100644
--- a/chrome/browser/android/metrics/uma_session_stats.cc
+++ b/chrome/browser/android/metrics/uma_session_stats.cc
@@ -168,8 +168,11 @@
   active_group.name = metrics::HashName(trial_name_utf8);
   for (int experiment_id : experiment_ids) {
     active_group.group = metrics::HashName(base::IntToString(experiment_id));
+    // Since external experiments are not based on Chrome's low entropy source,
+    // they are only sent to Google web properties for signed in users to make
+    // sure that this couldn't be used to identify a user that's not signed in.
     variations::AssociateGoogleVariationIDForceHashes(
-        variations::GOOGLE_WEB_PROPERTIES, active_group,
+        variations::GOOGLE_WEB_PROPERTIES_SIGNED_IN, active_group,
         static_cast<variations::VariationID>(experiment_id));
     group_name_hashes.push_back(active_group.group);
   }
diff --git a/chrome/browser/android/offline_pages/evaluation/run_offline_page_evaluation_test.py b/chrome/browser/android/offline_pages/evaluation/run_offline_page_evaluation_test.py
index bb231a6..dafd009 100755
--- a/chrome/browser/android/offline_pages/evaluation/run_offline_page_evaluation_test.py
+++ b/chrome/browser/android/offline_pages/evaluation/run_offline_page_evaluation_test.py
@@ -89,6 +89,7 @@
       output_dir=os.path.expanduser('~/offline_eval_output'),
       user_request=DEFAULT_USER_REQUEST,
       user_test_scheduler=DEFAULT_USE_TEST_SCHEDULER,
+      schedule_batch_size=DEFAULT_BATCH_SIZE,
       verbose=DEFAULT_VERBOSE)
 
   def get_adb_command(args):
diff --git a/chrome/browser/android/webapk/webapk.proto b/chrome/browser/android/webapk/webapk.proto
index 4a18b4cc..90b171e 100644
--- a/chrome/browser/android/webapk/webapk.proto
+++ b/chrome/browser/android/webapk/webapk.proto
@@ -19,7 +19,10 @@
   // URL to download WebAPK.
   optional string signed_download_url = 3;
 
-  reserved 4;
+  // Unique id identifying session with WebAPK server.
+  optional string token = 6;
+
+  reserved 4, 5;
 }
 
 // Sent as part of request to create or update a WebAPK.
diff --git a/chrome/browser/android/webapk/webapk_installer.cc b/chrome/browser/android/webapk/webapk_installer.cc
index 348c336c..840e1147 100644
--- a/chrome/browser/android/webapk/webapk_installer.cc
+++ b/chrome/browser/android/webapk/webapk_installer.cc
@@ -13,6 +13,7 @@
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/memory/ref_counted.h"
+#include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
@@ -315,6 +316,39 @@
       env, java_ref_, java_file_path);
 }
 
+bool WebApkInstaller::HasGooglePlayWebApkInstallDelegate() {
+  JNIEnv* env = base::android::AttachCurrentThread();
+  return Java_WebApkInstaller_hasGooglePlayWebApkInstallDelegate(
+      env, java_ref_);
+}
+
+bool WebApkInstaller::InstallOrUpdateWebApkFromGooglePlay(
+    const std::string& package_name,
+    int version,
+    const std::string& token) {
+  webapk_package_ = package_name;
+
+  JNIEnv* env = base::android::AttachCurrentThread();
+  base::android::ScopedJavaLocalRef<jstring> java_webapk_package =
+      base::android::ConvertUTF8ToJavaString(env, webapk_package_);
+  base::android::ScopedJavaLocalRef<jstring> java_title =
+      base::android::ConvertUTF16ToJavaString(env, shortcut_info_.user_title);
+  base::android::ScopedJavaLocalRef<jstring> java_token =
+      base::android::ConvertUTF8ToJavaString(env, token);
+  base::android::ScopedJavaLocalRef<jstring> java_url =
+      base::android::ConvertUTF8ToJavaString(env, shortcut_info_.url.spec());
+
+  if (task_type_ == WebApkInstaller::INSTALL) {
+    return Java_WebApkInstaller_installWebApkFromGooglePlayAsync(
+        env, java_ref_, java_webapk_package, version, java_title, java_token,
+        java_url);
+  } else {
+    return Java_WebApkInstaller_updateAsyncFromGooglePlay(
+        env, java_ref_, java_webapk_package, version, java_title, java_token,
+        java_url);
+  }
+}
+
 void WebApkInstaller::OnURLFetchComplete(const net::URLFetcher* source) {
   timer_.Stop();
 
@@ -339,6 +373,17 @@
     OnFailure();
     return;
   }
+
+  if (HasGooglePlayWebApkInstallDelegate()) {
+    int version = 1;
+    base::StringToInt(response->version(), &version);
+    if (!InstallOrUpdateWebApkFromGooglePlay(
+        response->package_name(), version, response->token())) {
+      OnFailure();
+    }
+    return;
+  }
+
   OnGotWebApkDownloadUrl(signed_download_url, response->package_name());
 }
 
diff --git a/chrome/browser/android/webapk/webapk_installer.h b/chrome/browser/android/webapk/webapk_installer.h
index c24a6688..052f988e0 100644
--- a/chrome/browser/android/webapk/webapk_installer.h
+++ b/chrome/browser/android/webapk/webapk_installer.h
@@ -105,6 +105,18 @@
       JNIEnv* env,
       const base::android::ScopedJavaLocalRef<jstring>& java_file_path);
 
+  // Returns whether the Google Play install delegate is available.
+  // Note: it is possible that this delegate is null even when installing
+  // WebAPKs using Google Play is enabled.
+  virtual bool HasGooglePlayWebApkInstallDelegate();
+
+  // Called when the package name of the WebAPK is available and the install
+  // or update request is handled by Google Play.
+  virtual bool InstallOrUpdateWebApkFromGooglePlay(
+      const std::string& package_name,
+      int version,
+      const std::string& token);
+
   // Called when the request to install the WebAPK is sent to Google Play.
   void OnSuccess();
 
diff --git a/chrome/browser/android/webapk/webapk_installer_unittest.cc b/chrome/browser/android/webapk/webapk_installer_unittest.cc
index 10021ff9..0734459e 100644
--- a/chrome/browser/android/webapk/webapk_installer_unittest.cc
+++ b/chrome/browser/android/webapk/webapk_installer_unittest.cc
@@ -52,12 +52,17 @@
 
 // WebApkInstaller subclass where
 // WebApkInstaller::StartInstallingDownloadedWebApk() and
-// WebApkInstaller::StartUpdateUsingDownloadedWebApk() are stubbed out.
+// WebApkInstaller::StartUpdateUsingDownloadedWebApk() and
+// WebApkInstaller::HasGooglePlayWebApkInstallDelegate() and
+// WebApkInstaller::InstallOrUpdateWebApkFromGooglePlay() are stubbed out.
 class TestWebApkInstaller : public WebApkInstaller {
  public:
   TestWebApkInstaller(const ShortcutInfo& shortcut_info,
-                      const SkBitmap& shortcut_icon)
-      : WebApkInstaller(shortcut_info, shortcut_icon) {}
+                      const SkBitmap& shortcut_icon,
+                      bool has_google_play_webapk_install_delegate)
+      : WebApkInstaller(shortcut_info, shortcut_icon),
+        has_google_play_webapk_install_delegate_(
+            has_google_play_webapk_install_delegate) {}
 
   bool StartInstallingDownloadedWebApk(
       JNIEnv* env,
@@ -73,6 +78,17 @@
     return true;
   }
 
+  bool HasGooglePlayWebApkInstallDelegate() override {
+    return has_google_play_webapk_install_delegate_;
+  }
+
+  bool InstallOrUpdateWebApkFromGooglePlay(const std::string& package_name,
+                                           int version,
+                                           const std::string& token) override {
+    PostTaskToRunSuccessCallback();
+    return true;
+  }
+
   void PostTaskToRunSuccessCallback() {
     base::ThreadTaskRunnerHandle::Get()->PostTask(
         FROM_HERE,
@@ -80,6 +96,9 @@
   }
 
  private:
+  // Whether the Google Play install delegate is available.
+  bool has_google_play_webapk_install_delegate_;
+
   DISALLOW_COPY_AND_ASSIGN(TestWebApkInstaller);
 };
 
@@ -89,9 +108,15 @@
   explicit WebApkInstallerRunner(const GURL& best_icon_url)
       : url_request_context_getter_(new net::TestURLRequestContextGetter(
             base::ThreadTaskRunnerHandle::Get())),
-        best_icon_url_(best_icon_url) {}
+        best_icon_url_(best_icon_url),
+        has_google_play_webapk_install_delegate_(false) {}
+
   ~WebApkInstallerRunner() {}
 
+  void SetHasGooglePlayWebApkInstallDelegate(bool has_delegate) {
+    has_google_play_webapk_install_delegate_ = has_delegate;
+  }
+
   void RunInstallWebApk() {
     WebApkInstaller* installer = CreateWebApkInstaller();
 
@@ -123,7 +148,8 @@
     info.best_icon_url = best_icon_url_;
 
     // WebApkInstaller owns itself.
-    WebApkInstaller* installer = new TestWebApkInstaller(info, SkBitmap());
+    WebApkInstaller* installer = new TestWebApkInstaller(
+        info, SkBitmap(), has_google_play_webapk_install_delegate_);
     installer->SetTimeoutMs(100);
     return installer;
   }
@@ -154,6 +180,9 @@
   // Whether the installation process succeeded.
   bool success_;
 
+  // Whether the Google Play install delegate is available.
+  bool has_google_play_webapk_install_delegate_;
+
   DISALLOW_COPY_AND_ASSIGN(WebApkInstallerRunner);
 };
 
@@ -331,3 +360,11 @@
   runner->RunUpdateWebApk();
   EXPECT_TRUE(runner->success());
 }
+
+// Test installation succeeds using Google Play.
+TEST_F(WebApkInstallerTest, InstallFromGooglePlaySuccess) {
+  std::unique_ptr<WebApkInstallerRunner> runner = CreateWebApkInstallerRunner();
+  runner->SetHasGooglePlayWebApkInstallDelegate(true);
+  runner->RunInstallWebApk();
+  EXPECT_TRUE(runner->success());
+}
diff --git a/chrome/browser/browser_shutdown.cc b/chrome/browser/browser_shutdown.cc
index cf324c8..33c5ee6 100644
--- a/chrome/browser/browser_shutdown.cc
+++ b/chrome/browser/browser_shutdown.cc
@@ -38,6 +38,7 @@
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/tracing_controller.h"
 #include "printing/features/features.h"
+#include "rlz/features/features.h"
 
 #if defined(OS_WIN)
 #include "chrome/browser/first_run/upgrade_util_win.h"
@@ -52,7 +53,7 @@
 #include "chrome/browser/background/background_mode_manager.h"
 #endif
 
-#if defined(ENABLE_RLZ)
+#if BUILDFLAG(ENABLE_RLZ)
 #include "components/rlz/rlz_tracker.h"
 #endif
 
@@ -175,7 +176,7 @@
 
   prefs->CommitPendingWrite();
 
-#if defined(ENABLE_RLZ)
+#if BUILDFLAG(ENABLE_RLZ)
   // Cleanup any statics created by RLZ. Must be done before NotificationService
   // is destroyed.
   rlz::RLZTracker::CleanupRlz();
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc
index dcf863d..ab34cda 100644
--- a/chrome/browser/chrome_browser_main.cc
+++ b/chrome/browser/chrome_browser_main.cc
@@ -163,6 +163,7 @@
 #include "net/http/http_stream_factory.h"
 #include "net/url_request/url_request.h"
 #include "printing/features/features.h"
+#include "rlz/features/features.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/layout.h"
 #include "ui/base/material_design/material_design_controller.h"
@@ -246,10 +247,10 @@
 #include "printing/printed_document.h"
 #endif  // BUILDFLAG(ENABLE_PRINT_PREVIEW) && !defined(OFFICIAL_BUILD)
 
-#if defined(ENABLE_RLZ)
+#if BUILDFLAG(ENABLE_RLZ)
 #include "chrome/browser/rlz/chrome_rlz_tracker_delegate.h"
 #include "components/rlz/rlz_tracker.h"
-#endif  // defined(ENABLE_RLZ)
+#endif  // BUILDFLAG(ENABLE_RLZ)
 
 #if BUILDFLAG(ENABLE_WEBRTC)
 #include "chrome/browser/media/webrtc/webrtc_log_util.h"
@@ -1708,7 +1709,7 @@
   }
 #endif  // defined(OS_WIN)
 
-#if defined(ENABLE_RLZ) && !defined(OS_CHROMEOS)
+#if BUILDFLAG(ENABLE_RLZ) && !defined(OS_CHROMEOS)
   // Init the RLZ library. This just binds the dll and schedules a task on the
   // file thread to be run sometime later. If this is the first run we record
   // the installation event.
@@ -1725,7 +1726,7 @@
       ChromeRLZTrackerDelegate::IsGoogleDefaultSearch(profile_),
       ChromeRLZTrackerDelegate::IsGoogleHomepage(profile_),
       ChromeRLZTrackerDelegate::IsGoogleInStartpages(profile_));
-#endif  // defined(ENABLE_RLZ) && !defined(OS_CHROMEOS)
+#endif  // BUILDFLAG(ENABLE_RLZ) && !defined(OS_CHROMEOS)
 
   // Configure modules that need access to resources.
   net::NetModule::SetResourceProvider(chrome_common_net::NetResourceProvider);
diff --git a/chrome/browser/chrome_browser_main_extra_parts_exo.cc b/chrome/browser/chrome_browser_main_extra_parts_exo.cc
index 01df0be..af9342b 100644
--- a/chrome/browser/chrome_browser_main_extra_parts_exo.cc
+++ b/chrome/browser/chrome_browser_main_extra_parts_exo.cc
@@ -131,6 +131,7 @@
   display_ =
       base::MakeUnique<exo::Display>(arc_notification_surface_manager_.get());
   wayland_server_ = exo::wayland::Server::Create(display_.get());
+  // Wayland server creation can fail if XDG_RUNTIME_DIR is not set correctly.
   if (wayland_server_)
     wayland_watcher_ = base::MakeUnique<WaylandWatcher>(wayland_server_.get());
 }
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn
index 85b53d1..e04aed9 100644
--- a/chrome/browser/chromeos/BUILD.gn
+++ b/chrome/browser/chromeos/BUILD.gn
@@ -877,14 +877,22 @@
     "login/ui/models/user_board_model.cc",
     "login/ui/models/user_board_model.h",
     "login/ui/proxy_settings_dialog.cc",
+    "login/ui/shared_web_view.cc",
+    "login/ui/shared_web_view.h",
+    "login/ui/shared_web_view_factory.cc",
+    "login/ui/shared_web_view_factory.h",
     "login/ui/simple_web_view_dialog.cc",
     "login/ui/simple_web_view_dialog.h",
     "login/ui/user_adding_screen.cc",
     "login/ui/user_adding_screen.h",
     "login/ui/user_adding_screen_input_methods_controller.cc",
     "login/ui/user_adding_screen_input_methods_controller.h",
+    "login/ui/web_contents_forced_title.cc",
+    "login/ui/web_contents_forced_title.h",
     "login/ui/web_contents_set_background_color.cc",
     "login/ui/web_contents_set_background_color.h",
+    "login/ui/web_view_handle.cc",
+    "login/ui/web_view_handle.h",
     "login/ui/webui_login_display.cc",
     "login/ui/webui_login_display.h",
     "login/ui/webui_login_view.cc",
diff --git a/chrome/browser/chromeos/arc/arc_service_launcher.cc b/chrome/browser/chromeos/arc/arc_service_launcher.cc
index af50b1ae..be75eba 100644
--- a/chrome/browser/chromeos/arc/arc_service_launcher.cc
+++ b/chrome/browser/chromeos/arc/arc_service_launcher.cc
@@ -36,7 +36,6 @@
 #include "components/arc/obb_mounter/arc_obb_mounter_bridge.h"
 #include "components/arc/power/arc_power_bridge.h"
 #include "components/arc/storage_manager/arc_storage_manager.h"
-#include "components/arc/user_data/arc_user_data_service.h"
 #include "components/prefs/pref_member.h"
 #include "content/public/browser/browser_thread.h"
 #include "ui/arc/notification/arc_notification_manager.h"
diff --git a/chrome/browser/chromeos/arc/enterprise/arc_enterprise_reporting_service.cc b/chrome/browser/chromeos/arc/enterprise/arc_enterprise_reporting_service.cc
index 7c005ffb..ea63ad1 100644
--- a/chrome/browser/chromeos/arc/enterprise/arc_enterprise_reporting_service.cc
+++ b/chrome/browser/chromeos/arc/enterprise/arc_enterprise_reporting_service.cc
@@ -11,7 +11,6 @@
 #include "chrome/browser/chromeos/arc/arc_session_manager.h"
 #include "components/arc/arc_bridge_service.h"
 #include "components/arc/arc_service_manager.h"
-#include "components/arc/user_data/arc_user_data_service.h"
 
 namespace arc {
 
diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
index 3e74f47..4b3e12bf 100644
--- a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
+++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
@@ -148,12 +148,13 @@
 #include "net/url_request/url_request.h"
 #include "net/url_request/url_request_context_getter.h"
 #include "printing/backend/print_backend.h"
+#include "rlz/features/features.h"
 #include "ui/base/ime/chromeos/ime_keyboard.h"
 #include "ui/base/ime/chromeos/input_method_manager.h"
 #include "ui/base/touch/touch_device.h"
 #include "ui/events/event_utils.h"
 
-#if defined(ENABLE_RLZ)
+#if BUILDFLAG(ENABLE_RLZ)
 #include "components/rlz/rlz_tracker.h"
 #endif
 
diff --git a/chrome/browser/chromeos/login/lock/webui_screen_locker.cc b/chrome/browser/chromeos/login/lock/webui_screen_locker.cc
index f962b73..4a7aa6d 100644
--- a/chrome/browser/chromeos/login/lock/webui_screen_locker.cc
+++ b/chrome/browser/chromeos/login/lock/webui_screen_locker.cc
@@ -61,7 +61,8 @@
 // WebUIScreenLocker implementation.
 
 WebUIScreenLocker::WebUIScreenLocker(ScreenLocker* screen_locker)
-    : screen_locker_(screen_locker),
+    : WebUILoginView(WebViewSettings()),
+      screen_locker_(screen_locker),
       network_state_helper_(new login::NetworkStateHelper),
       weak_factory_(this) {
   set_should_emit_login_prompt_visible(false);
@@ -88,7 +89,7 @@
   }
   // If LockScreen() was called, we need to clear the signin screen handler
   // delegate set in ShowSigninScreen so that it no longer points to us.
-  if (login_display_.get())
+  if (login_display_.get() && GetOobeUI())
     GetOobeUI()->ResetSigninScreenHandlerDelegate();
 
   if (keyboard::KeyboardController::GetInstance() && is_observing_keyboard_) {
@@ -107,7 +108,7 @@
   lock_window_->AddObserver(this);
 
   Init();
-  content::WebContentsObserver::Observe(webui_login_->GetWebContents());
+  content::WebContentsObserver::Observe(web_view()->GetWebContents());
 
   lock_window_->SetContentsView(this);
   lock_window_->SetBounds(bounds);
@@ -171,7 +172,7 @@
 void WebUIScreenLocker::FocusUserPod() {
   if (!webui_ready_)
     return;
-  webui_login_->RequestFocus();
+  web_view()->RequestFocus();
   GetWebUI()->CallJavascriptFunctionUnsafe(
       "cr.ui.Oobe.forceLockedUserPodFocus");
 }
diff --git a/chrome/browser/chromeos/login/login_utils_browsertest.cc b/chrome/browser/chromeos/login/login_utils_browsertest.cc
index c50687b..b8730021 100644
--- a/chrome/browser/chromeos/login/login_utils_browsertest.cc
+++ b/chrome/browser/chromeos/login/login_utils_browsertest.cc
@@ -27,8 +27,9 @@
 #include "google_apis/gaia/gaia_urls.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
 #include "net/test/embedded_test_server/http_response.h"
+#include "rlz/features/features.h"
 
-#if defined(ENABLE_RLZ)
+#if BUILDFLAG(ENABLE_RLZ)
 #include "components/rlz/rlz_tracker.h"
 #endif
 
@@ -36,7 +37,7 @@
 
 namespace {
 
-#if defined(ENABLE_RLZ)
+#if BUILDFLAG(ENABLE_RLZ)
 void GetAccessPointRlzInBackgroundThread(rlz_lib::AccessPoint point,
                                          base::string16* rlz) {
   ASSERT_FALSE(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
@@ -81,7 +82,7 @@
   DISALLOW_COPY_AND_ASSIGN(LoginUtilsTest);
 };
 
-#if defined(ENABLE_RLZ)
+#if BUILDFLAG(ENABLE_RLZ)
 IN_PROC_BROWSER_TEST_F(LoginUtilsTest, RlzInitialized) {
   WaitForSigninScreen();
 
diff --git a/chrome/browser/chromeos/login/screens/user_selection_screen.cc b/chrome/browser/chromeos/login/screens/user_selection_screen.cc
index 9ebe8f3..e5e2949 100644
--- a/chrome/browser/chromeos/login/screens/user_selection_screen.cc
+++ b/chrome/browser/chromeos/login/screens/user_selection_screen.cc
@@ -269,6 +269,13 @@
 
 void UserSelectionScreen::SetHandler(LoginDisplayWebUIHandler* handler) {
   handler_ = handler;
+
+  if (handler_) {
+    // Forcibly refresh all of the user images, as the |handler_| instance may
+    // have been reused.
+    for (user_manager::User* user : users_)
+      handler_->OnUserImageChanged(*user);
+  }
 }
 
 void UserSelectionScreen::SetView(UserBoardView* view) {
diff --git a/chrome/browser/chromeos/login/session/user_session_manager.cc b/chrome/browser/chromeos/login/session/user_session_manager.cc
index e6956a98..581a1c1 100644
--- a/chrome/browser/chromeos/login/session/user_session_manager.cc
+++ b/chrome/browser/chromeos/login/session/user_session_manager.cc
@@ -114,11 +114,12 @@
 #include "content/public/browser/storage_partition.h"
 #include "content/public/common/content_switches.h"
 #include "net/cert/sth_distributor.h"
+#include "rlz/features/features.h"
 #include "ui/base/ime/chromeos/input_method_descriptor.h"
 #include "ui/base/ime/chromeos/input_method_manager.h"
 #include "url/gurl.h"
 
-#if defined(ENABLE_RLZ)
+#if BUILDFLAG(ENABLE_RLZ)
 #include "chrome/browser/rlz/chrome_rlz_tracker_delegate.h"
 #include "components/rlz/rlz_tracker.h"
 #endif
@@ -242,7 +243,7 @@
   prefs->SetBoolean(prefs::kLanguageShouldMergeInputMethods, true);
 }
 
-#if defined(ENABLE_RLZ)
+#if BUILDFLAG(ENABLE_RLZ)
 // Flag file that disables RLZ tracking, when present.
 const base::FilePath::CharType kRLZDisabledFlagName[] =
     FILE_PATH_LITERAL(".rlz_disabled");
@@ -555,7 +556,7 @@
 }
 
 void UserSessionManager::InitRlz(Profile* profile) {
-#if defined(ENABLE_RLZ)
+#if BUILDFLAG(ENABLE_RLZ)
   if (!g_browser_process->local_state()->HasPrefPath(prefs::kRLZBrand)) {
     // Read brand code asynchronously from an OEM data and repost ourselves.
     google_brand::chromeos::InitBrand(
@@ -1354,7 +1355,7 @@
 }
 
 void UserSessionManager::InitRlzImpl(Profile* profile, bool disabled) {
-#if defined(ENABLE_RLZ)
+#if BUILDFLAG(ENABLE_RLZ)
   PrefService* local_state = g_browser_process->local_state();
   if (disabled) {
     // Empty brand code means an organic install (no RLZ pings are sent).
diff --git a/chrome/browser/chromeos/login/signin_screen_controller.h b/chrome/browser/chromeos/login/signin_screen_controller.h
index 6b95adc..b60cb2f5 100644
--- a/chrome/browser/chromeos/login/signin_screen_controller.h
+++ b/chrome/browser/chromeos/login/signin_screen_controller.h
@@ -23,6 +23,10 @@
 
 // Class that manages control flow between wizard screens. Wizard controller
 // interacts with screen controllers to move the user between screens.
+//
+// This class is allocated when the signin or lock screen is actually visible to
+// the user. It is a 'per-session' class; SignInScreenHandler, in comparsion, is
+// tied to the WebContents lifetime and therefore may live beyond this class.
 class SignInScreenController : public user_manager::RemoveUserDelegate,
                                public content::NotificationObserver {
  public:
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_impl.cc b/chrome/browser/chromeos/login/ui/login_display_host_impl.cc
index c8bb5f6..2b6122d 100644
--- a/chrome/browser/chromeos/login/ui/login_display_host_impl.cc
+++ b/chrome/browser/chromeos/login/ui/login_display_host_impl.cc
@@ -1141,7 +1141,7 @@
   params.delegate = new LoginWidgetDelegate(login_window_);
   login_window_->Init(params);
 
-  login_view_ = new WebUILoginView();
+  login_view_ = new WebUILoginView(WebUILoginView::WebViewSettings());
   login_view_->Init();
   if (login_view_->webui_visible())
     OnLoginPromptVisible();
diff --git a/chrome/browser/chromeos/login/ui/shared_web_view.cc b/chrome/browser/chromeos/login/ui/shared_web_view.cc
new file mode 100644
index 0000000..e2d14be4
--- /dev/null
+++ b/chrome/browser/chromeos/login/ui/shared_web_view.cc
@@ -0,0 +1,81 @@
+// 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 "chrome/browser/chromeos/login/ui/shared_web_view.h"
+
+#include "chrome/browser/chrome_notification_types.h"
+#include "chrome/browser/chromeos/login/ui/web_view_handle.h"
+#include "chrome/browser/profiles/profile.h"
+#include "content/public/browser/notification_service.h"
+#include "content/public/browser/render_view_host.h"
+#include "content/public/browser/render_widget_host.h"
+#include "content/public/browser/web_contents.h"
+#include "ui/views/controls/webview/webview.h"
+
+namespace chromeos {
+
+SharedWebView::SharedWebView(Profile* profile) : profile_(profile) {
+  registrar_.Add(this, chrome::NOTIFICATION_CLOSE_ALL_BROWSERS_REQUEST,
+                 content::NotificationService::AllSources());
+  memory_pressure_listener_ = base::MakeUnique<base::MemoryPressureListener>(
+      base::Bind(&SharedWebView::OnMemoryPressure, base::Unretained(this)));
+}
+
+SharedWebView::~SharedWebView() {}
+
+void SharedWebView::Shutdown() {
+  web_view_handle_ = nullptr;
+}
+
+bool SharedWebView::Get(const GURL& url,
+                        scoped_refptr<WebViewHandle>* out_handle) {
+  // At the moment only one shared WebView instance is supported per profile.
+  DCHECK(web_view_url_.is_empty() || web_view_url_ == url);
+  web_view_url_ = url;
+
+  // Ensure the WebView is not being reused simultaneously.
+  DCHECK(!web_view_handle_ || web_view_handle_->HasOneRef());
+
+  // Clear cached reference if it is no longer valid (ie, destroyed in task
+  // manager).
+  if (web_view_handle_ &&
+      !web_view_handle_->web_view()
+           ->GetWebContents()
+           ->GetRenderViewHost()
+           ->GetWidget()
+           ->GetView()) {
+    web_view_handle_ = nullptr;
+  }
+
+  // Create WebView if needed.
+  bool reused = true;
+  if (!web_view_handle_) {
+    web_view_handle_ = new WebViewHandle(profile_);
+    reused = false;
+  }
+
+  *out_handle = web_view_handle_;
+  return reused;
+}
+
+void SharedWebView::Observe(int type,
+                            const content::NotificationSource& source,
+                            const content::NotificationDetails& details) {
+  DCHECK_EQ(chrome::NOTIFICATION_CLOSE_ALL_BROWSERS_REQUEST, type);
+  web_view_handle_ = nullptr;
+}
+
+void SharedWebView::OnMemoryPressure(
+    base::MemoryPressureListener::MemoryPressureLevel level) {
+  switch (level) {
+    case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE:
+      break;
+    case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE:
+    case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL:
+      web_view_handle_ = nullptr;
+      break;
+  }
+}
+
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/ui/shared_web_view.h b/chrome/browser/chromeos/login/ui/shared_web_view.h
new file mode 100644
index 0000000..abe936f8
--- /dev/null
+++ b/chrome/browser/chromeos/login/ui/shared_web_view.h
@@ -0,0 +1,70 @@
+// 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 CHROME_BROWSER_CHROMEOS_LOGIN_UI_SHARED_WEB_VIEW_H_
+#define CHROME_BROWSER_CHROMEOS_LOGIN_UI_SHARED_WEB_VIEW_H_
+
+#include <memory>
+
+#include "base/macros.h"
+#include "base/memory/memory_pressure_listener.h"
+#include "base/memory/ref_counted.h"
+#include "components/keyed_service/core/keyed_service.h"
+#include "content/public/browser/notification_observer.h"
+#include "content/public/browser/notification_registrar.h"
+#include "url/gurl.h"
+
+class Profile;
+
+namespace chromeos {
+
+class WebViewHandle;
+
+// Stores and fetches a views::WebView instance that is ulimately owned by the
+// signin profile. This allows for a WebView to be reused over time or
+// preloaded. Use SharedWebViewFactory to get an instance of this class.
+class SharedWebView : public KeyedService,
+                      public content::NotificationObserver {
+ public:
+  explicit SharedWebView(Profile* profile);
+  ~SharedWebView() override;
+  void Shutdown() override;
+
+  // Stores a webview instance inside of |out_handle|. |url| is the initial
+  // URL that the webview stores (note: this function does not perform the
+  // navigation). This returns true if the webview was reused, false if it
+  // was freshly created.
+  bool Get(const GURL& url, scoped_refptr<WebViewHandle>* out_handle);
+
+ private:
+  // content::NotificationObserver:
+  void Observe(int type,
+               const content::NotificationSource& source,
+               const content::NotificationDetails& details) override;
+
+  // Called when there is a memory pressure event.
+  void OnMemoryPressure(
+      base::MemoryPressureListener::MemoryPressureLevel level);
+
+  content::NotificationRegistrar registrar_;
+
+  // Profile used for creating the views::WebView instance.
+  Profile* const profile_;
+
+  // Cached URL that the |web_view_| instance should point to used for
+  // validation.
+  GURL web_view_url_;
+
+  // Shared web-view instance. Callers may take a reference on the handle so it
+  // could outlive this class.
+  scoped_refptr<WebViewHandle> web_view_handle_;
+
+  std::unique_ptr<base::MemoryPressureListener> memory_pressure_listener_;
+
+  DISALLOW_COPY_AND_ASSIGN(SharedWebView);
+};
+
+}  // namespace chromeos
+
+#endif  // CHROME_BROWSER_CHROMEOS_LOGIN_UI_SHARED_WEB_VIEW_H_
diff --git a/chrome/browser/chromeos/login/ui/shared_web_view_factory.cc b/chrome/browser/chromeos/login/ui/shared_web_view_factory.cc
new file mode 100644
index 0000000..a42a30b3f
--- /dev/null
+++ b/chrome/browser/chromeos/login/ui/shared_web_view_factory.cc
@@ -0,0 +1,48 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/login/ui/shared_web_view_factory.h"
+
+#include "chrome/browser/chromeos/login/ui/shared_web_view.h"
+#include "chrome/browser/chromeos/profiles/profile_helper.h"
+#include "chrome/browser/profiles/incognito_helpers.h"
+#include "chrome/browser/profiles/profile.h"
+#include "components/keyed_service/content/browser_context_dependency_manager.h"
+
+namespace chromeos {
+
+// static
+SharedWebView* SharedWebViewFactory::GetForProfile(Profile* profile) {
+  auto result = static_cast<SharedWebView*>(
+      GetInstance()->GetServiceForBrowserContext(profile, true));
+  return result;
+}
+
+// static
+SharedWebViewFactory* SharedWebViewFactory::GetInstance() {
+  return base::Singleton<SharedWebViewFactory>::get();
+}
+
+SharedWebViewFactory::SharedWebViewFactory()
+    : BrowserContextKeyedServiceFactory(
+          "SharedWebViewFactory",
+          BrowserContextDependencyManager::GetInstance()) {}
+
+SharedWebViewFactory::~SharedWebViewFactory() {}
+
+content::BrowserContext* SharedWebViewFactory::GetBrowserContextToUse(
+    content::BrowserContext* context) const {
+  // Make sure that only the SigninProfile is using a shared webview.
+  if (Profile::FromBrowserContext(context) != ProfileHelper::GetSigninProfile())
+    return nullptr;
+
+  return context;
+}
+
+KeyedService* SharedWebViewFactory::BuildServiceInstanceFor(
+    content::BrowserContext* context) const {
+  return new SharedWebView(Profile::FromBrowserContext(context));
+}
+
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/ui/shared_web_view_factory.h b/chrome/browser/chromeos/login/ui/shared_web_view_factory.h
new file mode 100644
index 0000000..7386b5e
--- /dev/null
+++ b/chrome/browser/chromeos/login/ui/shared_web_view_factory.h
@@ -0,0 +1,42 @@
+// 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 CHROME_BROWSER_CHROMEOS_LOGIN_UI_SHARED_WEB_VIEW_FACTORY_H_
+#define CHROME_BROWSER_CHROMEOS_LOGIN_UI_SHARED_WEB_VIEW_FACTORY_H_
+
+#include "base/macros.h"
+#include "base/memory/singleton.h"
+#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
+
+class Profile;
+
+namespace chromeos {
+
+class SharedWebView;
+
+// Fetches a SharedWebView instance for the signin profile.
+class SharedWebViewFactory : public BrowserContextKeyedServiceFactory {
+ public:
+  static SharedWebView* GetForProfile(Profile* profile);
+
+  static SharedWebViewFactory* GetInstance();
+
+ private:
+  friend struct base::DefaultSingletonTraits<SharedWebViewFactory>;
+
+  SharedWebViewFactory();
+  ~SharedWebViewFactory() override;
+
+  // BrowserContextKeyedServiceFactory:
+  content::BrowserContext* GetBrowserContextToUse(
+      content::BrowserContext* context) const override;
+  KeyedService* BuildServiceInstanceFor(
+      content::BrowserContext* profile) const override;
+
+  DISALLOW_COPY_AND_ASSIGN(SharedWebViewFactory);
+};
+
+}  // namespace chromeos
+
+#endif  // CHROME_BROWSER_CHROMEOS_LOGIN_UI_SHARED_WEB_VIEW_FACTORY_H_
diff --git a/chrome/browser/chromeos/login/ui/web_contents_forced_title.cc b/chrome/browser/chromeos/login/ui/web_contents_forced_title.cc
new file mode 100644
index 0000000..51dbef2
--- /dev/null
+++ b/chrome/browser/chromeos/login/ui/web_contents_forced_title.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 "chrome/browser/chromeos/login/ui/web_contents_forced_title.h"
+
+#include "content/public/browser/navigation_entry.h"
+#include "content/public/browser/web_contents.h"
+
+DEFINE_WEB_CONTENTS_USER_DATA_KEY(chromeos::WebContentsForcedTitle);
+
+namespace chromeos {
+
+// static
+void WebContentsForcedTitle::CreateForWebContentsWithTitle(
+    content::WebContents* web_contents,
+    const base::string16& title) {
+  if (FromWebContents(web_contents))
+    return;
+
+  web_contents->UpdateTitleForEntry(nullptr, title);
+  web_contents->SetUserData(UserDataKey(),
+                            new WebContentsForcedTitle(web_contents, title));
+}
+
+WebContentsForcedTitle::WebContentsForcedTitle(
+    content::WebContents* web_contents,
+    const base::string16& title)
+    : content::WebContentsObserver(web_contents), title_(title) {}
+
+WebContentsForcedTitle::~WebContentsForcedTitle() {}
+
+void WebContentsForcedTitle::TitleWasSet(content::NavigationEntry* entry,
+                                         bool explicit_set) {
+  if (!entry || entry->GetTitle() != title_)
+    web_contents()->UpdateTitleForEntry(entry, title_);
+}
+
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/ui/web_contents_forced_title.h b/chrome/browser/chromeos/login/ui/web_contents_forced_title.h
new file mode 100644
index 0000000..b12ebd2
--- /dev/null
+++ b/chrome/browser/chromeos/login/ui/web_contents_forced_title.h
@@ -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.
+
+#ifndef CHROME_BROWSER_CHROMEOS_LOGIN_UI_WEB_CONTENTS_FORCED_TITLE_H_
+#define CHROME_BROWSER_CHROMEOS_LOGIN_UI_WEB_CONTENTS_FORCED_TITLE_H_
+
+#include "base/strings/string16.h"
+#include "content/public/browser/web_contents_observer.h"
+#include "content/public/browser/web_contents_user_data.h"
+
+namespace chromeos {
+
+// Ensures that the title of the WebContents instance this object is attached
+// to is always set to the given title value.
+class WebContentsForcedTitle
+    : public content::WebContentsObserver,
+      public content::WebContentsUserData<WebContentsForcedTitle> {
+ public:
+  static void CreateForWebContentsWithTitle(content::WebContents* web_contents,
+                                            const base::string16& title);
+
+  ~WebContentsForcedTitle() override;
+
+ private:
+  WebContentsForcedTitle(content::WebContents* web_contents,
+                         const base::string16& title);
+
+  // content::WebContentsObserver:
+  void TitleWasSet(content::NavigationEntry* entry, bool explicit_set) override;
+
+  base::string16 title_;
+
+  DISALLOW_COPY_AND_ASSIGN(WebContentsForcedTitle);
+};
+
+}  // namespace chromeos
+
+#endif  // CHROME_BROWSER_CHROMEOS_LOGIN_UI_WEB_CONTENTS_FORCED_TITLE_H_
diff --git a/chrome/browser/chromeos/login/ui/web_view_handle.cc b/chrome/browser/chromeos/login/ui/web_view_handle.cc
new file mode 100644
index 0000000..45165abd
--- /dev/null
+++ b/chrome/browser/chromeos/login/ui/web_view_handle.cc
@@ -0,0 +1,19 @@
+// 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 "chrome/browser/chromeos/login/ui/web_view_handle.h"
+
+#include "chrome/browser/profiles/profile.h"
+#include "ui/views/controls/webview/webview.h"
+
+namespace chromeos {
+
+WebViewHandle::WebViewHandle(Profile* profile)
+    : web_view_(base::MakeUnique<views::WebView>(profile)) {
+  web_view_->set_owned_by_client();
+}
+
+WebViewHandle::~WebViewHandle() {}
+
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/ui/web_view_handle.h b/chrome/browser/chromeos/login/ui/web_view_handle.h
new file mode 100644
index 0000000..856abfc
--- /dev/null
+++ b/chrome/browser/chromeos/login/ui/web_view_handle.h
@@ -0,0 +1,41 @@
+// 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 CHROME_BROWSER_CHROMEOS_LOGIN_UI_WEB_VIEW_HANDLE_H_
+#define CHROME_BROWSER_CHROMEOS_LOGIN_UI_WEB_VIEW_HANDLE_H_
+
+#include <memory>
+
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+
+class Profile;
+
+namespace views {
+class WebView;
+}
+
+namespace chromeos {
+
+// Owns a views::WebView instance. Any caller actively using the views::WebView
+// instance should increase/decrease the refcount.
+class WebViewHandle : public base::RefCounted<WebViewHandle> {
+ public:
+  explicit WebViewHandle(Profile* profile);
+
+  // Returns an unowned pointer to the stored |web_view| instance.
+  views::WebView* web_view() { return web_view_.get(); }
+
+ private:
+  friend class base::RefCounted<WebViewHandle>;
+  ~WebViewHandle();
+
+  std::unique_ptr<views::WebView> web_view_;
+
+  DISALLOW_COPY_AND_ASSIGN(WebViewHandle);
+};
+
+}  // namespace chromeos
+
+#endif  // CHROME_BROWSER_CHROMEOS_LOGIN_UI_WEB_VIEW_HANDLE_H_
diff --git a/chrome/browser/chromeos/login/ui/webui_login_view.cc b/chrome/browser/chromeos/login/ui/webui_login_view.cc
index a9d53c9..3cc07a5 100644
--- a/chrome/browser/chromeos/login/ui/webui_login_view.cc
+++ b/chrome/browser/chromeos/login/ui/webui_login_view.cc
@@ -22,7 +22,11 @@
 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h"
 #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h"
 #include "chrome/browser/chromeos/login/ui/proxy_settings_dialog.h"
+#include "chrome/browser/chromeos/login/ui/shared_web_view.h"
+#include "chrome/browser/chromeos/login/ui/shared_web_view_factory.h"
+#include "chrome/browser/chromeos/login/ui/web_contents_forced_title.h"
 #include "chrome/browser/chromeos/login/ui/web_contents_set_background_color.h"
+#include "chrome/browser/chromeos/login/ui/web_view_handle.h"
 #include "chrome/browser/chromeos/login/ui/webui_login_display.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/chromeos/settings/cros_settings.h"
@@ -176,7 +180,8 @@
 
 // WebUILoginView public: ------------------------------------------------------
 
-WebUILoginView::WebUILoginView() {
+WebUILoginView::WebUILoginView(const WebViewSettings& settings)
+    : settings_(settings) {
   registrar_.Add(this,
                  chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE,
                  content::NotificationService::AllSources());
@@ -252,15 +257,28 @@
   } else {
     NOTIMPLEMENTED();
   }
+
+  // If the WebView is going to be reused, make sure we call teardown.
+  if (!webui_login_->HasOneRef())
+    GetWebUI()->CallJavascriptFunctionUnsafe("cr.ui.Oobe.teardown");
+
+  // Clear any delegates we have set on the WebView.
+  WebContents* web_contents = web_view()->GetWebContents();
+  WebContentsModalDialogManager::FromWebContents(web_contents)
+      ->SetDelegate(nullptr);
+  web_contents->SetDelegate(nullptr);
 }
 
-void WebUILoginView::Init() {
-  Profile* signin_profile = ProfileHelper::GetSigninProfile();
-  webui_login_ = new views::WebView(signin_profile);
-  webui_login_->set_allow_accelerators(true);
-  AddChildView(webui_login_);
+// static
+void WebUILoginView::InitializeWebView(views::WebView* web_view,
+                                       const base::string16& title) {
+  WebContents* web_contents = web_view->GetWebContents();
 
-  WebContents* web_contents = webui_login_->GetWebContents();
+  if (!title.empty())
+    WebContentsForcedTitle::CreateForWebContentsWithTitle(web_contents, title);
+
+  WebContentsSetBackgroundColor::CreateForWebContentsWithColor(
+      web_contents, SK_ColorTRANSPARENT);
 
   // Ensure that the login UI has a tab ID, which will allow the GAIA auth
   // extension's background script to tell it apart from a captive portal window
@@ -274,16 +292,38 @@
 
   // LoginHandlerViews uses a constrained window for the password manager view.
   WebContentsModalDialogManager::CreateForWebContents(web_contents);
-  WebContentsModalDialogManager::FromWebContents(web_contents)->
-      SetDelegate(this);
 
-  web_contents->SetDelegate(this);
   extensions::SetViewType(web_contents, extensions::VIEW_TYPE_COMPONENT);
   extensions::ChromeExtensionWebContentsObserver::CreateForWebContents(
       web_contents);
   content::RendererPreferences* prefs = web_contents->GetMutableRendererPrefs();
   renderer_preferences_util::UpdateFromSystemSettings(
-      prefs, signin_profile, web_contents);
+      prefs, ProfileHelper::GetSigninProfile(), web_contents);
+}
+
+void WebUILoginView::Init() {
+  Profile* signin_profile = ProfileHelper::GetSigninProfile();
+
+  if (!settings_.preloaded_url.is_empty()) {
+    SharedWebView* shared_web_view =
+        SharedWebViewFactory::GetForProfile(signin_profile);
+    is_reusing_webview_ =
+        shared_web_view->Get(settings_.preloaded_url, &webui_login_);
+  } else {
+    webui_login_ = new WebViewHandle(signin_profile);
+    is_reusing_webview_ = false;
+  }
+
+  WebContents* web_contents = web_view()->GetWebContents();
+  if (!is_reusing_webview_)
+    InitializeWebView(web_view(), settings_.web_view_title);
+
+  web_view()->set_allow_accelerators(true);
+  AddChildView(web_view());
+
+  WebContentsModalDialogManager::FromWebContents(web_contents)
+      ->SetDelegate(this);
+  web_contents->SetDelegate(this);
 
   status_area_widget_host_ = new views::View;
   AddChildView(status_area_widget_host_);
@@ -294,7 +334,7 @@
 }
 
 void WebUILoginView::RequestFocus() {
-  webui_login_->RequestFocus();
+  web_view()->RequestFocus();
 }
 
 web_modal::WebContentsModalDialogHost*
@@ -334,7 +374,7 @@
   if (entry == accel_map_.end())
     return false;
 
-  if (!webui_login_)
+  if (!web_view())
     return true;
 
   content::WebUI* web_ui = GetWebUI();
@@ -351,12 +391,15 @@
   return GetWidget()->GetNativeWindow();
 }
 
-void WebUILoginView::LoadURL(const GURL & url) {
-  webui_login_->LoadInitialURL(url);
-  webui_login_->RequestFocus();
+void WebUILoginView::LoadURL(const GURL& url) {
+  // If a preloaded_url is provided then |url| must match it.
+  DCHECK(settings_.preloaded_url.is_empty() || url == settings_.preloaded_url);
 
-  WebContentsSetBackgroundColor::CreateForWebContentsWithColor(
-      GetWebContents(), SK_ColorTRANSPARENT);
+  if (is_reusing_webview_ && !settings_.preloaded_url.is_empty())
+    GetWebUI()->CallJavascriptFunctionUnsafe("cr.ui.Oobe.reload");
+  else
+    web_view()->LoadInitialURL(url);
+  web_view()->RequestFocus();
 
   // There is no Shell instance while running in mash.
   if (chrome::IsRunningInMash())
@@ -373,14 +416,17 @@
 }
 
 content::WebUI* WebUILoginView::GetWebUI() {
-  return webui_login_->web_contents()->GetWebUI();
+  return web_view()->web_contents()->GetWebUI();
 }
 
 content::WebContents* WebUILoginView::GetWebContents() {
-  return webui_login_->web_contents();
+  return web_view()->web_contents();
 }
 
 OobeUI* WebUILoginView::GetOobeUI() {
+  if (!GetWebUI())
+    return nullptr;
+
   return static_cast<OobeUI*>(GetWebUI()->GetController());
 }
 
@@ -442,8 +488,8 @@
 // WebUILoginView protected: ---------------------------------------------------
 
 void WebUILoginView::Layout() {
-  DCHECK(webui_login_);
-  webui_login_->SetBoundsRect(bounds());
+  DCHECK(web_view());
+  web_view()->SetBoundsRect(bounds());
 
   for (auto& observer : observer_list_)
     observer.OnPositionRequiresUpdate();
@@ -459,9 +505,9 @@
 
 void WebUILoginView::AboutToRequestFocusFromTabTraversal(bool reverse) {
   // Return the focus to the web contents.
-  webui_login_->web_contents()->FocusThroughTabTraversal(reverse);
+  web_view()->web_contents()->FocusThroughTabTraversal(reverse);
   GetWidget()->Activate();
-  webui_login_->web_contents()->Focus();
+  web_view()->web_contents()->Focus();
 }
 
 void WebUILoginView::Observe(int type,
@@ -479,6 +525,10 @@
   }
 }
 
+views::WebView* WebUILoginView::web_view() {
+  return webui_login_->web_view();
+}
+
 // WebUILoginView private: -----------------------------------------------------
 
 bool WebUILoginView::HandleContextMenu(
diff --git a/chrome/browser/chromeos/login/ui/webui_login_view.h b/chrome/browser/chromeos/login/ui/webui_login_view.h
index 5fbd2c7..c3f3bb2 100644
--- a/chrome/browser/chromeos/login/ui/webui_login_view.h
+++ b/chrome/browser/chromeos/login/ui/webui_login_view.h
@@ -9,6 +9,7 @@
 #include <string>
 
 #include "base/macros.h"
+#include "base/memory/ref_counted.h"
 #include "base/observer_list.h"
 #include "chrome/browser/ui/chrome_web_modal_dialog_manager_delegate.h"
 #include "components/web_modal/web_contents_modal_dialog_host.h"
@@ -18,8 +19,7 @@
 #include "ui/views/controls/webview/unhandled_keyboard_event_handler.h"
 #include "ui/views/widget/widget.h"
 #include "ui/views/widget/widget_delegate.h"
-
-class GURL;
+#include "url/gurl.h"
 
 namespace content {
 class WebUI;
@@ -34,6 +34,7 @@
 namespace chromeos {
 
 class OobeUI;
+class WebViewHandle;
 
 // View used to render a WebUI supporting Widget. This widget is used for the
 // WebUI based start up and lock screens. It contains a WebView.
@@ -43,10 +44,19 @@
                        public ChromeWebModalDialogManagerDelegate,
                        public web_modal::WebContentsModalDialogHost {
  public:
+  struct WebViewSettings {
+    // URL of the WebView to preload and reuse across WebUILoginView instances.
+    GURL preloaded_url;
+
+    // Title of the web contents. This will be shown in the task manager. If
+    // empty, the default webview title will be used.
+    base::string16 web_view_title;
+  };
+
   // Internal class name.
   static const char kViewClassName[];
 
-  WebUILoginView();
+  explicit WebUILoginView(const WebViewSettings& settings);
   ~WebUILoginView() override;
 
   // Initializes the webui login view.
@@ -105,6 +115,9 @@
   }
 
  protected:
+  static void InitializeWebView(views::WebView* web_view,
+                                const base::string16& title);
+
   // Overridden from views::View:
   void Layout() override;
   void OnLocaleChanged() override;
@@ -116,8 +129,7 @@
                const content::NotificationSource& source,
                const content::NotificationDetails& details) override;
 
-  // WebView for rendering a webpage as a webui login.
-  views::WebView* webui_login_ = nullptr;
+  views::WebView* web_view();
 
  private:
   // Map type for the accelerator-to-identifier map.
@@ -148,6 +160,15 @@
 
   content::NotificationRegistrar registrar_;
 
+  // WebView configuration options.
+  const WebViewSettings settings_;
+
+  // WebView for rendering a webpage as a webui login.
+  scoped_refptr<WebViewHandle> webui_login_;
+
+  // True if the current webview instance (ie, GetWebUI()) has been reused.
+  bool is_reusing_webview_ = false;
+
   // Converts keyboard events on the WebContents to accelerators.
   views::UnhandledKeyboardEventHandler unhandled_keyboard_event_handler_;
 
diff --git a/chrome/browser/extensions/BUILD.gn b/chrome/browser/extensions/BUILD.gn
index afc16da..4398018 100644
--- a/chrome/browser/extensions/BUILD.gn
+++ b/chrome/browser/extensions/BUILD.gn
@@ -7,6 +7,7 @@
 import("//chrome/common/features.gni")
 import("//extensions/features/features.gni")
 import("//media/media_options.gni")
+import("//rlz/features/features.gni")
 
 assert(enable_extensions)
 
@@ -897,6 +898,7 @@
     "//net",
     "//ppapi/features",
     "//printing/features",
+    "//rlz/features",
     "//skia",
     "//sql",
     "//storage/browser",
diff --git a/chrome/browser/extensions/api/music_manager_private/device_id_win.cc b/chrome/browser/extensions/api/music_manager_private/device_id_win.cc
index 90814d7..6455e9a 100644
--- a/chrome/browser/extensions/api/music_manager_private/device_id_win.cc
+++ b/chrome/browser/extensions/api/music_manager_private/device_id_win.cc
@@ -25,8 +25,9 @@
 #include "base/threading/thread_restrictions.h"
 #include "base/win/windows_version.h"
 #include "content/public/browser/browser_thread.h"
+#include "rlz/features/features.h"
 
-#if defined(ENABLE_RLZ)
+#if BUILDFLAG(ENABLE_RLZ)
 #include "rlz/lib/machine_id.h"
 #endif
 
@@ -183,13 +184,13 @@
 }
 
 std::string GetRlzMachineId() {
-#if defined(ENABLE_RLZ)
+#if BUILDFLAG(ENABLE_RLZ)
   std::string machine_id;
   if (!rlz_lib::GetMachineId(&machine_id))
-    return "";
+    return std::string();
   return machine_id;
 #else
-  return "";
+  return std::string();
 #endif
 }
 
diff --git a/chrome/browser/extensions/api/music_manager_private/music_manager_private_browsertest.cc b/chrome/browser/extensions/api/music_manager_private/music_manager_private_browsertest.cc
index 27e7bc9..40a360b 100644
--- a/chrome/browser/extensions/api/music_manager_private/music_manager_private_browsertest.cc
+++ b/chrome/browser/extensions/api/music_manager_private/music_manager_private_browsertest.cc
@@ -5,9 +5,10 @@
 #include "build/build_config.h"
 #include "chrome/browser/apps/app_browsertest_util.h"
 #include "extensions/test/extension_test_message_listener.h"
+#include "rlz/features/features.h"
 
 // Supported on all platforms, but on Windows only if RLZ is enabled.
-#if !defined(OS_WIN) || defined(ENABLE_RLZ)
+#if !defined(OS_WIN) || BUILDFLAG(ENABLE_RLZ)
 
 class MusicManagerPrivateTest : public extensions::PlatformAppBrowserTest {
 };
diff --git a/chrome/browser/extensions/install_signer.cc b/chrome/browser/extensions/install_signer.cc
index a7a085af..bc584ad 100644
--- a/chrome/browser/extensions/install_signer.cc
+++ b/chrome/browser/extensions/install_signer.cc
@@ -34,9 +34,10 @@
 #include "net/url_request/url_fetcher_delegate.h"
 #include "net/url_request/url_request_context_getter.h"
 #include "net/url_request/url_request_status.h"
+#include "rlz/features/features.h"
 #include "url/gurl.h"
 
-#if defined(ENABLE_RLZ)
+#if BUILDFLAG(ENABLE_RLZ)
 #include "rlz/lib/machine_id.h"
 #endif
 
@@ -84,7 +85,7 @@
 // |result|.
 bool HashWithMachineId(const std::string& salt, std::string* result) {
   std::string machine_id;
-#if defined(ENABLE_RLZ)
+#if BUILDFLAG(ENABLE_RLZ)
   if (!rlz_lib::GetMachineId(&machine_id))
     return false;
 #else
diff --git a/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.cc b/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.cc
index e5a36cc..a144df7c 100644
--- a/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.cc
+++ b/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.cc
@@ -485,8 +485,11 @@
     net::HttpRequestHeaders headers;
     headers.CopyFrom(request->extra_request_headers());
     bool is_off_the_record = io_data->IsOffTheRecord();
+    bool is_signed_in =
+        !is_off_the_record &&
+        !io_data->google_services_account_id()->GetValue().empty();
     variations::AppendVariationHeaders(
-        request->url(), is_off_the_record,
+        request->url(), is_off_the_record, is_signed_in,
         !is_off_the_record && io_data->GetMetricsEnabledStateOnIOThread(),
         &headers);
     request->SetExtraRequestHeaders(headers);
diff --git a/chrome/browser/mac/exception_processor_unittest.mm b/chrome/browser/mac/exception_processor_unittest.mm
index 74c1128..0e8460b 100644
--- a/chrome/browser/mac/exception_processor_unittest.mm
+++ b/chrome/browser/mac/exception_processor_unittest.mm
@@ -95,7 +95,7 @@
   CFRunLoopRef run_loop = CFRunLoopGetCurrent();
 
   CFRunLoopPerformBlock(run_loop, kCFRunLoopCommonModes, ^{
-    [NSException raise:@"ThrowExceptionInRunLoop" format:nil];
+    [NSException raise:@"ThrowExceptionInRunLoop" format:@""];
   });
   CFRunLoopPerformBlock(run_loop, kCFRunLoopCommonModes, ^{
     CFRunLoopStop(run_loop);
@@ -129,7 +129,7 @@
   CFRunLoopRef run_loop = CFRunLoopGetCurrent();
   CFRunLoopPerformBlock(run_loop, kCFRunLoopCommonModes, ^{
     @try {
-      [NSException raise:@"ObjcExceptionPreprocessCaught" format:nil];
+      [NSException raise:@"ObjcExceptionPreprocessCaught" format:@""];
     } @catch (id exception) {
     }
   });
diff --git a/chrome/browser/media/cast_remoting_connector_messaging.cc b/chrome/browser/media/cast_remoting_connector_messaging.cc
index 40682e37..d55d6a5 100644
--- a/chrome/browser/media/cast_remoting_connector_messaging.cc
+++ b/chrome/browser/media/cast_remoting_connector_messaging.cc
@@ -50,10 +50,9 @@
   start += specifier.size();
   if (start + 1 >= message.size())
     return -1; // Must be at least one hex digit following the specifier.
+  const auto length = message.find(kMessageFieldSeparator, start) - start;
   int parsed_value;
-  if (!base::HexStringToInt(
-          message.substr(start, message.find(kMessageFieldSeparator, start)),
-          &parsed_value) ||
+  if (!base::HexStringToInt(message.substr(start, length), &parsed_value) ||
       parsed_value < 0 ||
       parsed_value > std::numeric_limits<int32_t>::max()) {
     return -1; // Non-hex digits, or outside valid range.
diff --git a/chrome/browser/ntp_snippets/download_suggestions_provider.cc b/chrome/browser/ntp_snippets/download_suggestions_provider.cc
index b1e5fac..86155a2e 100644
--- a/chrome/browser/ntp_snippets/download_suggestions_provider.cc
+++ b/chrome/browser/ntp_snippets/download_suggestions_provider.cc
@@ -17,6 +17,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/time/time.h"
+#include "base/values.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/ntp_snippets/features.h"
@@ -29,6 +30,7 @@
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/gfx/image/image.h"
 
+using base::ContainsValue;
 using content::DownloadItem;
 using content::DownloadManager;
 using ntp_snippets::Category;
@@ -49,6 +51,9 @@
 
 const char* kMaxSuggestionsCountParamName = "downloads_max_count";
 
+// Maximal number of dismissed asset download IDs stored at any time.
+const int kMaxDismissedIdCount = 100;
+
 bool CompareOfflinePagesMostRecentlyCreatedFirst(const OfflinePageItem& left,
                                                  const OfflinePageItem& right) {
   return left.creation_time > right.creation_time;
@@ -186,12 +191,8 @@
 void DownloadSuggestionsProvider::DismissSuggestion(
     const ContentSuggestion::ID& suggestion_id) {
   DCHECK_EQ(provided_category_, suggestion_id.category());
-  std::set<std::string> dismissed_ids =
-      ReadDismissedIDsFromPrefs(CorrespondsToOfflinePage(suggestion_id));
-  dismissed_ids.insert(suggestion_id.id_within_category());
-  StoreDismissedIDsToPrefs(CorrespondsToOfflinePage(suggestion_id),
-                           dismissed_ids);
 
+  AddToDismissedStorageIfNeeded(suggestion_id);
   RemoveSuggestionFromCacheAndRetrieveMoreIfNeeded(suggestion_id);
 }
 
@@ -262,7 +263,7 @@
 void DownloadSuggestionsProvider::ClearDismissedSuggestionsForDebugging(
     Category category) {
   DCHECK_EQ(provided_category_, category);
-  StoreAssetDismissedIDsToPrefs(std::set<std::string>());
+  StoreAssetDismissedIDsToPrefs(std::vector<std::string>());
   StoreOfflinePageDismissedIDsToPrefs(std::set<std::string>());
   AsynchronouslyFetchAllDownloadsAndSubmitSuggestions();
 }
@@ -274,6 +275,10 @@
   registry->RegisterListPref(kDismissedOfflinePageDownloadSuggestions);
 }
 
+int DownloadSuggestionsProvider::GetMaxDismissedCountForTesting() {
+  return kMaxDismissedIdCount;
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // Private methods
 
@@ -281,10 +286,12 @@
     GetPagesMatchingQueryCallbackForGetDismissedSuggestions(
         const ntp_snippets::DismissedSuggestionsCallback& callback,
         const std::vector<OfflinePageItem>& offline_pages) const {
-  std::set<std::string> dismissed_ids = ReadOfflinePageDismissedIDsFromPrefs();
+  std::set<std::string> dismissed_offline_ids =
+      ReadOfflinePageDismissedIDsFromPrefs();
   std::vector<ContentSuggestion> suggestions;
   for (const OfflinePageItem& item : offline_pages) {
-    if (dismissed_ids.count(GetOfflinePagePerCategoryID(item.offline_id))) {
+    if (dismissed_offline_ids.count(
+            GetOfflinePagePerCategoryID(item.offline_id))) {
       suggestions.push_back(ConvertOfflinePage(item));
     }
   }
@@ -293,10 +300,12 @@
     std::vector<DownloadItem*> all_downloads;
     download_manager_->GetAllDownloads(&all_downloads);
 
-    dismissed_ids = ReadAssetDismissedIDsFromPrefs();
+    std::vector<std::string> dismissed_asset_ids =
+        ReadAssetDismissedIDsFromPrefs();
 
     for (const DownloadItem* item : all_downloads) {
-      if (dismissed_ids.count(GetAssetDownloadPerCategoryID(item->GetId()))) {
+      if (ContainsValue(dismissed_asset_ids,
+                        GetAssetDownloadPerCategoryID(item->GetId()))) {
         suggestions.push_back(ConvertDownloadItem(*item));
       }
     }
@@ -369,7 +378,7 @@
 }
 
 void DownloadSuggestionsProvider::OnDownloadUpdated(DownloadItem* item) {
-  if (base::ContainsValue(cached_asset_downloads_, item)) {
+  if (ContainsValue(cached_asset_downloads_, item)) {
     if (item->GetFileExternallyRemoved()) {
       InvalidateSuggestion(GetAssetDownloadPerCategoryID(item->GetId()));
     } else {
@@ -450,25 +459,23 @@
 
   std::vector<DownloadItem*> all_downloads;
   download_manager_->GetAllDownloads(&all_downloads);
-  std::set<std::string> old_dismissed_ids = ReadAssetDismissedIDsFromPrefs();
-  std::set<std::string> retained_dismissed_ids;
+  std::vector<std::string> old_dismissed_ids = ReadAssetDismissedIDsFromPrefs();
   cached_asset_downloads_.clear();
   for (const DownloadItem* item : all_downloads) {
     std::string within_category_id =
         GetAssetDownloadPerCategoryID(item->GetId());
-    if (!old_dismissed_ids.count(within_category_id)) {
+    if (!ContainsValue(old_dismissed_ids, within_category_id)) {
       if (IsDownloadCompleted(*item)) {
         cached_asset_downloads_.push_back(item);
       }
-    } else {
-      retained_dismissed_ids.insert(within_category_id);
     }
   }
 
-  if (old_dismissed_ids.size() != retained_dismissed_ids.size()) {
-    StoreAssetDismissedIDsToPrefs(retained_dismissed_ids);
-  }
-
+  // We do not prune dismissed IDs, because it is not possible to ensure that
+  // the list of downloads is complete (i.e. DownloadManager has finished
+  // reading them).
+  // TODO(vitaliii): Prune dismissed IDs once the |OnLoaded| notification is
+  // provided. See crbug.com/672758.
   const int max_suggestions_count = GetMaxSuggestionsCount();
   if (static_cast<int>(cached_asset_downloads_.size()) >
       max_suggestions_count) {
@@ -566,12 +573,13 @@
     return false;
   }
 
-  if (base::ContainsValue(cached_asset_downloads_, item)) {
+  if (ContainsValue(cached_asset_downloads_, item)) {
     return false;
   }
 
-  std::set<std::string> dismissed_ids = ReadAssetDismissedIDsFromPrefs();
-  if (dismissed_ids.count(GetAssetDownloadPerCategoryID(item->GetId()))) {
+  std::vector<std::string> dismissed_ids = ReadAssetDismissedIDsFromPrefs();
+  if (ContainsValue(dismissed_ids,
+                    GetAssetDownloadPerCategoryID(item->GetId()))) {
     return false;
   }
 
@@ -709,31 +717,38 @@
   ContentSuggestion::ID suggestion_id(provided_category_, id_within_category);
   observer()->OnSuggestionInvalidated(this, suggestion_id);
 
-  std::set<std::string> dismissed_ids =
-      ReadDismissedIDsFromPrefs(CorrespondsToOfflinePage(suggestion_id));
-  auto it = dismissed_ids.find(id_within_category);
-  if (it != dismissed_ids.end()) {
-    dismissed_ids.erase(it);
-    StoreDismissedIDsToPrefs(CorrespondsToOfflinePage(suggestion_id),
-                             dismissed_ids);
-  }
-
+  RemoveFromDismissedStorageIfNeeded(suggestion_id);
   RemoveSuggestionFromCacheAndRetrieveMoreIfNeeded(suggestion_id);
 }
 
-std::set<std::string>
+// TODO(vitaliii): Do not use std::vector, when we ensure that pruning happens
+// at the right time (crbug.com/672758).
+std::vector<std::string>
 DownloadSuggestionsProvider::ReadAssetDismissedIDsFromPrefs() const {
-  return ntp_snippets::prefs::ReadDismissedIDsFromPrefs(
-      *pref_service_, kDismissedAssetDownloadSuggestions);
+  std::vector<std::string> dismissed_ids;
+  const base::ListValue* list =
+      pref_service_->GetList(kDismissedAssetDownloadSuggestions);
+  for (const std::unique_ptr<base::Value>& value : *list) {
+    std::string dismissed_id;
+    bool success = value->GetAsString(&dismissed_id);
+    DCHECK(success) << "Failed to parse dismissed id from prefs param "
+                    << kDismissedAssetDownloadSuggestions << " into string.";
+    dismissed_ids.push_back(dismissed_id);
+  }
+  return dismissed_ids;
 }
 
 void DownloadSuggestionsProvider::StoreAssetDismissedIDsToPrefs(
-    const std::set<std::string>& dismissed_ids) {
+    const std::vector<std::string>& dismissed_ids) {
   DCHECK(std::all_of(
       dismissed_ids.begin(), dismissed_ids.end(),
       [](const std::string& id) { return id[0] == kAssetDownloadsPrefix; }));
-  ntp_snippets::prefs::StoreDismissedIDsToPrefs(
-      pref_service_, kDismissedAssetDownloadSuggestions, dismissed_ids);
+
+  base::ListValue list;
+  for (const std::string& dismissed_id : dismissed_ids) {
+    list.AppendString(dismissed_id);
+  }
+  pref_service_->Set(kDismissedAssetDownloadSuggestions, list);
 }
 
 std::set<std::string>
@@ -752,22 +767,45 @@
       pref_service_, kDismissedOfflinePageDownloadSuggestions, dismissed_ids);
 }
 
-std::set<std::string> DownloadSuggestionsProvider::ReadDismissedIDsFromPrefs(
-    bool for_offline_page_downloads) const {
-  if (for_offline_page_downloads) {
-    return ReadOfflinePageDismissedIDsFromPrefs();
-  }
-  return ReadAssetDismissedIDsFromPrefs();
-}
-
-// TODO(vitaliii): Store one set instead of two. See crbug.com/656024.
-void DownloadSuggestionsProvider::StoreDismissedIDsToPrefs(
-    bool for_offline_page_downloads,
-    const std::set<std::string>& dismissed_ids) {
-  if (for_offline_page_downloads) {
+void DownloadSuggestionsProvider::AddToDismissedStorageIfNeeded(
+    const ContentSuggestion::ID& suggestion_id) {
+  if (CorrespondsToOfflinePage(suggestion_id)) {
+    std::set<std::string> dismissed_ids =
+        ReadOfflinePageDismissedIDsFromPrefs();
+    dismissed_ids.insert(suggestion_id.id_within_category());
     StoreOfflinePageDismissedIDsToPrefs(dismissed_ids);
   } else {
-    StoreAssetDismissedIDsToPrefs(dismissed_ids);
+    std::vector<std::string> dismissed_ids = ReadAssetDismissedIDsFromPrefs();
+    // The suggestion may be double dismissed from previously opened NTPs.
+    if (!ContainsValue(dismissed_ids, suggestion_id.id_within_category())) {
+      dismissed_ids.push_back(suggestion_id.id_within_category());
+      // TODO(vitaliii): Remove this workaround once the dismissed ids are
+      // pruned. See crbug.com/672758.
+      while (dismissed_ids.size() > kMaxDismissedIdCount) {
+        dismissed_ids.erase(dismissed_ids.begin());
+      }
+      StoreAssetDismissedIDsToPrefs(dismissed_ids);
+    }
+  }
+}
+
+void DownloadSuggestionsProvider::RemoveFromDismissedStorageIfNeeded(
+    const ContentSuggestion::ID& suggestion_id) {
+  if (CorrespondsToOfflinePage(suggestion_id)) {
+    std::set<std::string> dismissed_ids =
+        ReadOfflinePageDismissedIDsFromPrefs();
+    if (dismissed_ids.count(suggestion_id.id_within_category())) {
+      dismissed_ids.erase(suggestion_id.id_within_category());
+      StoreOfflinePageDismissedIDsToPrefs(dismissed_ids);
+    }
+  } else {
+    std::vector<std::string> dismissed_ids = ReadAssetDismissedIDsFromPrefs();
+    auto it = std::find(dismissed_ids.begin(), dismissed_ids.end(),
+                        suggestion_id.id_within_category());
+    if (it != dismissed_ids.end()) {
+      dismissed_ids.erase(it);
+      StoreAssetDismissedIDsToPrefs(dismissed_ids);
+    }
   }
 }
 
diff --git a/chrome/browser/ntp_snippets/download_suggestions_provider.h b/chrome/browser/ntp_snippets/download_suggestions_provider.h
index 9b7cdb2..a98dc97 100644
--- a/chrome/browser/ntp_snippets/download_suggestions_provider.h
+++ b/chrome/browser/ntp_snippets/download_suggestions_provider.h
@@ -75,6 +75,8 @@
 
   static void RegisterProfilePrefs(PrefRegistrySimple* registry);
 
+  static int GetMaxDismissedCountForTesting();
+
  private:
   friend class DownloadSuggestionsProviderTest;
 
@@ -171,11 +173,11 @@
   void InvalidateSuggestion(const std::string& id_within_category);
 
   // Reads dismissed IDs related to asset downloads from prefs.
-  std::set<std::string> ReadAssetDismissedIDsFromPrefs() const;
+  std::vector<std::string> ReadAssetDismissedIDsFromPrefs() const;
 
   // Writes |dismissed_ids| into prefs for asset downloads.
   void StoreAssetDismissedIDsToPrefs(
-      const std::set<std::string>& dismissed_ids);
+      const std::vector<std::string>& dismissed_ids);
 
   // Reads dismissed IDs related to offline page downloads from prefs.
   std::set<std::string> ReadOfflinePageDismissedIDsFromPrefs() const;
@@ -184,15 +186,15 @@
   void StoreOfflinePageDismissedIDsToPrefs(
       const std::set<std::string>& dismissed_ids);
 
-  // Reads from prefs dismissed IDs related to either offline page or asset
-  // downloads (given by |for_offline_page_downloads|).
-  std::set<std::string> ReadDismissedIDsFromPrefs(
-      bool for_offline_page_downloads) const;
+  // Adds a suggestion ID to the dismissed list in prefs, if it is not there.
+  // Works for both Offline Page and Asset downloads.
+  void AddToDismissedStorageIfNeeded(
+      const ntp_snippets::ContentSuggestion::ID& suggestion_id);
 
-  // Writes |dismissed_ids| into prefs for either offline page or asset
-  // downloads (given by |for_offline_page_downloads|).
-  void StoreDismissedIDsToPrefs(bool for_offline_page_downloads,
-                                const std::set<std::string>& dismissed_ids);
+  // Removes a suggestion ID from the dismissed list in prefs, if it is there.
+  // Works for both Offline Page and Asset downloads.
+  void RemoveFromDismissedStorageIfNeeded(
+      const ntp_snippets::ContentSuggestion::ID& suggestion_id);
 
   void UnregisterDownloadItemObservers();
 
diff --git a/chrome/browser/ntp_snippets/download_suggestions_provider_unittest.cc b/chrome/browser/ntp_snippets/download_suggestions_provider_unittest.cc
index c68d1d3c..90f654f 100644
--- a/chrome/browser/ntp_snippets/download_suggestions_provider_unittest.cc
+++ b/chrome/browser/ntp_snippets/download_suggestions_provider_unittest.cc
@@ -38,12 +38,12 @@
 using testing::AnyNumber;
 using testing::ElementsAre;
 using testing::IsEmpty;
+using testing::Lt;
 using testing::Mock;
 using testing::Return;
 using testing::SizeIs;
 using testing::StrictMock;
 using testing::UnorderedElementsAre;
-using testing::Lt;
 
 namespace ntp_snippets {
 // These functions are implicitly used to print out values during the tests.
@@ -926,3 +926,87 @@
                                             HasUrl("http://download.com/2"))));
   CreateProvider(/*show_assets=*/true, /*show_offline_pages=*/false);
 }
+
+TEST_F(DownloadSuggestionsProviderTest,
+       ShouldNotPruneDismissedSuggestionsOnStartup) {
+  IgnoreOnCategoryStatusChangedToAvailable();
+  IgnoreOnSuggestionInvalidated();
+
+  // We dismiss an item to store it in the list of dismissed items.
+  *(downloads_manager()->mutable_items()) = CreateDummyAssetDownloads({1});
+  EXPECT_CALL(*observer(), OnNewSuggestions(_, downloads_category(), _));
+  CreateProvider(/*show_assets=*/true, /*show_offline_pages=*/false);
+  provider()->DismissSuggestion(
+      GetDummySuggestionId(1, /*is_offline_page=*/false));
+  DestroyProvider();
+
+  // We simulate current DownloadManager behaviour;
+  // The download manager has not started reading the list yet, so it is empty.
+  downloads_manager()->mutable_items()->clear();
+  EXPECT_CALL(*observer(), OnNewSuggestions(_, downloads_category(), _));
+  CreateProvider(/*show_assets=*/true, /*show_offline_pages=*/false);
+  Mock::VerifyAndClearExpectations(observer());
+
+  // The first download is being read.
+  *(downloads_manager()->mutable_items()) = CreateDummyAssetDownloads({1});
+  EXPECT_CALL(*observer(), OnNewSuggestions(_, downloads_category(), _))
+      .Times(0);
+  FireDownloadCreated(downloads_manager()->items()[0].get());
+  // The first download should not be reported, because it is dismissed.
+}
+
+TEST_F(DownloadSuggestionsProviderTest, ShouldStoreDismissedSuggestions) {
+  IgnoreOnCategoryStatusChangedToAvailable();
+  IgnoreOnSuggestionInvalidated();
+
+  // Dismiss items to store them in the list of dismissed items.
+  *(offline_pages_model()->mutable_items()) = CreateDummyOfflinePages({1});
+  *(downloads_manager()->mutable_items()) = CreateDummyAssetDownloads({1});
+  EXPECT_CALL(*observer(), OnNewSuggestions(_, downloads_category(), _));
+  CreateProvider(/*show_assets=*/true, /*show_offline_pages=*/true);
+  provider()->DismissSuggestion(
+      GetDummySuggestionId(1, /*is_offline_page=*/true));
+  provider()->DismissSuggestion(
+      GetDummySuggestionId(1, /*is_offline_page=*/false));
+  // Destroy and create provider to simulate turning off Chrome.
+  DestroyProvider();
+
+  EXPECT_CALL(*observer(), OnNewSuggestions(_, downloads_category(), _));
+  CreateProvider(/*show_assets=*/true, /*show_offline_pages=*/true);
+  EXPECT_THAT(GetDismissedSuggestions(),
+              UnorderedElementsAre(HasUrl("http://dummy.com/1"),
+                                   HasUrl("http://download.com/1")));
+}
+
+// TODO(vitaliii): Remove this test once the dismissed ids are pruned. See
+// crbug.com/672758.
+TEST_F(DownloadSuggestionsProviderTest, ShouldRemoveOldDismissedIdsIfTooMany) {
+  IgnoreOnCategoryStatusChangedToAvailable();
+  IgnoreOnSuggestionInvalidated();
+
+  const int kMaxDismissedIdCount =
+      DownloadSuggestionsProvider::GetMaxDismissedCountForTesting();
+  std::vector<int> ids;
+  for (int i = 0; i < kMaxDismissedIdCount + 1; ++i) {
+    ids.push_back(i);
+  }
+
+  *(downloads_manager()->mutable_items()) = CreateDummyAssetDownloads(ids);
+  EXPECT_CALL(*observer(), OnNewSuggestions(_, downloads_category(), _));
+  CreateProvider(/*show_assets=*/true, /*show_offline_pages=*/false);
+
+  for (int i = 0; i < static_cast<int>(ids.size()); ++i) {
+    provider()->DismissSuggestion(
+        GetDummySuggestionId(i, /*is_offline_page=*/false));
+  }
+
+  EXPECT_THAT(GetDismissedSuggestions(), SizeIs(kMaxDismissedIdCount));
+  DestroyProvider();
+  // The oldest dismissed suggestion must become undismissed now. This is a
+  // temporary workaround and not what we want in long term. This test must be
+  // removed once we start pruning dismissed asset downloads on startup.
+  EXPECT_CALL(*observer(),
+              OnNewSuggestions(_, downloads_category(),
+                               ElementsAre(HasUrl("http://download.com/0"))));
+  CreateProvider(/*show_assets=*/true, /*show_offline_pages=*/false);
+}
diff --git a/chrome/browser/predictors/resource_prefetch_predictor_browsertest.cc b/chrome/browser/predictors/resource_prefetch_predictor_browsertest.cc
index c47ea93c..3016a1e 100644
--- a/chrome/browser/predictors/resource_prefetch_predictor_browsertest.cc
+++ b/chrome/browser/predictors/resource_prefetch_predictor_browsertest.cc
@@ -112,6 +112,19 @@
   navigation_id->main_frame_url = GURL("http://127.0.0.1");
 }
 
+void ModifySubresourceForComparison(URLRequestSummary* subresource,
+                                    bool match_navigation_id) {
+  if (!match_navigation_id)
+    SetValidNavigationID(&subresource->navigation_id);
+  if (subresource->resource_type == content::RESOURCE_TYPE_IMAGE &&
+      subresource->priority == net::LOWEST) {
+    // Fuzzy comparison for images because an image priority can be
+    // boosted during layout via
+    // ResourceFetcher::updateAllImageResourcePriorities().
+    subresource->priority = net::MEDIUM;
+  }
+}
+
 // Does a custom comparison of subresources of URLRequestSummary
 // and fail the test if the expectation is not met.
 void CompareSubresources(std::vector<URLRequestSummary> actual_subresources,
@@ -121,12 +134,11 @@
   // ResourcePrefetchPredictor only cares about the first occurrence of each.
   RemoveDuplicateSubresources(&actual_subresources);
 
-  if (!match_navigation_id) {
-    for (auto& subresource : actual_subresources)
-      SetValidNavigationID(&subresource.navigation_id);
-    for (auto& subresource : expected_subresources)
-      SetValidNavigationID(&subresource.navigation_id);
-  }
+  for (auto& subresource : actual_subresources)
+    ModifySubresourceForComparison(&subresource, match_navigation_id);
+  for (auto& subresource : expected_subresources)
+    ModifySubresourceForComparison(&subresource, match_navigation_id);
+
   EXPECT_THAT(actual_subresources,
               testing::UnorderedElementsAreArray(expected_subresources));
 }
@@ -456,8 +468,9 @@
   NavigateToURLAndCheckSubresources(GetURL(kHtmlDocumentWritePath));
 }
 
+// Disabled due to flakiness (crbug.com/673028).
 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest,
-                       LearningJavascriptAppendChild) {
+                       DISABLED_LearningJavascriptAppendChild) {
   auto externalScript =
       AddExternalResource(GetURL(kScriptAppendChildPath),
                           content::RESOURCE_TYPE_SCRIPT, net::MEDIUM);
diff --git a/chrome/browser/prefs/chrome_pref_service_factory.cc b/chrome/browser/prefs/chrome_pref_service_factory.cc
index 0c761e6..0b72728 100644
--- a/chrome/browser/prefs/chrome_pref_service_factory.cc
+++ b/chrome/browser/prefs/chrome_pref_service_factory.cc
@@ -59,6 +59,7 @@
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_thread.h"
 #include "extensions/features/features.h"
+#include "rlz/features/features.h"
 #include "sql/error_delegate_util.h"
 #include "ui/base/resource/resource_bundle.h"
 
@@ -72,9 +73,9 @@
 
 #if defined(OS_WIN)
 #include "base/win/win_util.h"
-#if defined(ENABLE_RLZ)
+#if BUILDFLAG(ENABLE_RLZ)
 #include "rlz/lib/machine_id.h"
-#endif  // defined(ENABLE_RLZ)
+#endif  // BUILDFLAG(ENABLE_RLZ)
 #endif  // defined(OS_WIN)
 
 using content::BrowserContext;
@@ -399,7 +400,7 @@
 std::unique_ptr<ProfilePrefStoreManager> CreateProfilePrefStoreManager(
     const base::FilePath& profile_path) {
   std::string device_id;
-#if defined(OS_WIN) && defined(ENABLE_RLZ)
+#if defined(OS_WIN) && BUILDFLAG(ENABLE_RLZ)
   // This is used by
   // chrome/browser/extensions/api/music_manager_private/device_id_win.cc
   // but that API is private (http://crbug.com/276485) and other platforms are
diff --git a/chrome/browser/renderer_host/pepper/device_id_fetcher.cc b/chrome/browser/renderer_host/pepper/device_id_fetcher.cc
index fabd784e..ddca7f8 100644
--- a/chrome/browser/renderer_host/pepper/device_id_fetcher.cc
+++ b/chrome/browser/renderer_host/pepper/device_id_fetcher.cc
@@ -11,9 +11,6 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/common/pref_names.h"
 #include "components/prefs/pref_service.h"
-#if defined(OS_CHROMEOS)
-#include "chromeos/cryptohome/system_salt_getter.h"
-#endif
 #include "components/pref_registry/pref_registry_syncable.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_ppapi_host.h"
@@ -23,7 +20,13 @@
 #include "crypto/random.h"
 #include "crypto/sha2.h"
 #include "ppapi/c/pp_errors.h"
-#if defined(ENABLE_RLZ)
+#include "rlz/features/features.h"
+
+#if defined(OS_CHROMEOS)
+#include "chromeos/cryptohome/system_salt_getter.h"
+#endif
+
+#if BUILDFLAG(ENABLE_RLZ)
 #include "rlz/lib/machine_id.h"
 #endif
 
@@ -41,7 +44,7 @@
 
 void GetMachineIDAsync(
     const base::Callback<void(const std::string&)>& callback) {
-#if defined(OS_WIN) && defined(ENABLE_RLZ)
+#if defined(OS_WIN) && BUILDFLAG(ENABLE_RLZ)
   std::string result;
   rlz_lib::GetMachineId(&result);
   callback.Run(result);
diff --git a/chrome/browser/resources/bluetooth_internals/adapter_broker.js b/chrome/browser/resources/bluetooth_internals/adapter_broker.js
index 7aab614..c1cf8fa 100644
--- a/chrome/browser/resources/bluetooth_internals/adapter_broker.js
+++ b/chrome/browser/resources/bluetooth_internals/adapter_broker.js
@@ -46,7 +46,7 @@
         }
 
         return interfaces.Connection.bindHandleToProxy(
-            response.device,
+            response.device.ptr.passInterface().handle,
             interfaces.BluetoothDevice.Device);
       });
     },
@@ -56,8 +56,12 @@
      * @param {!interfaces.BluetoothAdapter.AdapterClient} adapterClient
      */
     setClient: function(adapterClient) {
-      this.adapter_.setClient(interfaces.Connection.bindStubDerivedImpl(
-          adapterClient));
+      adapterClient.binding = new interfaces.Bindings.Binding(
+          interfaces.BluetoothAdapter.AdapterClient,
+          adapterClient);
+
+      this.adapter_.setClient(
+          adapterClient.binding.createInterfacePtrAndBind());
     },
 
     /**
@@ -153,12 +157,12 @@
       // Get an Adapter service.
       return adapterFactory.getAdapter();
     }).then(function(response) {
-      if (!response.adapter) {
+      if (!response.adapter.ptr.isBound()) {
         throw new Error('Bluetooth Not Supported on this platform.');
       }
 
       var adapter = interfaces.Connection.bindHandleToProxy(
-          response.adapter,
+          response.adapter.ptr.passInterface().handle,
           interfaces.BluetoothAdapter.Adapter);
 
       adapterBroker = new AdapterBroker(adapter);
diff --git a/chrome/browser/resources/bluetooth_internals/interfaces.js b/chrome/browser/resources/bluetooth_internals/interfaces.js
index 063cbe7..0bbe9cb 100644
--- a/chrome/browser/resources/bluetooth_internals/interfaces.js
+++ b/chrome/browser/resources/bluetooth_internals/interfaces.js
@@ -25,11 +25,13 @@
         'content/public/renderer/frame_interfaces',
         'device/bluetooth/public/interfaces/adapter.mojom',
         'device/bluetooth/public/interfaces/device.mojom',
+        'mojo/public/js/bindings',
         'mojo/public/js/connection',
       ]).then(function([frameInterfaces, bluetoothAdapter, bluetoothDevice,
-          connection]) {
+          bindings, connection]) {
         interfaces.BluetoothAdapter = bluetoothAdapter;
         interfaces.BluetoothDevice = bluetoothDevice;
+        interfaces.Bindings = bindings;
         interfaces.Connection = connection;
         interfaces.FrameInterfaces = frameInterfaces;
       });
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/background_test.extjs b/chrome/browser/resources/chromeos/chromevox/cvox2/background/background_test.extjs
index 99c957d..1fab64c 100644
--- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/background_test.extjs
+++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/background_test.extjs
@@ -997,7 +997,7 @@
     };
 
     mockFeedback.call(doCmd('nextEditText'))
-        .expectSpeech('Top News')
+        .expectSpeech('Top News Most Popular Sports')
         .call(doCmd('nextHeading'))
         .expectSpeech('Top News')
         .call(assertRangeHasText('Top News'))
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/live_regions.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/live_regions.js
index 29a9c6f..7c0eb03 100644
--- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/live_regions.js
+++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/live_regions.js
@@ -134,6 +134,10 @@
       return;
     }
 
+    // Alerts should be announced as a result of focus.
+    if (node.role == RoleType.alert)
+      return;
+
     var range = cursors.Range.fromNode(node);
     var output = new Output();
     if (opt_prependFormatStr)
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/live_regions_test.extjs b/chrome/browser/resources/chromeos/chromevox/cvox2/background/live_regions_test.extjs
index d2bc87d..88d7d53a 100644
--- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/live_regions_test.extjs
+++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/live_regions_test.extjs
@@ -109,9 +109,7 @@
     function(rootNode) {
       var go = rootNode.find({ role: RoleType.button });
       mockFeedback.call(go.doDefault.bind(go))
-          .expectCategoryFlushSpeech('Alpha')
-          .expectQueuedSpeech('Bravo')
-          .expectQueuedSpeech('Charlie');
+          .expectCategoryFlushSpeech('Alpha Bravo Charlie')
       mockFeedback.replay();
     });
 });
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js
index bb8767b..1d12d9d 100644
--- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js
+++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js
@@ -397,11 +397,12 @@
       leave: '@exited_container($role)'
     },
     alert: {
-      speak: '$earcon(ALERT_NONMODAL) $role $descendants $state'
+      enter: '$name $role $state',
+      speak: '$earcon(ALERT_NONMODAL) $role $nameOrTextContent $state'
     },
     alertDialog: {
       enter: '$earcon(ALERT_MODAL) $name $state',
-      speak: '$earcon(ALERT_MODAL) $name $descendants $state $role'
+      speak: '$earcon(ALERT_MODAL) $name $nameOrTextContent $state $role'
     },
     cell: {
       enter: '@cell_summary($tableCellRowIndex, $tableCellColumnIndex) ' +
@@ -524,7 +525,7 @@
       enter: '$node(tableRowHeader)'
     },
     rowHeader: {
-      speak: '$descendants $state'
+      speak: '$nameOrTextContent $state'
     },
     slider: {
       speak: '$earcon(SLIDER) @describe_slider($value, $name) $description ' +
@@ -547,7 +548,7 @@
           '$node(tableHeader)'
     },
     tableHeaderContainer: {
-      speak: '$descendants $state $description'
+      speak: '$nameOrTextContent $state $description'
     },
     textField: {
       speak: '$name $value $if($multiline, @tag_textarea, $if(' +
@@ -601,7 +602,7 @@
   alert: {
     default: {
       speak: '$earcon(ALERT_NONMODAL) @role_alert ' +
-          '$if($name, $name, $descendants) $description'
+          '$nameOrTextContent $description'
     }
   }
 };
@@ -1236,11 +1237,14 @@
                 Dir.FORWARD,
                 {visit: AutomationPredicate.leafOrStaticText,
                  leaf: AutomationPredicate.leafOrStaticText});
+            var outputStrings = [];
             while (walker.next().node &&
                 walker.phase == AutomationTreeWalkerPhase.DESCENDANT) {
               if (walker.node.name)
-                this.append_(buff, walker.node.name, options);
+                outputStrings.push(walker.node.name);
             }
+            var joinedOutput = outputStrings.join(' ');
+            this.append_(buff, joinedOutput, options);
           }
         } else if (node[token] !== undefined) {
           options.annotation.push(token);
diff --git a/chrome/browser/resources/chromeos/login/lock.js b/chrome/browser/resources/chromeos/login/lock.js
index ad5919ce..4028f54 100644
--- a/chrome/browser/resources/chromeos/login/lock.js
+++ b/chrome/browser/resources/chromeos/login/lock.js
@@ -66,6 +66,39 @@
       chrome.send('screenStateInitialize');
     },
 
+    /**
+     * Notification from the host that the PIN keyboard will be used in the
+     * lock session so it should also get preloaded.
+     */
+    preloadPinKeyboard: function() {
+      showPinKeyboardAsync();
+    },
+
+    /**
+     * Called when a preloaded webview (this) instance is being reused to
+     * display a new lock screen session. This will also be called when a
+     * lock screen has been preloaded and is being displayed for the first
+     * time.
+     */
+    reload: function() {
+      // Sending accountPickerReady displays the webui. Wait for the next
+      // animation frame so the user does not see any state from the previous
+      // instance.
+      requestAnimationFrame(function() {
+        chrome.send('accountPickerReady');
+      });
+    },
+
+    /**
+     * Called when the lock screen has been dismissed but this webview will stay
+     * in memory. The webview will be reused when Oobe.reload() is called.
+     */
+    teardown: function() {
+      // The PIN keyboard will disable the virtual keyboard. Make sure to
+      // revert the force disable when hiding the lock screen.
+      chrome.send('setForceDisableVirtualKeyboard', [false]);
+    },
+
     // Dummy Oobe functions not present with stripped login UI.
     initializeA11yMenu: function(e) {},
     handleAccessibilityLinkClick: function(e) {},
diff --git a/chrome/browser/resources/md_history/app.crisper.js b/chrome/browser/resources/md_history/app.crisper.js
index a5a250e..299b3ab 100644
--- a/chrome/browser/resources/md_history/app.crisper.js
+++ b/chrome/browser/resources/md_history/app.crisper.js
@@ -13,13 +13,11 @@
 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
-cr.define("cr.ui",function(){function KeyboardShortcut(shortcut){var mods={};var ident="";shortcut.split("|").forEach(function(part){var partLc=part.toLowerCase();switch(partLc){case"alt":case"ctrl":case"meta":case"shift":mods[partLc+"Key"]=true;break;default:if(ident)throw Error("Invalid shortcut");ident=part}});this.ident_=ident;this.mods_=mods}KeyboardShortcut.prototype={matchesEvent:function(e){if(e.key==this.ident_){var mods=this.mods_;return["altKey","ctrlKey","metaKey","shiftKey"].every(function(k){return e[k]==!!mods[k]})}return false}};var Command=cr.ui.define("command");Command.prototype={__proto__:HTMLElement.prototype,decorate:function(){CommandManager.init(assert(this.ownerDocument));if(this.hasAttribute("shortcut"))this.shortcut=this.getAttribute("shortcut")},execute:function(opt_element){if(this.disabled)return;var doc=this.ownerDocument;if(doc.activeElement){var e=new Event("command",{bubbles:true});e.command=this;(opt_element||doc.activeElement).dispatchEvent(e)}},canExecuteChange:function(opt_node){dispatchCanExecuteEvent(this,opt_node||this.ownerDocument.activeElement)},shortcut_:"",get shortcut(){return this.shortcut_},set shortcut(shortcut){var oldShortcut=this.shortcut_;if(shortcut!==oldShortcut){this.keyboardShortcuts_=shortcut.split(/\s+/).map(function(shortcut){return new KeyboardShortcut(shortcut)});this.shortcut_=shortcut;cr.dispatchPropertyChange(this,"shortcut",this.shortcut_,oldShortcut)}},matchesEvent:function(e){if(!this.keyboardShortcuts_)return false;return this.keyboardShortcuts_.some(function(keyboardShortcut){return keyboardShortcut.matchesEvent(e)})}};cr.defineProperty(Command,"label",cr.PropertyKind.ATTR);cr.defineProperty(Command,"disabled",cr.PropertyKind.BOOL_ATTR);cr.defineProperty(Command,"hidden",cr.PropertyKind.BOOL_ATTR);cr.defineProperty(Command,"checked",cr.PropertyKind.BOOL_ATTR);cr.defineProperty(Command,"hideShortcutText",cr.PropertyKind.BOOL_ATTR);function dispatchCanExecuteEvent(command,target){var e=new CanExecuteEvent(command);target.dispatchEvent(e);command.disabled=!e.canExecute}var commandManagers={};function CommandManager(doc){doc.addEventListener("focus",this.handleFocus_.bind(this),true);doc.addEventListener("keydown",this.handleKeyDown_.bind(this),false)}CommandManager.init=function(doc){var uid=cr.getUid(doc);if(!(uid in commandManagers)){commandManagers[uid]=new CommandManager(doc)}};CommandManager.prototype={handleFocus_:function(e){var target=e.target;if(target.menu||target.command)return;var commands=Array.prototype.slice.call(target.ownerDocument.querySelectorAll("command"));commands.forEach(function(command){dispatchCanExecuteEvent(command,target)})},handleKeyDown_:function(e){var target=e.target;var commands=Array.prototype.slice.call(target.ownerDocument.querySelectorAll("command"));for(var i=0,command;command=commands[i];i++){if(command.matchesEvent(e)){command.canExecuteChange();if(!command.disabled){e.preventDefault();e.stopPropagation();command.execute();return}}}}};function CanExecuteEvent(command){var e=new Event("canExecute",{bubbles:true,cancelable:true});e.__proto__=CanExecuteEvent.prototype;e.command=command;return e}CanExecuteEvent.prototype={__proto__:Event.prototype,command:null,canExecute_:false,get canExecute(){return this.canExecute_},set canExecute(canExecute){this.canExecute_=!!canExecute;this.stopPropagation();this.preventDefault()}};return{Command:Command,CanExecuteEvent:CanExecuteEvent}});Polymer({is:"iron-media-query",properties:{queryMatches:{type:Boolean,value:false,readOnly:true,notify:true},query:{type:String,observer:"queryChanged"},full:{type:Boolean,value:false},_boundMQHandler:{value:function(){return this.queryHandler.bind(this)}},_mq:{value:null}},attached:function(){this.style.display="none";this.queryChanged()},detached:function(){this._remove()},_add:function(){if(this._mq){this._mq.addListener(this._boundMQHandler)}},_remove:function(){if(this._mq){this._mq.removeListener(this._boundMQHandler)}this._mq=null},queryChanged:function(){this._remove();var query=this.query;if(!query){return}if(!this.full&&query[0]!=="("){query="("+query+")"}this._mq=window.matchMedia(query);this._add();this.queryHandler(this._mq)},queryHandler:function(mq){this._setQueryMatches(mq.matches)}});Polymer.IronResizableBehavior={properties:{_parentResizable:{type:Object,observer:"_parentResizableChanged"},_notifyingDescendant:{type:Boolean,value:false}},listeners:{"iron-request-resize-notifications":"_onIronRequestResizeNotifications"},created:function(){this._interestedResizables=[];this._boundNotifyResize=this.notifyResize.bind(this)},attached:function(){this.fire("iron-request-resize-notifications",null,{node:this,bubbles:true,cancelable:true});if(!this._parentResizable){window.addEventListener("resize",this._boundNotifyResize);this.notifyResize()}},detached:function(){if(this._parentResizable){this._parentResizable.stopResizeNotificationsFor(this)}else{window.removeEventListener("resize",this._boundNotifyResize)}this._parentResizable=null},notifyResize:function(){if(!this.isAttached){return}this._interestedResizables.forEach(function(resizable){if(this.resizerShouldNotify(resizable)){this._notifyDescendant(resizable)}},this);this._fireResize()},assignParentResizable:function(parentResizable){this._parentResizable=parentResizable},stopResizeNotificationsFor:function(target){var index=this._interestedResizables.indexOf(target);if(index>-1){this._interestedResizables.splice(index,1);this.unlisten(target,"iron-resize","_onDescendantIronResize")}},resizerShouldNotify:function(element){return true},_onDescendantIronResize:function(event){if(this._notifyingDescendant){event.stopPropagation();return}if(!Polymer.Settings.useShadow){this._fireResize()}},_fireResize:function(){this.fire("iron-resize",null,{node:this,bubbles:false})},_onIronRequestResizeNotifications:function(event){var target=event.path?event.path[0]:event.target;if(target===this){return}if(this._interestedResizables.indexOf(target)===-1){this._interestedResizables.push(target);this.listen(target,"iron-resize","_onDescendantIronResize")}target.assignParentResizable(this);this._notifyDescendant(target);event.stopPropagation()},_parentResizableChanged:function(parentResizable){if(parentResizable){window.removeEventListener("resize",this._boundNotifyResize)}},_notifyDescendant:function(descendant){if(!this.isAttached){return}this._notifyingDescendant=true;descendant.notifyResize();this._notifyingDescendant=false}};Polymer.IronSelection=function(selectCallback){this.selection=[];this.selectCallback=selectCallback};Polymer.IronSelection.prototype={get:function(){return this.multi?this.selection.slice():this.selection[0]},clear:function(excludes){this.selection.slice().forEach(function(item){if(!excludes||excludes.indexOf(item)<0){this.setItemSelected(item,false)}},this)},isSelected:function(item){return this.selection.indexOf(item)>=0},setItemSelected:function(item,isSelected){if(item!=null){if(isSelected!==this.isSelected(item)){if(isSelected){this.selection.push(item)}else{var i=this.selection.indexOf(item);if(i>=0){this.selection.splice(i,1)}}if(this.selectCallback){this.selectCallback(item,isSelected)}}}},select:function(item){if(this.multi){this.toggle(item)}else if(this.get()!==item){this.setItemSelected(this.get(),false);this.setItemSelected(item,true)}},toggle:function(item){this.setItemSelected(item,!this.isSelected(item))}};Polymer.IronSelectableBehavior={properties:{attrForSelected:{type:String,value:null},selected:{type:String,notify:true},selectedItem:{type:Object,readOnly:true,notify:true},activateEvent:{type:String,value:"tap",observer:"_activateEventChanged"},selectable:String,selectedClass:{type:String,value:"iron-selected"},selectedAttribute:{type:String,value:null},fallbackSelection:{type:String,value:null},items:{type:Array,readOnly:true,notify:true,value:function(){return[]}},_excludedLocalNames:{type:Object,value:function(){return{template:1}}}},observers:["_updateAttrForSelected(attrForSelected)","_updateSelected(selected)","_checkFallback(fallbackSelection)"],created:function(){this._bindFilterItem=this._filterItem.bind(this);this._selection=new Polymer.IronSelection(this._applySelection.bind(this))},attached:function(){this._observer=this._observeItems(this);this._updateItems();if(!this._shouldUpdateSelection){this._updateSelected()}this._addListener(this.activateEvent)},detached:function(){if(this._observer){Polymer.dom(this).unobserveNodes(this._observer)}this._removeListener(this.activateEvent)},indexOf:function(item){return this.items.indexOf(item)},select:function(value){this.selected=value},selectPrevious:function(){var length=this.items.length;var index=(Number(this._valueToIndex(this.selected))-1+length)%length;this.selected=this._indexToValue(index)},selectNext:function(){var index=(Number(this._valueToIndex(this.selected))+1)%this.items.length;this.selected=this._indexToValue(index)},selectIndex:function(index){this.select(this._indexToValue(index))},forceSynchronousItemUpdate:function(){this._updateItems()},get _shouldUpdateSelection(){return this.selected!=null},_checkFallback:function(){if(this._shouldUpdateSelection){this._updateSelected()}},_addListener:function(eventName){this.listen(this,eventName,"_activateHandler")},_removeListener:function(eventName){this.unlisten(this,eventName,"_activateHandler")},_activateEventChanged:function(eventName,old){this._removeListener(old);this._addListener(eventName)},_updateItems:function(){var nodes=Polymer.dom(this).queryDistributedElements(this.selectable||"*");nodes=Array.prototype.filter.call(nodes,this._bindFilterItem);this._setItems(nodes)},_updateAttrForSelected:function(){if(this._shouldUpdateSelection){this.selected=this._indexToValue(this.indexOf(this.selectedItem))}},_updateSelected:function(){this._selectSelected(this.selected)},_selectSelected:function(selected){this._selection.select(this._valueToItem(this.selected));if(this.fallbackSelection&&this.items.length&&this._selection.get()===undefined){this.selected=this.fallbackSelection}},_filterItem:function(node){return!this._excludedLocalNames[node.localName]},_valueToItem:function(value){return value==null?null:this.items[this._valueToIndex(value)]},_valueToIndex:function(value){if(this.attrForSelected){for(var i=0,item;item=this.items[i];i++){if(this._valueForItem(item)==value){return i}}}else{return Number(value)}},_indexToValue:function(index){if(this.attrForSelected){var item=this.items[index];if(item){return this._valueForItem(item)}}else{return index}},_valueForItem:function(item){var propValue=item[Polymer.CaseMap.dashToCamelCase(this.attrForSelected)];return propValue!=undefined?propValue:item.getAttribute(this.attrForSelected)},_applySelection:function(item,isSelected){if(this.selectedClass){this.toggleClass(this.selectedClass,isSelected,item)}if(this.selectedAttribute){this.toggleAttribute(this.selectedAttribute,isSelected,item)}this._selectionChange();this.fire("iron-"+(isSelected?"select":"deselect"),{item:item})},_selectionChange:function(){this._setSelectedItem(this._selection.get())},_observeItems:function(node){return Polymer.dom(node).observeNodes(function(mutation){this._updateItems();if(this._shouldUpdateSelection){this._updateSelected()}this.fire("iron-items-changed",mutation,{bubbles:false,cancelable:false})})},_activateHandler:function(e){var t=e.target;var items=this.items;while(t&&t!=this){var i=items.indexOf(t);if(i>=0){var value=this._indexToValue(i);this._itemActivate(value,t);return}t=t.parentNode}},_itemActivate:function(value,item){if(!this.fire("iron-activate",{selected:value,item:item},{cancelable:true}).defaultPrevented){this.select(value)}}};Polymer({is:"iron-pages",behaviors:[Polymer.IronResizableBehavior,Polymer.IronSelectableBehavior],properties:{activateEvent:{type:String,value:null}},observers:["_selectedPageChanged(selected)"],_selectedPageChanged:function(selected,old){this.async(this.notifyResize)}});Polymer.IronScrollTargetBehavior={properties:{scrollTarget:{type:HTMLElement,value:function(){return this._defaultScrollTarget}}},observers:["_scrollTargetChanged(scrollTarget, isAttached)"],_shouldHaveListener:true,_scrollTargetChanged:function(scrollTarget,isAttached){var eventTarget;if(this._oldScrollTarget){this._toggleScrollListener(false,this._oldScrollTarget);this._oldScrollTarget=null}if(!isAttached){return}if(scrollTarget==="document"){this.scrollTarget=this._doc}else if(typeof scrollTarget==="string"){this.scrollTarget=this.domHost?this.domHost.$[scrollTarget]:Polymer.dom(this.ownerDocument).querySelector("#"+scrollTarget)}else if(this._isValidScrollTarget()){this._boundScrollHandler=this._boundScrollHandler||this._scrollHandler.bind(this);this._oldScrollTarget=scrollTarget;this._toggleScrollListener(this._shouldHaveListener,scrollTarget)}},_scrollHandler:function scrollHandler(){},get _defaultScrollTarget(){return this._doc},get _doc(){return this.ownerDocument.documentElement},get _scrollTop(){if(this._isValidScrollTarget()){return this.scrollTarget===this._doc?window.pageYOffset:this.scrollTarget.scrollTop}return 0},get _scrollLeft(){if(this._isValidScrollTarget()){return this.scrollTarget===this._doc?window.pageXOffset:this.scrollTarget.scrollLeft}return 0},set _scrollTop(top){if(this.scrollTarget===this._doc){window.scrollTo(window.pageXOffset,top)}else if(this._isValidScrollTarget()){this.scrollTarget.scrollTop=top}},set _scrollLeft(left){if(this.scrollTarget===this._doc){window.scrollTo(left,window.pageYOffset)}else if(this._isValidScrollTarget()){this.scrollTarget.scrollLeft=left}},scroll:function(left,top){if(this.scrollTarget===this._doc){window.scrollTo(left,top)}else if(this._isValidScrollTarget()){this.scrollTarget.scrollLeft=left;this.scrollTarget.scrollTop=top}},get _scrollTargetWidth(){if(this._isValidScrollTarget()){return this.scrollTarget===this._doc?window.innerWidth:this.scrollTarget.offsetWidth}return 0},get _scrollTargetHeight(){if(this._isValidScrollTarget()){return this.scrollTarget===this._doc?window.innerHeight:this.scrollTarget.offsetHeight}return 0},_isValidScrollTarget:function(){return this.scrollTarget instanceof HTMLElement},_toggleScrollListener:function(yes,scrollTarget){if(!this._boundScrollHandler){return}var eventTarget=scrollTarget===this._doc?window:scrollTarget;if(yes){eventTarget.addEventListener("scroll",this._boundScrollHandler)}else{eventTarget.removeEventListener("scroll",this._boundScrollHandler)}},toggleScrollListener:function(yes){this._shouldHaveListener=yes;this._toggleScrollListener(yes,this.scrollTarget)}};(function(){var metaDatas={};var metaArrays={};var singleton=null;Polymer.IronMeta=Polymer({is:"iron-meta",properties:{type:{type:String,value:"default",observer:"_typeChanged"},key:{type:String,observer:"_keyChanged"},value:{type:Object,notify:true,observer:"_valueChanged"},self:{type:Boolean,observer:"_selfChanged"},list:{type:Array,notify:true}},hostAttributes:{hidden:true},factoryImpl:function(config){if(config){for(var n in config){switch(n){case"type":case"key":case"value":this[n]=config[n];break}}}},created:function(){this._metaDatas=metaDatas;this._metaArrays=metaArrays},_keyChanged:function(key,old){this._resetRegistration(old)},_valueChanged:function(value){this._resetRegistration(this.key)},_selfChanged:function(self){if(self){this.value=this}},_typeChanged:function(type){this._unregisterKey(this.key);if(!metaDatas[type]){metaDatas[type]={}}this._metaData=metaDatas[type];if(!metaArrays[type]){metaArrays[type]=[]}this.list=metaArrays[type];this._registerKeyValue(this.key,this.value)},byKey:function(key){return this._metaData&&this._metaData[key]},_resetRegistration:function(oldKey){this._unregisterKey(oldKey);this._registerKeyValue(this.key,this.value)},_unregisterKey:function(key){this._unregister(key,this._metaData,this.list)},_registerKeyValue:function(key,value){this._register(key,value,this._metaData,this.list)},_register:function(key,value,data,list){if(key&&data&&value!==undefined){data[key]=value;list.push(value)}},_unregister:function(key,data,list){if(key&&data){if(key in data){var value=data[key];delete data[key];this.arrayDelete(list,value)}}}});Polymer.IronMeta.getIronMeta=function getIronMeta(){if(singleton===null){singleton=new Polymer.IronMeta}return singleton};Polymer.IronMetaQuery=Polymer({is:"iron-meta-query",properties:{type:{type:String,value:"default",observer:"_typeChanged"},key:{type:String,observer:"_keyChanged"},value:{type:Object,notify:true,readOnly:true},list:{type:Array,notify:true}},factoryImpl:function(config){if(config){for(var n in config){switch(n){case"type":case"key":this[n]=config[n];break}}}},created:function(){this._metaDatas=metaDatas;this._metaArrays=metaArrays},_keyChanged:function(key){this._setValue(this._metaData&&this._metaData[key])},_typeChanged:function(type){this._metaData=metaDatas[type];this.list=metaArrays[type];if(this.key){this._keyChanged(this.key)}},byKey:function(key){return this._metaData&&this._metaData[key]}})})();Polymer({is:"iron-icon",properties:{icon:{type:String,observer:"_iconChanged"},theme:{type:String,observer:"_updateIcon"},src:{type:String,observer:"_srcChanged"},_meta:{value:Polymer.Base.create("iron-meta",{type:"iconset"}),observer:"_updateIcon"}},_DEFAULT_ICONSET:"icons",_iconChanged:function(icon){var parts=(icon||"").split(":");this._iconName=parts.pop();this._iconsetName=parts.pop()||this._DEFAULT_ICONSET;this._updateIcon()},_srcChanged:function(src){this._updateIcon()},_usesIconset:function(){return this.icon||!this.src},_updateIcon:function(){if(this._usesIconset()){if(this._img&&this._img.parentNode){Polymer.dom(this.root).removeChild(this._img)}if(this._iconName===""){if(this._iconset){this._iconset.removeIcon(this)}}else if(this._iconsetName&&this._meta){this._iconset=this._meta.byKey(this._iconsetName);if(this._iconset){this._iconset.applyIcon(this,this._iconName,this.theme);this.unlisten(window,"iron-iconset-added","_updateIcon")}else{this.listen(window,"iron-iconset-added","_updateIcon")}}}else{if(this._iconset){this._iconset.removeIcon(this)}if(!this._img){this._img=document.createElement("img");this._img.style.width="100%";this._img.style.height="100%";this._img.draggable=false}this._img.src=this.src;Polymer.dom(this.root).appendChild(this._img)}}});(function(){"use strict";var KEY_IDENTIFIER={"U+0008":"backspace","U+0009":"tab","U+001B":"esc","U+0020":"space","U+007F":"del"};var KEY_CODE={8:"backspace",9:"tab",13:"enter",27:"esc",33:"pageup",34:"pagedown",35:"end",36:"home",32:"space",37:"left",38:"up",39:"right",40:"down",46:"del",106:"*"};var MODIFIER_KEYS={shift:"shiftKey",ctrl:"ctrlKey",alt:"altKey",meta:"metaKey"};var KEY_CHAR=/[a-z0-9*]/;var IDENT_CHAR=/U\+/;var ARROW_KEY=/^arrow/;var SPACE_KEY=/^space(bar)?/;var ESC_KEY=/^escape$/;function transformKey(key,noSpecialChars){var validKey="";if(key){var lKey=key.toLowerCase();if(lKey===" "||SPACE_KEY.test(lKey)){validKey="space"}else if(ESC_KEY.test(lKey)){validKey="esc"}else if(lKey.length==1){if(!noSpecialChars||KEY_CHAR.test(lKey)){validKey=lKey}}else if(ARROW_KEY.test(lKey)){validKey=lKey.replace("arrow","")}else if(lKey=="multiply"){validKey="*"}else{validKey=lKey}}return validKey}function transformKeyIdentifier(keyIdent){var validKey="";if(keyIdent){if(keyIdent in KEY_IDENTIFIER){validKey=KEY_IDENTIFIER[keyIdent]}else if(IDENT_CHAR.test(keyIdent)){keyIdent=parseInt(keyIdent.replace("U+","0x"),16);validKey=String.fromCharCode(keyIdent).toLowerCase()}else{validKey=keyIdent.toLowerCase()}}return validKey}function transformKeyCode(keyCode){var validKey="";if(Number(keyCode)){if(keyCode>=65&&keyCode<=90){validKey=String.fromCharCode(32+keyCode)}else if(keyCode>=112&&keyCode<=123){validKey="f"+(keyCode-112)}else if(keyCode>=48&&keyCode<=57){validKey=String(keyCode-48)}else if(keyCode>=96&&keyCode<=105){validKey=String(keyCode-96)}else{validKey=KEY_CODE[keyCode]}}return validKey}function normalizedKeyForEvent(keyEvent,noSpecialChars){if(keyEvent.key){return transformKey(keyEvent.key,noSpecialChars)}if(keyEvent.detail&&keyEvent.detail.key){return transformKey(keyEvent.detail.key,noSpecialChars)}return transformKeyIdentifier(keyEvent.keyIdentifier)||transformKeyCode(keyEvent.keyCode)||""}function keyComboMatchesEvent(keyCombo,event){var keyEvent=normalizedKeyForEvent(event,keyCombo.hasModifiers);return keyEvent===keyCombo.key&&(!keyCombo.hasModifiers||!!event.shiftKey===!!keyCombo.shiftKey&&!!event.ctrlKey===!!keyCombo.ctrlKey&&!!event.altKey===!!keyCombo.altKey&&!!event.metaKey===!!keyCombo.metaKey)}function parseKeyComboString(keyComboString){if(keyComboString.length===1){return{combo:keyComboString,key:keyComboString,event:"keydown"}}return keyComboString.split("+").reduce(function(parsedKeyCombo,keyComboPart){var eventParts=keyComboPart.split(":");var keyName=eventParts[0];var event=eventParts[1];if(keyName in MODIFIER_KEYS){parsedKeyCombo[MODIFIER_KEYS[keyName]]=true;parsedKeyCombo.hasModifiers=true}else{parsedKeyCombo.key=keyName;parsedKeyCombo.event=event||"keydown"}return parsedKeyCombo},{combo:keyComboString.split(":").shift()})}function parseEventString(eventString){return eventString.trim().split(" ").map(function(keyComboString){return parseKeyComboString(keyComboString)})}Polymer.IronA11yKeysBehavior={properties:{keyEventTarget:{type:Object,value:function(){return this}},stopKeyboardEventPropagation:{type:Boolean,value:false},_boundKeyHandlers:{type:Array,value:function(){return[]}},_imperativeKeyBindings:{type:Object,value:function(){return{}}}},observers:["_resetKeyEventListeners(keyEventTarget, _boundKeyHandlers)"],keyBindings:{},registered:function(){this._prepKeyBindings()},attached:function(){this._listenKeyEventListeners()},detached:function(){this._unlistenKeyEventListeners()},addOwnKeyBinding:function(eventString,handlerName){this._imperativeKeyBindings[eventString]=handlerName;this._prepKeyBindings();this._resetKeyEventListeners()},removeOwnKeyBindings:function(){this._imperativeKeyBindings={};this._prepKeyBindings();this._resetKeyEventListeners()},keyboardEventMatchesKeys:function(event,eventString){var keyCombos=parseEventString(eventString);for(var i=0;i<keyCombos.length;++i){if(keyComboMatchesEvent(keyCombos[i],event)){return true}}return false},_collectKeyBindings:function(){var keyBindings=this.behaviors.map(function(behavior){return behavior.keyBindings});if(keyBindings.indexOf(this.keyBindings)===-1){keyBindings.push(this.keyBindings)}return keyBindings},_prepKeyBindings:function(){this._keyBindings={};this._collectKeyBindings().forEach(function(keyBindings){for(var eventString in keyBindings){this._addKeyBinding(eventString,keyBindings[eventString])}},this);for(var eventString in this._imperativeKeyBindings){this._addKeyBinding(eventString,this._imperativeKeyBindings[eventString])}for(var eventName in this._keyBindings){this._keyBindings[eventName].sort(function(kb1,kb2){var b1=kb1[0].hasModifiers;var b2=kb2[0].hasModifiers;return b1===b2?0:b1?-1:1})}},_addKeyBinding:function(eventString,handlerName){parseEventString(eventString).forEach(function(keyCombo){this._keyBindings[keyCombo.event]=this._keyBindings[keyCombo.event]||[];this._keyBindings[keyCombo.event].push([keyCombo,handlerName])},this)},_resetKeyEventListeners:function(){this._unlistenKeyEventListeners();if(this.isAttached){this._listenKeyEventListeners()}},_listenKeyEventListeners:function(){if(!this.keyEventTarget){return}Object.keys(this._keyBindings).forEach(function(eventName){var keyBindings=this._keyBindings[eventName];var boundKeyHandler=this._onKeyBindingEvent.bind(this,keyBindings);this._boundKeyHandlers.push([this.keyEventTarget,eventName,boundKeyHandler]);this.keyEventTarget.addEventListener(eventName,boundKeyHandler)},this)},_unlistenKeyEventListeners:function(){var keyHandlerTuple;var keyEventTarget;var eventName;var boundKeyHandler;while(this._boundKeyHandlers.length){keyHandlerTuple=this._boundKeyHandlers.pop();keyEventTarget=keyHandlerTuple[0];eventName=keyHandlerTuple[1];boundKeyHandler=keyHandlerTuple[2];keyEventTarget.removeEventListener(eventName,boundKeyHandler)}},_onKeyBindingEvent:function(keyBindings,event){if(this.stopKeyboardEventPropagation){event.stopPropagation()}if(event.defaultPrevented){return}for(var i=0;i<keyBindings.length;i++){var keyCombo=keyBindings[i][0];var handlerName=keyBindings[i][1];if(keyComboMatchesEvent(keyCombo,event)){this._triggerKeyHandler(keyCombo,handlerName,event);if(event.defaultPrevented){return}}}},_triggerKeyHandler:function(keyCombo,handlerName,keyboardEvent){var detail=Object.create(keyCombo);detail.keyboardEvent=keyboardEvent;var event=new CustomEvent(keyCombo.event,{detail:detail,cancelable:true});this[handlerName].call(this,event);if(event.defaultPrevented){keyboardEvent.preventDefault()}}}})();Polymer.IronControlState={properties:{focused:{type:Boolean,value:false,notify:true,readOnly:true,reflectToAttribute:true},disabled:{type:Boolean,value:false,notify:true,observer:"_disabledChanged",reflectToAttribute:true},_oldTabIndex:{type:Number},_boundFocusBlurHandler:{type:Function,value:function(){return this._focusBlurHandler.bind(this)}}},observers:["_changedControlState(focused, disabled)"],ready:function(){this.addEventListener("focus",this._boundFocusBlurHandler,true);this.addEventListener("blur",this._boundFocusBlurHandler,true)},_focusBlurHandler:function(event){if(event.target===this){this._setFocused(event.type==="focus")}else if(!this.shadowRoot){var target=Polymer.dom(event).localTarget;if(!this.isLightDescendant(target)){this.fire(event.type,{sourceEvent:event},{node:this,bubbles:event.bubbles,cancelable:event.cancelable})}}},_disabledChanged:function(disabled,old){this.setAttribute("aria-disabled",disabled?"true":"false");this.style.pointerEvents=disabled?"none":"";if(disabled){this._oldTabIndex=this.tabIndex;this._setFocused(false);this.tabIndex=-1;this.blur()}else if(this._oldTabIndex!==undefined){this.tabIndex=this._oldTabIndex}},_changedControlState:function(){if(this._controlStateChanged){this._controlStateChanged()}}};Polymer.IronButtonStateImpl={properties:{pressed:{type:Boolean,readOnly:true,value:false,reflectToAttribute:true,observer:"_pressedChanged"},toggles:{type:Boolean,value:false,reflectToAttribute:true},active:{type:Boolean,value:false,notify:true,reflectToAttribute:true},pointerDown:{type:Boolean,readOnly:true,value:false},receivedFocusFromKeyboard:{type:Boolean,readOnly:true},ariaActiveAttribute:{type:String,value:"aria-pressed",observer:"_ariaActiveAttributeChanged"}},listeners:{down:"_downHandler",up:"_upHandler",tap:"_tapHandler"},observers:["_detectKeyboardFocus(focused)","_activeChanged(active, ariaActiveAttribute)"],keyBindings:{"enter:keydown":"_asyncClick","space:keydown":"_spaceKeyDownHandler","space:keyup":"_spaceKeyUpHandler"},_mouseEventRe:/^mouse/,_tapHandler:function(){if(this.toggles){this._userActivate(!this.active)}else{this.active=false}},_detectKeyboardFocus:function(focused){this._setReceivedFocusFromKeyboard(!this.pointerDown&&focused)},_userActivate:function(active){if(this.active!==active){this.active=active;this.fire("change")}},_downHandler:function(event){this._setPointerDown(true);this._setPressed(true);this._setReceivedFocusFromKeyboard(false)},_upHandler:function(){this._setPointerDown(false);this._setPressed(false)},_spaceKeyDownHandler:function(event){var keyboardEvent=event.detail.keyboardEvent;var target=Polymer.dom(keyboardEvent).localTarget;if(this.isLightDescendant(target))return;keyboardEvent.preventDefault();keyboardEvent.stopImmediatePropagation();this._setPressed(true)},_spaceKeyUpHandler:function(event){var keyboardEvent=event.detail.keyboardEvent;var target=Polymer.dom(keyboardEvent).localTarget;if(this.isLightDescendant(target))return;if(this.pressed){this._asyncClick()}this._setPressed(false)},_asyncClick:function(){this.async(function(){this.click()},1)},_pressedChanged:function(pressed){this._changedButtonState()},_ariaActiveAttributeChanged:function(value,oldValue){if(oldValue&&oldValue!=value&&this.hasAttribute(oldValue)){this.removeAttribute(oldValue)}},_activeChanged:function(active,ariaActiveAttribute){if(this.toggles){this.setAttribute(this.ariaActiveAttribute,active?"true":"false")}else{this.removeAttribute(this.ariaActiveAttribute)}this._changedButtonState()},_controlStateChanged:function(){if(this.disabled){this._setPressed(false)}else{this._changedButtonState()}},_changedButtonState:function(){if(this._buttonStateChanged){this._buttonStateChanged()}}};Polymer.IronButtonState=[Polymer.IronA11yKeysBehavior,Polymer.IronButtonStateImpl];(function(){var Utility={distance:function(x1,y1,x2,y2){var xDelta=x1-x2;var yDelta=y1-y2;return Math.sqrt(xDelta*xDelta+yDelta*yDelta)},now:window.performance&&window.performance.now?window.performance.now.bind(window.performance):Date.now};function ElementMetrics(element){this.element=element;this.width=this.boundingRect.width;this.height=this.boundingRect.height;this.size=Math.max(this.width,this.height)}ElementMetrics.prototype={get boundingRect(){return this.element.getBoundingClientRect()},furthestCornerDistanceFrom:function(x,y){var topLeft=Utility.distance(x,y,0,0);var topRight=Utility.distance(x,y,this.width,0);var bottomLeft=Utility.distance(x,y,0,this.height);var bottomRight=Utility.distance(x,y,this.width,this.height);return Math.max(topLeft,topRight,bottomLeft,bottomRight)}};function Ripple(element){this.element=element;this.color=window.getComputedStyle(element).color;this.wave=document.createElement("div");this.waveContainer=document.createElement("div");this.wave.style.backgroundColor=this.color;this.wave.classList.add("wave");this.waveContainer.classList.add("wave-container");Polymer.dom(this.waveContainer).appendChild(this.wave);this.resetInteractionState()}Ripple.MAX_RADIUS=300;Ripple.prototype={get recenters(){return this.element.recenters},get center(){return this.element.center},get mouseDownElapsed(){var elapsed;if(!this.mouseDownStart){return 0}elapsed=Utility.now()-this.mouseDownStart;if(this.mouseUpStart){elapsed-=this.mouseUpElapsed}return elapsed},get mouseUpElapsed(){return this.mouseUpStart?Utility.now()-this.mouseUpStart:0},get mouseDownElapsedSeconds(){return this.mouseDownElapsed/1e3},get mouseUpElapsedSeconds(){return this.mouseUpElapsed/1e3},get mouseInteractionSeconds(){return this.mouseDownElapsedSeconds+this.mouseUpElapsedSeconds},get initialOpacity(){return this.element.initialOpacity},get opacityDecayVelocity(){return this.element.opacityDecayVelocity},get radius(){var width2=this.containerMetrics.width*this.containerMetrics.width;var height2=this.containerMetrics.height*this.containerMetrics.height;var waveRadius=Math.min(Math.sqrt(width2+height2),Ripple.MAX_RADIUS)*1.1+5;var duration=1.1-.2*(waveRadius/Ripple.MAX_RADIUS);var timeNow=this.mouseInteractionSeconds/duration;var size=waveRadius*(1-Math.pow(80,-timeNow));return Math.abs(size)},get opacity(){if(!this.mouseUpStart){return this.initialOpacity}return Math.max(0,this.initialOpacity-this.mouseUpElapsedSeconds*this.opacityDecayVelocity)},get outerOpacity(){var outerOpacity=this.mouseUpElapsedSeconds*.3;var waveOpacity=this.opacity;return Math.max(0,Math.min(outerOpacity,waveOpacity))},get isOpacityFullyDecayed(){return this.opacity<.01&&this.radius>=Math.min(this.maxRadius,Ripple.MAX_RADIUS)},get isRestingAtMaxRadius(){return this.opacity>=this.initialOpacity&&this.radius>=Math.min(this.maxRadius,Ripple.MAX_RADIUS)},get isAnimationComplete(){return this.mouseUpStart?this.isOpacityFullyDecayed:this.isRestingAtMaxRadius},get translationFraction(){return Math.min(1,this.radius/this.containerMetrics.size*2/Math.sqrt(2))},get xNow(){if(this.xEnd){return this.xStart+this.translationFraction*(this.xEnd-this.xStart)}return this.xStart},get yNow(){if(this.yEnd){return this.yStart+this.translationFraction*(this.yEnd-this.yStart)}return this.yStart},get isMouseDown(){return this.mouseDownStart&&!this.mouseUpStart},resetInteractionState:function(){this.maxRadius=0;this.mouseDownStart=0;this.mouseUpStart=0;this.xStart=0;
-
-this.yStart=0;this.xEnd=0;this.yEnd=0;this.slideDistance=0;this.containerMetrics=new ElementMetrics(this.element)},draw:function(){var scale;var translateString;var dx;var dy;this.wave.style.opacity=this.opacity;scale=this.radius/(this.containerMetrics.size/2);dx=this.xNow-this.containerMetrics.width/2;dy=this.yNow-this.containerMetrics.height/2;this.waveContainer.style.webkitTransform="translate("+dx+"px, "+dy+"px)";this.waveContainer.style.transform="translate3d("+dx+"px, "+dy+"px, 0)";this.wave.style.webkitTransform="scale("+scale+","+scale+")";this.wave.style.transform="scale3d("+scale+","+scale+",1)"},downAction:function(event){var xCenter=this.containerMetrics.width/2;var yCenter=this.containerMetrics.height/2;this.resetInteractionState();this.mouseDownStart=Utility.now();if(this.center){this.xStart=xCenter;this.yStart=yCenter;this.slideDistance=Utility.distance(this.xStart,this.yStart,this.xEnd,this.yEnd)}else{this.xStart=event?event.detail.x-this.containerMetrics.boundingRect.left:this.containerMetrics.width/2;this.yStart=event?event.detail.y-this.containerMetrics.boundingRect.top:this.containerMetrics.height/2}if(this.recenters){this.xEnd=xCenter;this.yEnd=yCenter;this.slideDistance=Utility.distance(this.xStart,this.yStart,this.xEnd,this.yEnd)}this.maxRadius=this.containerMetrics.furthestCornerDistanceFrom(this.xStart,this.yStart);this.waveContainer.style.top=(this.containerMetrics.height-this.containerMetrics.size)/2+"px";this.waveContainer.style.left=(this.containerMetrics.width-this.containerMetrics.size)/2+"px";this.waveContainer.style.width=this.containerMetrics.size+"px";this.waveContainer.style.height=this.containerMetrics.size+"px"},upAction:function(event){if(!this.isMouseDown){return}this.mouseUpStart=Utility.now()},remove:function(){Polymer.dom(this.waveContainer.parentNode).removeChild(this.waveContainer)}};Polymer({is:"paper-ripple",behaviors:[Polymer.IronA11yKeysBehavior],properties:{initialOpacity:{type:Number,value:.25},opacityDecayVelocity:{type:Number,value:.8},recenters:{type:Boolean,value:false},center:{type:Boolean,value:false},ripples:{type:Array,value:function(){return[]}},animating:{type:Boolean,readOnly:true,reflectToAttribute:true,value:false},holdDown:{type:Boolean,value:false,observer:"_holdDownChanged"},noink:{type:Boolean,value:false},_animating:{type:Boolean},_boundAnimate:{type:Function,value:function(){return this.animate.bind(this)}}},get target(){return this.keyEventTarget},keyBindings:{"enter:keydown":"_onEnterKeydown","space:keydown":"_onSpaceKeydown","space:keyup":"_onSpaceKeyup"},attached:function(){if(this.parentNode.nodeType==11){this.keyEventTarget=Polymer.dom(this).getOwnerRoot().host}else{this.keyEventTarget=this.parentNode}var keyEventTarget=this.keyEventTarget;this.listen(keyEventTarget,"up","uiUpAction");this.listen(keyEventTarget,"down","uiDownAction")},detached:function(){this.unlisten(this.keyEventTarget,"up","uiUpAction");this.unlisten(this.keyEventTarget,"down","uiDownAction");this.keyEventTarget=null},get shouldKeepAnimating(){for(var index=0;index<this.ripples.length;++index){if(!this.ripples[index].isAnimationComplete){return true}}return false},simulatedRipple:function(){this.downAction(null);this.async(function(){this.upAction()},1)},uiDownAction:function(event){if(!this.noink){this.downAction(event)}},downAction:function(event){if(this.holdDown&&this.ripples.length>0){return}var ripple=this.addRipple();ripple.downAction(event);if(!this._animating){this._animating=true;this.animate()}},uiUpAction:function(event){if(!this.noink){this.upAction(event)}},upAction:function(event){if(this.holdDown){return}this.ripples.forEach(function(ripple){ripple.upAction(event)});this._animating=true;this.animate()},onAnimationComplete:function(){this._animating=false;this.$.background.style.backgroundColor=null;this.fire("transitionend")},addRipple:function(){var ripple=new Ripple(this);Polymer.dom(this.$.waves).appendChild(ripple.waveContainer);this.$.background.style.backgroundColor=ripple.color;this.ripples.push(ripple);this._setAnimating(true);return ripple},removeRipple:function(ripple){var rippleIndex=this.ripples.indexOf(ripple);if(rippleIndex<0){return}this.ripples.splice(rippleIndex,1);ripple.remove();if(!this.ripples.length){this._setAnimating(false)}},animate:function(){if(!this._animating){return}var index;var ripple;for(index=0;index<this.ripples.length;++index){ripple=this.ripples[index];ripple.draw();this.$.background.style.opacity=ripple.outerOpacity;if(ripple.isOpacityFullyDecayed&&!ripple.isRestingAtMaxRadius){this.removeRipple(ripple)}}if(!this.shouldKeepAnimating&&this.ripples.length===0){this.onAnimationComplete()}else{window.requestAnimationFrame(this._boundAnimate)}},_onEnterKeydown:function(){this.uiDownAction();this.async(this.uiUpAction,1)},_onSpaceKeydown:function(){this.uiDownAction()},_onSpaceKeyup:function(){this.uiUpAction()},_holdDownChanged:function(newVal,oldVal){if(oldVal===undefined){return}if(newVal){this.downAction()}else{this.upAction()}}})})();Polymer.PaperRippleBehavior={properties:{noink:{type:Boolean,observer:"_noinkChanged"},_rippleContainer:{type:Object}},_buttonStateChanged:function(){if(this.focused){this.ensureRipple()}},_downHandler:function(event){Polymer.IronButtonStateImpl._downHandler.call(this,event);if(this.pressed){this.ensureRipple(event)}},ensureRipple:function(optTriggeringEvent){if(!this.hasRipple()){this._ripple=this._createRipple();this._ripple.noink=this.noink;var rippleContainer=this._rippleContainer||this.root;if(rippleContainer){Polymer.dom(rippleContainer).appendChild(this._ripple)}if(optTriggeringEvent){var domContainer=Polymer.dom(this._rippleContainer||this);var target=Polymer.dom(optTriggeringEvent).rootTarget;if(domContainer.deepContains(target)){this._ripple.uiDownAction(optTriggeringEvent)}}}},getRipple:function(){this.ensureRipple();return this._ripple},hasRipple:function(){return Boolean(this._ripple)},_createRipple:function(){return document.createElement("paper-ripple")},_noinkChanged:function(noink){if(this.hasRipple()){this._ripple.noink=noink}}};Polymer.PaperInkyFocusBehaviorImpl={observers:["_focusedChanged(receivedFocusFromKeyboard)"],_focusedChanged:function(receivedFocusFromKeyboard){if(receivedFocusFromKeyboard){this.ensureRipple()}if(this.hasRipple()){this._ripple.holdDown=receivedFocusFromKeyboard}},_createRipple:function(){var ripple=Polymer.PaperRippleBehavior._createRipple();ripple.id="ink";ripple.setAttribute("center","");ripple.classList.add("circle");return ripple}};Polymer.PaperInkyFocusBehavior=[Polymer.IronButtonState,Polymer.IronControlState,Polymer.PaperRippleBehavior,Polymer.PaperInkyFocusBehaviorImpl];Polymer({is:"paper-icon-button",hostAttributes:{role:"button",tabindex:"0"},behaviors:[Polymer.PaperInkyFocusBehavior],properties:{src:{type:String},icon:{type:String},alt:{type:String,observer:"_altChanged"}},_altChanged:function(newValue,oldValue){var label=this.getAttribute("aria-label");if(!label||oldValue==label){this.setAttribute("aria-label",newValue)}}});Polymer({is:"iron-iconset-svg",properties:{name:{type:String,observer:"_nameChanged"},size:{type:Number,value:24},rtlMirroring:{type:Boolean,value:false}},_targetIsRTL:function(target){if(target&&target.nodeType!==Node.ELEMENT_NODE){target=target.host}return target&&window.getComputedStyle(target)["direction"]==="rtl"},attached:function(){this.style.display="none"},getIconNames:function(){this._icons=this._createIconMap();return Object.keys(this._icons).map(function(n){return this.name+":"+n},this)},applyIcon:function(element,iconName){element=element.root||element;this.removeIcon(element);var svg=this._cloneIcon(iconName,this.rtlMirroring&&this._targetIsRTL(element));if(svg){var pde=Polymer.dom(element);pde.insertBefore(svg,pde.childNodes[0]);return element._svgIcon=svg}return null},removeIcon:function(element){element=element.root||element;if(element._svgIcon){Polymer.dom(element).removeChild(element._svgIcon);element._svgIcon=null}},_nameChanged:function(){new Polymer.IronMeta({type:"iconset",key:this.name,value:this});this.async(function(){this.fire("iron-iconset-added",this,{node:window})})},_createIconMap:function(){var icons=Object.create(null);Polymer.dom(this).querySelectorAll("[id]").forEach(function(icon){icons[icon.id]=icon});return icons},_cloneIcon:function(id,mirrorAllowed){this._icons=this._icons||this._createIconMap();return this._prepareSvgClone(this._icons[id],this.size,mirrorAllowed)},_prepareSvgClone:function(sourceSvg,size,mirrorAllowed){if(sourceSvg){var content=sourceSvg.cloneNode(true),svg=document.createElementNS("http://www.w3.org/2000/svg","svg"),viewBox=content.getAttribute("viewBox")||"0 0 "+size+" "+size,cssText="pointer-events: none; display: block; width: 100%; height: 100%;";if(mirrorAllowed&&content.hasAttribute("mirror-in-rtl")){cssText+="-webkit-transform:scale(-1,1);transform:scale(-1,1);"}svg.setAttribute("viewBox",viewBox);svg.setAttribute("preserveAspectRatio","xMidYMid meet");svg.style.cssText=cssText;svg.appendChild(content).removeAttribute("id");return svg}return null}});
+cr.define("cr.ui",function(){function KeyboardShortcut(shortcut){var mods={};var ident="";shortcut.split("|").forEach(function(part){var partLc=part.toLowerCase();switch(partLc){case"alt":case"ctrl":case"meta":case"shift":mods[partLc+"Key"]=true;break;default:if(ident)throw Error("Invalid shortcut");ident=part}});this.ident_=ident;this.mods_=mods}KeyboardShortcut.prototype={matchesEvent:function(e){if(e.key==this.ident_){var mods=this.mods_;return["altKey","ctrlKey","metaKey","shiftKey"].every(function(k){return e[k]==!!mods[k]})}return false}};var Command=cr.ui.define("command");Command.prototype={__proto__:HTMLElement.prototype,decorate:function(){CommandManager.init(assert(this.ownerDocument));if(this.hasAttribute("shortcut"))this.shortcut=this.getAttribute("shortcut")},execute:function(opt_element){if(this.disabled)return;var doc=this.ownerDocument;if(doc.activeElement){var e=new Event("command",{bubbles:true});e.command=this;(opt_element||doc.activeElement).dispatchEvent(e)}},canExecuteChange:function(opt_node){dispatchCanExecuteEvent(this,opt_node||this.ownerDocument.activeElement)},shortcut_:"",get shortcut(){return this.shortcut_},set shortcut(shortcut){var oldShortcut=this.shortcut_;if(shortcut!==oldShortcut){this.keyboardShortcuts_=shortcut.split(/\s+/).map(function(shortcut){return new KeyboardShortcut(shortcut)});this.shortcut_=shortcut;cr.dispatchPropertyChange(this,"shortcut",this.shortcut_,oldShortcut)}},matchesEvent:function(e){if(!this.keyboardShortcuts_)return false;return this.keyboardShortcuts_.some(function(keyboardShortcut){return keyboardShortcut.matchesEvent(e)})}};cr.defineProperty(Command,"label",cr.PropertyKind.ATTR);cr.defineProperty(Command,"disabled",cr.PropertyKind.BOOL_ATTR);cr.defineProperty(Command,"hidden",cr.PropertyKind.BOOL_ATTR);cr.defineProperty(Command,"checked",cr.PropertyKind.BOOL_ATTR);cr.defineProperty(Command,"hideShortcutText",cr.PropertyKind.BOOL_ATTR);function dispatchCanExecuteEvent(command,target){var e=new CanExecuteEvent(command);target.dispatchEvent(e);command.disabled=!e.canExecute}var commandManagers={};function CommandManager(doc){doc.addEventListener("focus",this.handleFocus_.bind(this),true);doc.addEventListener("keydown",this.handleKeyDown_.bind(this),false)}CommandManager.init=function(doc){var uid=cr.getUid(doc);if(!(uid in commandManagers)){commandManagers[uid]=new CommandManager(doc)}};CommandManager.prototype={handleFocus_:function(e){var target=e.target;if(target.menu||target.command)return;var commands=Array.prototype.slice.call(target.ownerDocument.querySelectorAll("command"));commands.forEach(function(command){dispatchCanExecuteEvent(command,target)})},handleKeyDown_:function(e){var target=e.target;var commands=Array.prototype.slice.call(target.ownerDocument.querySelectorAll("command"));for(var i=0,command;command=commands[i];i++){if(command.matchesEvent(e)){command.canExecuteChange();if(!command.disabled){e.preventDefault();e.stopPropagation();command.execute();return}}}}};function CanExecuteEvent(command){var e=new Event("canExecute",{bubbles:true,cancelable:true});e.__proto__=CanExecuteEvent.prototype;e.command=command;return e}CanExecuteEvent.prototype={__proto__:Event.prototype,command:null,canExecute_:false,get canExecute(){return this.canExecute_},set canExecute(canExecute){this.canExecute_=!!canExecute;this.stopPropagation();this.preventDefault()}};return{Command:Command,CanExecuteEvent:CanExecuteEvent}});Polymer({is:"iron-media-query",properties:{queryMatches:{type:Boolean,value:false,readOnly:true,notify:true},query:{type:String,observer:"queryChanged"},full:{type:Boolean,value:false},_boundMQHandler:{value:function(){return this.queryHandler.bind(this)}},_mq:{value:null}},attached:function(){this.style.display="none";this.queryChanged()},detached:function(){this._remove()},_add:function(){if(this._mq){this._mq.addListener(this._boundMQHandler)}},_remove:function(){if(this._mq){this._mq.removeListener(this._boundMQHandler)}this._mq=null},queryChanged:function(){this._remove();var query=this.query;if(!query){return}if(!this.full&&query[0]!=="("){query="("+query+")"}this._mq=window.matchMedia(query);this._add();this.queryHandler(this._mq)},queryHandler:function(mq){this._setQueryMatches(mq.matches)}});Polymer.IronResizableBehavior={properties:{_parentResizable:{type:Object,observer:"_parentResizableChanged"},_notifyingDescendant:{type:Boolean,value:false}},listeners:{"iron-request-resize-notifications":"_onIronRequestResizeNotifications"},created:function(){this._interestedResizables=[];this._boundNotifyResize=this.notifyResize.bind(this)},attached:function(){this.fire("iron-request-resize-notifications",null,{node:this,bubbles:true,cancelable:true});if(!this._parentResizable){window.addEventListener("resize",this._boundNotifyResize);this.notifyResize()}},detached:function(){if(this._parentResizable){this._parentResizable.stopResizeNotificationsFor(this)}else{window.removeEventListener("resize",this._boundNotifyResize)}this._parentResizable=null},notifyResize:function(){if(!this.isAttached){return}this._interestedResizables.forEach(function(resizable){if(this.resizerShouldNotify(resizable)){this._notifyDescendant(resizable)}},this);this._fireResize()},assignParentResizable:function(parentResizable){this._parentResizable=parentResizable},stopResizeNotificationsFor:function(target){var index=this._interestedResizables.indexOf(target);if(index>-1){this._interestedResizables.splice(index,1);this.unlisten(target,"iron-resize","_onDescendantIronResize")}},resizerShouldNotify:function(element){return true},_onDescendantIronResize:function(event){if(this._notifyingDescendant){event.stopPropagation();return}if(!Polymer.Settings.useShadow){this._fireResize()}},_fireResize:function(){this.fire("iron-resize",null,{node:this,bubbles:false})},_onIronRequestResizeNotifications:function(event){var target=event.path?event.path[0]:event.target;if(target===this){return}if(this._interestedResizables.indexOf(target)===-1){this._interestedResizables.push(target);this.listen(target,"iron-resize","_onDescendantIronResize")}target.assignParentResizable(this);this._notifyDescendant(target);event.stopPropagation()},_parentResizableChanged:function(parentResizable){if(parentResizable){window.removeEventListener("resize",this._boundNotifyResize)}},_notifyDescendant:function(descendant){if(!this.isAttached){return}this._notifyingDescendant=true;descendant.notifyResize();this._notifyingDescendant=false}};Polymer.IronSelection=function(selectCallback){this.selection=[];this.selectCallback=selectCallback};Polymer.IronSelection.prototype={get:function(){return this.multi?this.selection.slice():this.selection[0]},clear:function(excludes){this.selection.slice().forEach(function(item){if(!excludes||excludes.indexOf(item)<0){this.setItemSelected(item,false)}},this)},isSelected:function(item){return this.selection.indexOf(item)>=0},setItemSelected:function(item,isSelected){if(item!=null){if(isSelected!==this.isSelected(item)){if(isSelected){this.selection.push(item)}else{var i=this.selection.indexOf(item);if(i>=0){this.selection.splice(i,1)}}if(this.selectCallback){this.selectCallback(item,isSelected)}}}},select:function(item){if(this.multi){this.toggle(item)}else if(this.get()!==item){this.setItemSelected(this.get(),false);this.setItemSelected(item,true)}},toggle:function(item){this.setItemSelected(item,!this.isSelected(item))}};Polymer.IronSelectableBehavior={properties:{attrForSelected:{type:String,value:null},selected:{type:String,notify:true},selectedItem:{type:Object,readOnly:true,notify:true},activateEvent:{type:String,value:"tap",observer:"_activateEventChanged"},selectable:String,selectedClass:{type:String,value:"iron-selected"},selectedAttribute:{type:String,value:null},fallbackSelection:{type:String,value:null},items:{type:Array,readOnly:true,notify:true,value:function(){return[]}},_excludedLocalNames:{type:Object,value:function(){return{template:1}}}},observers:["_updateAttrForSelected(attrForSelected)","_updateSelected(selected)","_checkFallback(fallbackSelection)"],created:function(){this._bindFilterItem=this._filterItem.bind(this);this._selection=new Polymer.IronSelection(this._applySelection.bind(this))},attached:function(){this._observer=this._observeItems(this);this._updateItems();if(!this._shouldUpdateSelection){this._updateSelected()}this._addListener(this.activateEvent)},detached:function(){if(this._observer){Polymer.dom(this).unobserveNodes(this._observer)}this._removeListener(this.activateEvent)},indexOf:function(item){return this.items.indexOf(item)},select:function(value){this.selected=value},selectPrevious:function(){var length=this.items.length;var index=(Number(this._valueToIndex(this.selected))-1+length)%length;this.selected=this._indexToValue(index)},selectNext:function(){var index=(Number(this._valueToIndex(this.selected))+1)%this.items.length;this.selected=this._indexToValue(index)},selectIndex:function(index){this.select(this._indexToValue(index))},forceSynchronousItemUpdate:function(){this._updateItems()},get _shouldUpdateSelection(){return this.selected!=null},_checkFallback:function(){if(this._shouldUpdateSelection){this._updateSelected()}},_addListener:function(eventName){this.listen(this,eventName,"_activateHandler")},_removeListener:function(eventName){this.unlisten(this,eventName,"_activateHandler")},_activateEventChanged:function(eventName,old){this._removeListener(old);this._addListener(eventName)},_updateItems:function(){var nodes=Polymer.dom(this).queryDistributedElements(this.selectable||"*");nodes=Array.prototype.filter.call(nodes,this._bindFilterItem);this._setItems(nodes)},_updateAttrForSelected:function(){if(this._shouldUpdateSelection){this.selected=this._indexToValue(this.indexOf(this.selectedItem))}},_updateSelected:function(){this._selectSelected(this.selected)},_selectSelected:function(selected){this._selection.select(this._valueToItem(this.selected));if(this.fallbackSelection&&this.items.length&&this._selection.get()===undefined){this.selected=this.fallbackSelection}},_filterItem:function(node){return!this._excludedLocalNames[node.localName]},_valueToItem:function(value){return value==null?null:this.items[this._valueToIndex(value)]},_valueToIndex:function(value){if(this.attrForSelected){for(var i=0,item;item=this.items[i];i++){if(this._valueForItem(item)==value){return i}}}else{return Number(value)}},_indexToValue:function(index){if(this.attrForSelected){var item=this.items[index];if(item){return this._valueForItem(item)}}else{return index}},_valueForItem:function(item){var propValue=item[Polymer.CaseMap.dashToCamelCase(this.attrForSelected)];return propValue!=undefined?propValue:item.getAttribute(this.attrForSelected)},_applySelection:function(item,isSelected){if(this.selectedClass){this.toggleClass(this.selectedClass,isSelected,item)}if(this.selectedAttribute){this.toggleAttribute(this.selectedAttribute,isSelected,item)}this._selectionChange();this.fire("iron-"+(isSelected?"select":"deselect"),{item:item})},_selectionChange:function(){this._setSelectedItem(this._selection.get())},_observeItems:function(node){return Polymer.dom(node).observeNodes(function(mutation){this._updateItems();if(this._shouldUpdateSelection){this._updateSelected()}this.fire("iron-items-changed",mutation,{bubbles:false,cancelable:false})})},_activateHandler:function(e){var t=e.target;var items=this.items;while(t&&t!=this){var i=items.indexOf(t);if(i>=0){var value=this._indexToValue(i);this._itemActivate(value,t);return}t=t.parentNode}},_itemActivate:function(value,item){if(!this.fire("iron-activate",{selected:value,item:item},{cancelable:true}).defaultPrevented){this.select(value)}}};Polymer({is:"iron-pages",behaviors:[Polymer.IronResizableBehavior,Polymer.IronSelectableBehavior],properties:{activateEvent:{type:String,value:null}},observers:["_selectedPageChanged(selected)"],_selectedPageChanged:function(selected,old){this.async(this.notifyResize)}});Polymer.IronScrollTargetBehavior={properties:{scrollTarget:{type:HTMLElement,value:function(){return this._defaultScrollTarget}}},observers:["_scrollTargetChanged(scrollTarget, isAttached)"],_shouldHaveListener:true,_scrollTargetChanged:function(scrollTarget,isAttached){var eventTarget;if(this._oldScrollTarget){this._toggleScrollListener(false,this._oldScrollTarget);this._oldScrollTarget=null}if(!isAttached){return}if(scrollTarget==="document"){this.scrollTarget=this._doc}else if(typeof scrollTarget==="string"){this.scrollTarget=this.domHost?this.domHost.$[scrollTarget]:Polymer.dom(this.ownerDocument).querySelector("#"+scrollTarget)}else if(this._isValidScrollTarget()){this._boundScrollHandler=this._boundScrollHandler||this._scrollHandler.bind(this);this._oldScrollTarget=scrollTarget;this._toggleScrollListener(this._shouldHaveListener,scrollTarget)}},_scrollHandler:function scrollHandler(){},get _defaultScrollTarget(){return this._doc},get _doc(){return this.ownerDocument.documentElement},get _scrollTop(){if(this._isValidScrollTarget()){return this.scrollTarget===this._doc?window.pageYOffset:this.scrollTarget.scrollTop}return 0},get _scrollLeft(){if(this._isValidScrollTarget()){return this.scrollTarget===this._doc?window.pageXOffset:this.scrollTarget.scrollLeft}return 0},set _scrollTop(top){if(this.scrollTarget===this._doc){window.scrollTo(window.pageXOffset,top)}else if(this._isValidScrollTarget()){this.scrollTarget.scrollTop=top}},set _scrollLeft(left){if(this.scrollTarget===this._doc){window.scrollTo(left,window.pageYOffset)}else if(this._isValidScrollTarget()){this.scrollTarget.scrollLeft=left}},scroll:function(left,top){if(this.scrollTarget===this._doc){window.scrollTo(left,top)}else if(this._isValidScrollTarget()){this.scrollTarget.scrollLeft=left;this.scrollTarget.scrollTop=top}},get _scrollTargetWidth(){if(this._isValidScrollTarget()){return this.scrollTarget===this._doc?window.innerWidth:this.scrollTarget.offsetWidth}return 0},get _scrollTargetHeight(){if(this._isValidScrollTarget()){return this.scrollTarget===this._doc?window.innerHeight:this.scrollTarget.offsetHeight}return 0},_isValidScrollTarget:function(){return this.scrollTarget instanceof HTMLElement},_toggleScrollListener:function(yes,scrollTarget){if(!this._boundScrollHandler){return}var eventTarget=scrollTarget===this._doc?window:scrollTarget;if(yes){eventTarget.addEventListener("scroll",this._boundScrollHandler)}else{eventTarget.removeEventListener("scroll",this._boundScrollHandler)}},toggleScrollListener:function(yes){this._shouldHaveListener=yes;this._toggleScrollListener(yes,this.scrollTarget)}};(function(){var metaDatas={};var metaArrays={};var singleton=null;Polymer.IronMeta=Polymer({is:"iron-meta",properties:{type:{type:String,value:"default",observer:"_typeChanged"},key:{type:String,observer:"_keyChanged"},value:{type:Object,notify:true,observer:"_valueChanged"},self:{type:Boolean,observer:"_selfChanged"},list:{type:Array,notify:true}},hostAttributes:{hidden:true},factoryImpl:function(config){if(config){for(var n in config){switch(n){case"type":case"key":case"value":this[n]=config[n];break}}}},created:function(){this._metaDatas=metaDatas;this._metaArrays=metaArrays},_keyChanged:function(key,old){this._resetRegistration(old)},_valueChanged:function(value){this._resetRegistration(this.key)},_selfChanged:function(self){if(self){this.value=this}},_typeChanged:function(type){this._unregisterKey(this.key);if(!metaDatas[type]){metaDatas[type]={}}this._metaData=metaDatas[type];if(!metaArrays[type]){metaArrays[type]=[]}this.list=metaArrays[type];this._registerKeyValue(this.key,this.value)},byKey:function(key){return this._metaData&&this._metaData[key]},_resetRegistration:function(oldKey){this._unregisterKey(oldKey);this._registerKeyValue(this.key,this.value)},_unregisterKey:function(key){this._unregister(key,this._metaData,this.list)},_registerKeyValue:function(key,value){this._register(key,value,this._metaData,this.list)},_register:function(key,value,data,list){if(key&&data&&value!==undefined){data[key]=value;list.push(value)}},_unregister:function(key,data,list){if(key&&data){if(key in data){var value=data[key];delete data[key];this.arrayDelete(list,value)}}}});Polymer.IronMeta.getIronMeta=function getIronMeta(){if(singleton===null){singleton=new Polymer.IronMeta}return singleton};Polymer.IronMetaQuery=Polymer({is:"iron-meta-query",properties:{type:{type:String,value:"default",observer:"_typeChanged"},key:{type:String,observer:"_keyChanged"},value:{type:Object,notify:true,readOnly:true},list:{type:Array,notify:true}},factoryImpl:function(config){if(config){for(var n in config){switch(n){case"type":case"key":this[n]=config[n];break}}}},created:function(){this._metaDatas=metaDatas;this._metaArrays=metaArrays},_keyChanged:function(key){this._setValue(this._metaData&&this._metaData[key])},_typeChanged:function(type){this._metaData=metaDatas[type];this.list=metaArrays[type];if(this.key){this._keyChanged(this.key)}},byKey:function(key){return this._metaData&&this._metaData[key]}})})();Polymer({is:"iron-icon",properties:{icon:{type:String,observer:"_iconChanged"},theme:{type:String,observer:"_updateIcon"},src:{type:String,observer:"_srcChanged"},_meta:{value:Polymer.Base.create("iron-meta",{type:"iconset"}),observer:"_updateIcon"}},_DEFAULT_ICONSET:"icons",_iconChanged:function(icon){var parts=(icon||"").split(":");this._iconName=parts.pop();this._iconsetName=parts.pop()||this._DEFAULT_ICONSET;this._updateIcon()},_srcChanged:function(src){this._updateIcon()},_usesIconset:function(){return this.icon||!this.src},_updateIcon:function(){if(this._usesIconset()){if(this._img&&this._img.parentNode){Polymer.dom(this.root).removeChild(this._img)}if(this._iconName===""){if(this._iconset){this._iconset.removeIcon(this)}}else if(this._iconsetName&&this._meta){this._iconset=this._meta.byKey(this._iconsetName);if(this._iconset){this._iconset.applyIcon(this,this._iconName,this.theme);this.unlisten(window,"iron-iconset-added","_updateIcon")}else{this.listen(window,"iron-iconset-added","_updateIcon")}}}else{if(this._iconset){this._iconset.removeIcon(this)}if(!this._img){this._img=document.createElement("img");this._img.style.width="100%";this._img.style.height="100%";this._img.draggable=false}this._img.src=this.src;Polymer.dom(this.root).appendChild(this._img)}}});Polymer({is:"iron-iconset-svg",properties:{name:{type:String,observer:"_nameChanged"},size:{type:Number,value:24},rtlMirroring:{type:Boolean,value:false}},_targetIsRTL:function(target){if(target&&target.nodeType!==Node.ELEMENT_NODE){target=target.host}return target&&window.getComputedStyle(target)["direction"]==="rtl"},attached:function(){this.style.display="none"},getIconNames:function(){this._icons=this._createIconMap();return Object.keys(this._icons).map(function(n){return this.name+":"+n},this)},applyIcon:function(element,iconName){element=element.root||element;this.removeIcon(element);var svg=this._cloneIcon(iconName,this.rtlMirroring&&this._targetIsRTL(element));if(svg){var pde=Polymer.dom(element);pde.insertBefore(svg,pde.childNodes[0]);return element._svgIcon=svg}return null},removeIcon:function(element){element=element.root||element;if(element._svgIcon){Polymer.dom(element).removeChild(element._svgIcon);element._svgIcon=null}},_nameChanged:function(){new Polymer.IronMeta({type:"iconset",key:this.name,value:this});this.async(function(){this.fire("iron-iconset-added",this,{node:window})})},_createIconMap:function(){var icons=Object.create(null);Polymer.dom(this).querySelectorAll("[id]").forEach(function(icon){icons[icon.id]=icon});return icons},_cloneIcon:function(id,mirrorAllowed){this._icons=this._icons||this._createIconMap();return this._prepareSvgClone(this._icons[id],this.size,mirrorAllowed)},_prepareSvgClone:function(sourceSvg,size,mirrorAllowed){if(sourceSvg){var content=sourceSvg.cloneNode(true),svg=document.createElementNS("http://www.w3.org/2000/svg","svg"),viewBox=content.getAttribute("viewBox")||"0 0 "+size+" "+size,cssText="pointer-events: none; display: block; width: 100%; height: 100%;";if(mirrorAllowed&&content.hasAttribute("mirror-in-rtl")){cssText+="-webkit-transform:scale(-1,1);transform:scale(-1,1);"}svg.setAttribute("viewBox",viewBox);svg.setAttribute("preserveAspectRatio","xMidYMid meet");svg.style.cssText=cssText;svg.appendChild(content).removeAttribute("id");return svg}return null}});
 // 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.
-Polymer({is:"cr-lazy-render","extends":"template",behaviors:[Polymer.Templatizer],child_:null,get:function(){if(!this.child_)this.render_();return this.child_},getIfExists:function(){return this.child_},render_:function(){if(!this.ctor)this.templatize(this);var parentNode=this.parentNode;if(parentNode&&!this.child_){var instance=this.stamp({});this.child_=instance.root.firstElementChild;parentNode.insertBefore(instance.root,this)}},_forwardParentProp:function(prop,value){if(this.child_)this.child_._templateInstance[prop]=value},_forwardParentPath:function(path,value){if(this.child_)this.child_._templateInstance.notifyPath(path,value,true)}});Polymer.PaperSpinnerBehavior={listeners:{animationend:"__reset",webkitAnimationEnd:"__reset"},properties:{active:{type:Boolean,value:false,reflectToAttribute:true,observer:"__activeChanged"},alt:{type:String,value:"loading",observer:"__altChanged"},__coolingDown:{type:Boolean,value:false}},__computeContainerClasses:function(active,coolingDown){return[active||coolingDown?"active":"",coolingDown?"cooldown":""].join(" ")},__activeChanged:function(active,old){this.__setAriaHidden(!active);this.__coolingDown=!active&&old},__altChanged:function(alt){if(alt===this.getPropertyInfo("alt").value){this.alt=this.getAttribute("aria-label")||alt}else{this.__setAriaHidden(alt==="");this.setAttribute("aria-label",alt)}},__setAriaHidden:function(hidden){var attr="aria-hidden";if(hidden){this.setAttribute(attr,"true")}else{this.removeAttribute(attr)}},__reset:function(){this.active=false;this.__coolingDown=false}};Polymer({is:"paper-spinner-lite",behaviors:[Polymer.PaperSpinnerBehavior]});
+Polymer({is:"cr-lazy-render","extends":"template",behaviors:[Polymer.Templatizer],child_:null,get:function(){if(!this.child_)this.render_();return this.child_},getIfExists:function(){return this.child_},render_:function(){if(!this.ctor)this.templatize(this);var parentNode=this.parentNode;if(parentNode&&!this.child_){var instance=this.stamp({});this.child_=instance.root.firstElementChild;parentNode.insertBefore(instance.root,this)}},_forwardParentProp:function(prop,value){if(this.child_)this.child_._templateInstance[prop]=value},_forwardParentPath:function(path,value){if(this.child_)this.child_._templateInstance.notifyPath(path,value,true)}});(function(){"use strict";var KEY_IDENTIFIER={"U+0008":"backspace","U+0009":"tab","U+001B":"esc","U+0020":"space","U+007F":"del"};var KEY_CODE={8:"backspace",9:"tab",13:"enter",27:"esc",33:"pageup",34:"pagedown",35:"end",36:"home",32:"space",37:"left",38:"up",39:"right",40:"down",46:"del",106:"*"};var MODIFIER_KEYS={shift:"shiftKey",ctrl:"ctrlKey",alt:"altKey",meta:"metaKey"};var KEY_CHAR=/[a-z0-9*]/;var IDENT_CHAR=/U\+/;var ARROW_KEY=/^arrow/;var SPACE_KEY=/^space(bar)?/;var ESC_KEY=/^escape$/;function transformKey(key,noSpecialChars){var validKey="";if(key){var lKey=key.toLowerCase();if(lKey===" "||SPACE_KEY.test(lKey)){validKey="space"}else if(ESC_KEY.test(lKey)){validKey="esc"}else if(lKey.length==1){if(!noSpecialChars||KEY_CHAR.test(lKey)){validKey=lKey}}else if(ARROW_KEY.test(lKey)){validKey=lKey.replace("arrow","")}else if(lKey=="multiply"){validKey="*"}else{validKey=lKey}}return validKey}function transformKeyIdentifier(keyIdent){var validKey="";if(keyIdent){if(keyIdent in KEY_IDENTIFIER){validKey=KEY_IDENTIFIER[keyIdent]}else if(IDENT_CHAR.test(keyIdent)){keyIdent=parseInt(keyIdent.replace("U+","0x"),16);validKey=String.fromCharCode(keyIdent).toLowerCase()}else{validKey=keyIdent.toLowerCase()}}return validKey}function transformKeyCode(keyCode){var validKey="";if(Number(keyCode)){if(keyCode>=65&&keyCode<=90){validKey=String.fromCharCode(32+keyCode)}else if(keyCode>=112&&keyCode<=123){validKey="f"+(keyCode-112)}else if(keyCode>=48&&keyCode<=57){validKey=String(keyCode-48)}else if(keyCode>=96&&keyCode<=105){validKey=String(keyCode-96)}else{validKey=KEY_CODE[keyCode]}}return validKey}function normalizedKeyForEvent(keyEvent,noSpecialChars){if(keyEvent.key){return transformKey(keyEvent.key,noSpecialChars)}if(keyEvent.detail&&keyEvent.detail.key){return transformKey(keyEvent.detail.key,noSpecialChars)}return transformKeyIdentifier(keyEvent.keyIdentifier)||transformKeyCode(keyEvent.keyCode)||""}function keyComboMatchesEvent(keyCombo,event){var keyEvent=normalizedKeyForEvent(event,keyCombo.hasModifiers);return keyEvent===keyCombo.key&&(!keyCombo.hasModifiers||!!event.shiftKey===!!keyCombo.shiftKey&&!!event.ctrlKey===!!keyCombo.ctrlKey&&!!event.altKey===!!keyCombo.altKey&&!!event.metaKey===!!keyCombo.metaKey)}function parseKeyComboString(keyComboString){if(keyComboString.length===1){return{combo:keyComboString,key:keyComboString,event:"keydown"}}return keyComboString.split("+").reduce(function(parsedKeyCombo,keyComboPart){var eventParts=keyComboPart.split(":");var keyName=eventParts[0];var event=eventParts[1];if(keyName in MODIFIER_KEYS){parsedKeyCombo[MODIFIER_KEYS[keyName]]=true;parsedKeyCombo.hasModifiers=true}else{parsedKeyCombo.key=keyName;parsedKeyCombo.event=event||"keydown"}return parsedKeyCombo},{combo:keyComboString.split(":").shift()})}function parseEventString(eventString){return eventString.trim().split(" ").map(function(keyComboString){return parseKeyComboString(keyComboString)})}Polymer.IronA11yKeysBehavior={properties:{keyEventTarget:{type:Object,value:function(){return this}},stopKeyboardEventPropagation:{type:Boolean,value:false},_boundKeyHandlers:{type:Array,value:function(){return[]}},_imperativeKeyBindings:{type:Object,value:function(){return{}}}},observers:["_resetKeyEventListeners(keyEventTarget, _boundKeyHandlers)"],keyBindings:{},registered:function(){this._prepKeyBindings()},attached:function(){this._listenKeyEventListeners()},detached:function(){this._unlistenKeyEventListeners()},addOwnKeyBinding:function(eventString,handlerName){this._imperativeKeyBindings[eventString]=handlerName;this._prepKeyBindings();this._resetKeyEventListeners()},removeOwnKeyBindings:function(){this._imperativeKeyBindings={};this._prepKeyBindings();this._resetKeyEventListeners()},keyboardEventMatchesKeys:function(event,eventString){var keyCombos=parseEventString(eventString);for(var i=0;i<keyCombos.length;++i){if(keyComboMatchesEvent(keyCombos[i],event)){return true}}return false},_collectKeyBindings:function(){var keyBindings=this.behaviors.map(function(behavior){return behavior.keyBindings});if(keyBindings.indexOf(this.keyBindings)===-1){keyBindings.push(this.keyBindings)}return keyBindings},_prepKeyBindings:function(){this._keyBindings={};this._collectKeyBindings().forEach(function(keyBindings){for(var eventString in keyBindings){this._addKeyBinding(eventString,keyBindings[eventString])}},this);for(var eventString in this._imperativeKeyBindings){this._addKeyBinding(eventString,this._imperativeKeyBindings[eventString])}for(var eventName in this._keyBindings){this._keyBindings[eventName].sort(function(kb1,kb2){var b1=kb1[0].hasModifiers;var b2=kb2[0].hasModifiers;return b1===b2?0:b1?-1:1})}},_addKeyBinding:function(eventString,handlerName){parseEventString(eventString).forEach(function(keyCombo){this._keyBindings[keyCombo.event]=this._keyBindings[keyCombo.event]||[];this._keyBindings[keyCombo.event].push([keyCombo,handlerName])},this)},_resetKeyEventListeners:function(){this._unlistenKeyEventListeners();if(this.isAttached){this._listenKeyEventListeners()}},_listenKeyEventListeners:function(){if(!this.keyEventTarget){return}Object.keys(this._keyBindings).forEach(function(eventName){var keyBindings=this._keyBindings[eventName];var boundKeyHandler=this._onKeyBindingEvent.bind(this,keyBindings);this._boundKeyHandlers.push([this.keyEventTarget,eventName,boundKeyHandler]);this.keyEventTarget.addEventListener(eventName,boundKeyHandler)},this)},_unlistenKeyEventListeners:function(){var keyHandlerTuple;var keyEventTarget;var eventName;var boundKeyHandler;while(this._boundKeyHandlers.length){keyHandlerTuple=this._boundKeyHandlers.pop();keyEventTarget=keyHandlerTuple[0];eventName=keyHandlerTuple[1];boundKeyHandler=keyHandlerTuple[2];keyEventTarget.removeEventListener(eventName,boundKeyHandler)}},_onKeyBindingEvent:function(keyBindings,event){if(this.stopKeyboardEventPropagation){event.stopPropagation()}if(event.defaultPrevented){return}for(var i=0;i<keyBindings.length;i++){var keyCombo=keyBindings[i][0];var handlerName=keyBindings[i][1];if(keyComboMatchesEvent(keyCombo,event)){this._triggerKeyHandler(keyCombo,handlerName,event);if(event.defaultPrevented){return}}}},_triggerKeyHandler:function(keyCombo,handlerName,keyboardEvent){var detail=Object.create(keyCombo);detail.keyboardEvent=keyboardEvent;var event=new CustomEvent(keyCombo.event,{detail:detail,cancelable:true});this[handlerName].call(this,event);if(event.defaultPrevented){keyboardEvent.preventDefault()}}}})();Polymer.IronControlState={properties:{focused:{type:Boolean,value:false,notify:true,readOnly:true,reflectToAttribute:true},disabled:{type:Boolean,value:false,notify:true,observer:"_disabledChanged",reflectToAttribute:true},_oldTabIndex:{type:Number},_boundFocusBlurHandler:{type:Function,value:function(){return this._focusBlurHandler.bind(this)}}},observers:["_changedControlState(focused, disabled)"],ready:function(){this.addEventListener("focus",this._boundFocusBlurHandler,true);this.addEventListener("blur",this._boundFocusBlurHandler,true)},_focusBlurHandler:function(event){if(event.target===this){this._setFocused(event.type==="focus")}else if(!this.shadowRoot){var target=Polymer.dom(event).localTarget;if(!this.isLightDescendant(target)){this.fire(event.type,{sourceEvent:event},{node:this,bubbles:event.bubbles,cancelable:event.cancelable})}}},_disabledChanged:function(disabled,old){this.setAttribute("aria-disabled",disabled?"true":"false");this.style.pointerEvents=disabled?"none":"";if(disabled){this._oldTabIndex=this.tabIndex;this._setFocused(false);this.tabIndex=-1;this.blur()}else if(this._oldTabIndex!==undefined){this.tabIndex=this._oldTabIndex}},_changedControlState:function(){if(this._controlStateChanged){this._controlStateChanged()}}};Polymer.IronButtonStateImpl={properties:{pressed:{type:Boolean,readOnly:true,value:false,reflectToAttribute:true,observer:"_pressedChanged"},toggles:{type:Boolean,value:false,reflectToAttribute:true},active:{type:Boolean,value:false,notify:true,reflectToAttribute:true},pointerDown:{type:Boolean,readOnly:true,value:false},receivedFocusFromKeyboard:{type:Boolean,readOnly:true},ariaActiveAttribute:{type:String,value:"aria-pressed",observer:"_ariaActiveAttributeChanged"}},listeners:{down:"_downHandler",up:"_upHandler",tap:"_tapHandler"},observers:["_detectKeyboardFocus(focused)","_activeChanged(active, ariaActiveAttribute)"],keyBindings:{"enter:keydown":"_asyncClick","space:keydown":"_spaceKeyDownHandler","space:keyup":"_spaceKeyUpHandler"},_mouseEventRe:/^mouse/,_tapHandler:function(){if(this.toggles){this._userActivate(!this.active)}else{this.active=false}},_detectKeyboardFocus:function(focused){this._setReceivedFocusFromKeyboard(!this.pointerDown&&focused)},_userActivate:function(active){if(this.active!==active){this.active=active;this.fire("change")}},_downHandler:function(event){this._setPointerDown(true);this._setPressed(true);this._setReceivedFocusFromKeyboard(false)},_upHandler:function(){this._setPointerDown(false);this._setPressed(false)},_spaceKeyDownHandler:function(event){var keyboardEvent=event.detail.keyboardEvent;var target=Polymer.dom(keyboardEvent).localTarget;if(this.isLightDescendant(target))return;keyboardEvent.preventDefault();keyboardEvent.stopImmediatePropagation();this._setPressed(true)},_spaceKeyUpHandler:function(event){var keyboardEvent=event.detail.keyboardEvent;var target=Polymer.dom(keyboardEvent).localTarget;if(this.isLightDescendant(target))return;if(this.pressed){this._asyncClick()}this._setPressed(false)},_asyncClick:function(){this.async(function(){this.click()},1)},_pressedChanged:function(pressed){this._changedButtonState()},_ariaActiveAttributeChanged:function(value,oldValue){if(oldValue&&oldValue!=value&&this.hasAttribute(oldValue)){this.removeAttribute(oldValue)}},_activeChanged:function(active,ariaActiveAttribute){if(this.toggles){this.setAttribute(this.ariaActiveAttribute,active?"true":"false")}else{this.removeAttribute(this.ariaActiveAttribute)}this._changedButtonState()},_controlStateChanged:function(){if(this.disabled){this._setPressed(false)}else{this._changedButtonState()}},_changedButtonState:function(){if(this._buttonStateChanged){this._buttonStateChanged()}}};Polymer.IronButtonState=[Polymer.IronA11yKeysBehavior,Polymer.IronButtonStateImpl];(function(){var Utility={distance:function(x1,y1,x2,y2){var xDelta=x1-x2;var yDelta=y1-y2;return Math.sqrt(xDelta*xDelta+yDelta*yDelta)},now:window.performance&&window.performance.now?window.performance.now.bind(window.performance):Date.now};function ElementMetrics(element){this.element=element;this.width=this.boundingRect.width;this.height=this.boundingRect.height;this.size=Math.max(this.width,this.height)}ElementMetrics.prototype={get boundingRect(){return this.element.getBoundingClientRect()},furthestCornerDistanceFrom:function(x,y){var topLeft=Utility.distance(x,y,0,0);var topRight=Utility.distance(x,y,this.width,0);var bottomLeft=Utility.distance(x,y,0,this.height);var bottomRight=Utility.distance(x,y,this.width,this.height);return Math.max(topLeft,topRight,bottomLeft,bottomRight)}};function Ripple(element){this.element=element;this.color=window.getComputedStyle(element).color;this.wave=document.createElement("div");this.waveContainer=document.createElement("div");this.wave.style.backgroundColor=this.color;this.wave.classList.add("wave");this.waveContainer.classList.add("wave-container");Polymer.dom(this.waveContainer).appendChild(this.wave);this.resetInteractionState()}Ripple.MAX_RADIUS=300;Ripple.prototype={get recenters(){return this.element.recenters},get center(){return this.element.center},get mouseDownElapsed(){var elapsed;if(!this.mouseDownStart){return 0}elapsed=Utility.now()-this.mouseDownStart;if(this.mouseUpStart){elapsed-=this.mouseUpElapsed}return elapsed},get mouseUpElapsed(){return this.mouseUpStart?Utility.now()-this.mouseUpStart:0},get mouseDownElapsedSeconds(){return this.mouseDownElapsed/1e3},get mouseUpElapsedSeconds(){return this.mouseUpElapsed/1e3},get mouseInteractionSeconds(){return this.mouseDownElapsedSeconds+this.mouseUpElapsedSeconds},get initialOpacity(){return this.element.initialOpacity},get opacityDecayVelocity(){return this.element.opacityDecayVelocity},get radius(){var width2=this.containerMetrics.width*this.containerMetrics.width;var height2=this.containerMetrics.height*this.containerMetrics.height;var waveRadius=Math.min(Math.sqrt(width2+height2),Ripple.MAX_RADIUS)*1.1+5;var duration=1.1-.2*(waveRadius/Ripple.MAX_RADIUS);var timeNow=this.mouseInteractionSeconds/duration;var size=waveRadius*(1-Math.pow(80,-timeNow));return Math.abs(size)},get opacity(){if(!this.mouseUpStart){return this.initialOpacity}return Math.max(0,this.initialOpacity-this.mouseUpElapsedSeconds*this.opacityDecayVelocity)},get outerOpacity(){var outerOpacity=this.mouseUpElapsedSeconds*.3;var waveOpacity=this.opacity;return Math.max(0,Math.min(outerOpacity,waveOpacity))},get isOpacityFullyDecayed(){return this.opacity<.01&&this.radius>=Math.min(this.maxRadius,Ripple.MAX_RADIUS)},get isRestingAtMaxRadius(){return this.opacity>=this.initialOpacity&&this.radius>=Math.min(this.maxRadius,Ripple.MAX_RADIUS)},get isAnimationComplete(){return this.mouseUpStart?this.isOpacityFullyDecayed:this.isRestingAtMaxRadius},get translationFraction(){return Math.min(1,this.radius/this.containerMetrics.size*2/Math.sqrt(2))},get xNow(){if(this.xEnd){return this.xStart+this.translationFraction*(this.xEnd-this.xStart)}return this.xStart},get yNow(){if(this.yEnd){return this.yStart+this.translationFraction*(this.yEnd-this.yStart)}return this.yStart},get isMouseDown(){return this.mouseDownStart&&!this.mouseUpStart},resetInteractionState:function(){this.maxRadius=0;this.mouseDownStart=0;this.mouseUpStart=0;this.xStart=0;this.yStart=0;this.xEnd=0;this.yEnd=0;this.slideDistance=0;this.containerMetrics=new ElementMetrics(this.element)},draw:function(){var scale;var translateString;var dx;var dy;this.wave.style.opacity=this.opacity;scale=this.radius/(this.containerMetrics.size/2);dx=this.xNow-this.containerMetrics.width/2;dy=this.yNow-this.containerMetrics.height/2;this.waveContainer.style.webkitTransform="translate("+dx+"px, "+dy+"px)";this.waveContainer.style.transform="translate3d("+dx+"px, "+dy+"px, 0)";this.wave.style.webkitTransform="scale("+scale+","+scale+")";this.wave.style.transform="scale3d("+scale+","+scale+",1)"},downAction:function(event){var xCenter=this.containerMetrics.width/2;var yCenter=this.containerMetrics.height/2;this.resetInteractionState();this.mouseDownStart=Utility.now();if(this.center){this.xStart=xCenter;this.yStart=yCenter;this.slideDistance=Utility.distance(this.xStart,this.yStart,this.xEnd,this.yEnd)}else{this.xStart=event?event.detail.x-this.containerMetrics.boundingRect.left:this.containerMetrics.width/2;this.yStart=event?event.detail.y-this.containerMetrics.boundingRect.top:this.containerMetrics.height/2}if(this.recenters){this.xEnd=xCenter;this.yEnd=yCenter;this.slideDistance=Utility.distance(this.xStart,this.yStart,this.xEnd,this.yEnd)}this.maxRadius=this.containerMetrics.furthestCornerDistanceFrom(this.xStart,this.yStart);this.waveContainer.style.top=(this.containerMetrics.height-this.containerMetrics.size)/2+"px";this.waveContainer.style.left=(this.containerMetrics.width-this.containerMetrics.size)/2+"px";this.waveContainer.style.width=this.containerMetrics.size+"px";this.waveContainer.style.height=this.containerMetrics.size+"px"},upAction:function(event){if(!this.isMouseDown){return}this.mouseUpStart=Utility.now()},remove:function(){Polymer.dom(this.waveContainer.parentNode).removeChild(this.waveContainer)}};Polymer({is:"paper-ripple",behaviors:[Polymer.IronA11yKeysBehavior],properties:{initialOpacity:{type:Number,value:.25},opacityDecayVelocity:{type:Number,value:.8},recenters:{type:Boolean,value:false},center:{type:Boolean,value:false},ripples:{type:Array,value:function(){return[]}},animating:{type:Boolean,readOnly:true,reflectToAttribute:true,value:false},holdDown:{type:Boolean,value:false,observer:"_holdDownChanged"},noink:{type:Boolean,value:false},_animating:{type:Boolean},_boundAnimate:{type:Function,value:function(){return this.animate.bind(this)}}},get target(){return this.keyEventTarget},keyBindings:{"enter:keydown":"_onEnterKeydown","space:keydown":"_onSpaceKeydown","space:keyup":"_onSpaceKeyup"},attached:function(){if(this.parentNode.nodeType==11){this.keyEventTarget=Polymer.dom(this).getOwnerRoot().host}else{this.keyEventTarget=this.parentNode}var keyEventTarget=this.keyEventTarget;this.listen(keyEventTarget,"up","uiUpAction");this.listen(keyEventTarget,"down","uiDownAction")},detached:function(){this.unlisten(this.keyEventTarget,"up","uiUpAction");this.unlisten(this.keyEventTarget,"down","uiDownAction");this.keyEventTarget=null},get shouldKeepAnimating(){for(var index=0;index<this.ripples.length;++index){if(!this.ripples[index].isAnimationComplete){return true}}return false},simulatedRipple:function(){this.downAction(null);this.async(function(){this.upAction()},1)},uiDownAction:function(event){if(!this.noink){this.downAction(event)}},downAction:function(event){if(this.holdDown&&this.ripples.length>0){return}var ripple=this.addRipple();ripple.downAction(event);if(!this._animating){this._animating=true;this.animate()}},uiUpAction:function(event){if(!this.noink){this.upAction(event)}},upAction:function(event){if(this.holdDown){return}this.ripples.forEach(function(ripple){ripple.upAction(event)});this._animating=true;this.animate()},onAnimationComplete:function(){this._animating=false;this.$.background.style.backgroundColor=null;this.fire("transitionend")},addRipple:function(){var ripple=new Ripple(this);Polymer.dom(this.$.waves).appendChild(ripple.waveContainer);this.$.background.style.backgroundColor=ripple.color;this.ripples.push(ripple);this._setAnimating(true);return ripple},removeRipple:function(ripple){var rippleIndex=this.ripples.indexOf(ripple);if(rippleIndex<0){return}this.ripples.splice(rippleIndex,1);ripple.remove();if(!this.ripples.length){this._setAnimating(false)}},animate:function(){if(!this._animating){return}var index;var ripple;for(index=0;index<this.ripples.length;++index){ripple=this.ripples[index];ripple.draw();this.$.background.style.opacity=ripple.outerOpacity;if(ripple.isOpacityFullyDecayed&&!ripple.isRestingAtMaxRadius){this.removeRipple(ripple)}}if(!this.shouldKeepAnimating&&this.ripples.length===0){this.onAnimationComplete()}else{window.requestAnimationFrame(this._boundAnimate)}},_onEnterKeydown:function(){this.uiDownAction();this.async(this.uiUpAction,1)},_onSpaceKeydown:function(){this.uiDownAction()},_onSpaceKeyup:function(){this.uiUpAction()},_holdDownChanged:function(newVal,oldVal){if(oldVal===undefined){return}if(newVal){this.downAction()}else{this.upAction()}}})})();Polymer.PaperRippleBehavior={properties:{noink:{type:Boolean,observer:"_noinkChanged"},_rippleContainer:{type:Object}},_buttonStateChanged:function(){if(this.focused){this.ensureRipple()}},_downHandler:function(event){Polymer.IronButtonStateImpl._downHandler.call(this,event);if(this.pressed){this.ensureRipple(event)}},ensureRipple:function(optTriggeringEvent){if(!this.hasRipple()){this._ripple=this._createRipple();this._ripple.noink=this.noink;var rippleContainer=this._rippleContainer||this.root;if(rippleContainer){Polymer.dom(rippleContainer).appendChild(this._ripple)}if(optTriggeringEvent){var domContainer=Polymer.dom(this._rippleContainer||this);var target=Polymer.dom(optTriggeringEvent).rootTarget;if(domContainer.deepContains(target)){this._ripple.uiDownAction(optTriggeringEvent)}}}},getRipple:function(){this.ensureRipple();return this._ripple},hasRipple:function(){return Boolean(this._ripple)},_createRipple:function(){return document.createElement("paper-ripple")},_noinkChanged:function(noink){if(this.hasRipple()){this._ripple.noink=noink}}};Polymer.PaperInkyFocusBehaviorImpl={observers:["_focusedChanged(receivedFocusFromKeyboard)"],_focusedChanged:function(receivedFocusFromKeyboard){if(receivedFocusFromKeyboard){this.ensureRipple()}if(this.hasRipple()){this._ripple.holdDown=receivedFocusFromKeyboard}},_createRipple:function(){var ripple=Polymer.PaperRippleBehavior._createRipple();ripple.id="ink";ripple.setAttribute("center","");ripple.classList.add("circle");return ripple}};Polymer.PaperInkyFocusBehavior=[Polymer.IronButtonState,Polymer.IronControlState,Polymer.PaperRippleBehavior,Polymer.PaperInkyFocusBehaviorImpl];Polymer({is:"paper-icon-button",hostAttributes:{role:"button",tabindex:"0"},behaviors:[Polymer.PaperInkyFocusBehavior],properties:{src:{type:String},icon:{type:String},alt:{type:String,observer:"_altChanged"}},_altChanged:function(newValue,oldValue){var label=this.getAttribute("aria-label");if(!label||oldValue==label){this.setAttribute("aria-label",newValue)}}});Polymer.PaperSpinnerBehavior={listeners:{animationend:"__reset",webkitAnimationEnd:"__reset"},properties:{active:{type:Boolean,value:false,reflectToAttribute:true,observer:"__activeChanged"},alt:{type:String,value:"loading",observer:"__altChanged"},__coolingDown:{type:Boolean,value:false}},__computeContainerClasses:function(active,coolingDown){return[active||coolingDown?"active":"",coolingDown?"cooldown":""].join(" ")},__activeChanged:function(active,old){this.__setAriaHidden(!active);this.__coolingDown=!active&&old},__altChanged:function(alt){if(alt===this.getPropertyInfo("alt").value){this.alt=this.getAttribute("aria-label")||alt}else{this.__setAriaHidden(alt==="");this.setAttribute("aria-label",alt)}},__setAriaHidden:function(hidden){var attr="aria-hidden";if(hidden){this.setAttribute(attr,"true")}else{this.removeAttribute(attr)}},__reset:function(){this.active=false;this.__coolingDown=false}};Polymer({is:"paper-spinner-lite",behaviors:[Polymer.PaperSpinnerBehavior]});
 // 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.
diff --git a/chrome/browser/resources/md_history/app.vulcanized.html b/chrome/browser/resources/md_history/app.vulcanized.html
index 09e4008..971bc5f59 100644
--- a/chrome/browser/resources/md_history/app.vulcanized.html
+++ b/chrome/browser/resources/md_history/app.vulcanized.html
@@ -207,6 +207,39 @@
   </template>
 
   </dom-module>
+<iron-iconset-svg name="cr" size="24">
+  <svg>
+    <defs>
+      
+      <g id="add"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"></path></g>
+      <g id="arrow-drop-down"><path d="M7 10l5 5 5-5z"></path></g>
+      <g id="cancel"><path d="M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z"></path></g>
+<if expr="chromeos">
+      <g id="check"><path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"></path></g>
+</if>
+      <g id="chevron-right"><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"></path></g>
+      <g id="clear"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"></path></g>
+      <g id="close"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"></path></g>
+      <g id="delete"><path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"></path></g>
+      <g id="domain"><path d="M12 7V3H2v18h20V7H12zM6 19H4v-2h2v2zm0-4H4v-2h2v2zm0-4H4V9h2v2zm0-4H4V5h2v2zm4 12H8v-2h2v2zm0-4H8v-2h2v2zm0-4H8V9h2v2zm0-4H8V5h2v2zm10 12h-8v-2h2v-2h-2v-2h2v-2h-2V9h8v10zm-2-8h-2v2h2v-2zm0 4h-2v2h2v-2z"></path></g>
+      <g id="expand-less"><path d="M12 8l-6 6 1.41 1.41L12 10.83l4.59 4.58L18 14z"></path></g>
+      <g id="expand-more"><path d="M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6z"></path></g>
+      <g id="extension"><path d="M20.5 11H19V7c0-1.1-.9-2-2-2h-4V3.5C13 2.12 11.88 1 10.5 1S8 2.12 8 3.5V5H4c-1.1 0-1.99.9-1.99 2v3.8H3.5c1.49 0 2.7 1.21 2.7 2.7s-1.21 2.7-2.7 2.7H2V20c0 1.1.9 2 2 2h3.8v-1.5c0-1.49 1.21-2.7 2.7-2.7 1.49 0 2.7 1.21 2.7 2.7V22H17c1.1 0 2-.9 2-2v-4h1.5c1.38 0 2.5-1.12 2.5-2.5S21.88 11 20.5 11z"></path></g>
+      <g id="file-download"><path d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"></path></g>
+      <g id="fullscreen"><path d="M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z"></path></g>
+      <g id="group"><path d="M16 11c1.66 0 2.99-1.34 2.99-3S17.66 5 16 5c-1.66 0-3 1.34-3 3s1.34 3 3 3zm-8 0c1.66 0 2.99-1.34 2.99-3S9.66 5 8 5C6.34 5 5 6.34 5 8s1.34 3 3 3zm0 2c-2.33 0-7 1.17-7 3.5V19h14v-2.5c0-2.33-4.67-3.5-7-3.5zm8 0c-.29 0-.62.02-.97.05 1.16.84 1.97 1.97 1.97 3.45V19h6v-2.5c0-2.33-4.67-3.5-7-3.5z"></path></g>
+      <g id="menu"><path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z"></path></g>
+      <g id="more-vert"><path d="M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"></path></g>
+      <g id="open-in-new"><path d="M19 19H5V5h7V3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2v-7h-2v7zM14 3v2h3.59l-9.83 9.83 1.41 1.41L19 6.41V10h2V3h-7z"></path></g>
+      <g id="person"><path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"></path></g>
+      <g id="print"><path d="M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z"></path></g>
+      <g id="search"><path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"></path></g>
+      <g id="settings"><path d="M19.43 12.98c.04-.32.07-.64.07-.98s-.03-.66-.07-.98l2.11-1.65c.19-.15.24-.42.12-.64l-2-3.46c-.12-.22-.39-.3-.61-.22l-2.49 1c-.52-.4-1.08-.73-1.69-.98l-.38-2.65C14.46 2.18 14.25 2 14 2h-4c-.25 0-.46.18-.49.42l-.38 2.65c-.61.25-1.17.59-1.69.98l-2.49-1c-.23-.09-.49 0-.61.22l-2 3.46c-.13.22-.07.49.12.64l2.11 1.65c-.04.32-.07.65-.07.98s.03.66.07.98l-2.11 1.65c-.19.15-.24.42-.12.64l2 3.46c.12.22.39.3.61.22l2.49-1c.52.4 1.08.73 1.69.98l.38 2.65c.03.24.24.42.49.42h4c.25 0 .46-.18.49-.42l.38-2.65c.61-.25 1.17-.59 1.69-.98l2.49 1c.23.09.49 0 .61-.22l2-3.46c.12-.22.07-.49-.12-.64l-2.11-1.65zM12 15.5c-1.93 0-3.5-1.57-3.5-3.5s1.57-3.5 3.5-3.5 3.5 1.57 3.5 3.5-1.57 3.5-3.5 3.5z"></path></g>
+      <g id="star"><path d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z"></path></g>
+      <g id="warning"><path d="M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z"></path></g>
+    </defs>
+  </svg>
+</iron-iconset-svg>
 <dom-module id="paper-ripple" assetpath="chrome://resources/polymer/v1_0/paper-ripple/" css-build="shadow">
 
   <template>
@@ -679,39 +712,6 @@
   </template>
 
   </dom-module>
-<iron-iconset-svg name="cr" size="24">
-  <svg>
-    <defs>
-      
-      <g id="add"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"></path></g>
-      <g id="arrow-drop-down"><path d="M7 10l5 5 5-5z"></path></g>
-      <g id="cancel"><path d="M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z"></path></g>
-<if expr="chromeos">
-      <g id="check"><path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"></path></g>
-</if>
-      <g id="chevron-right"><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"></path></g>
-      <g id="clear"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"></path></g>
-      <g id="close"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"></path></g>
-      <g id="delete"><path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"></path></g>
-      <g id="domain"><path d="M12 7V3H2v18h20V7H12zM6 19H4v-2h2v2zm0-4H4v-2h2v2zm0-4H4V9h2v2zm0-4H4V5h2v2zm4 12H8v-2h2v2zm0-4H8v-2h2v2zm0-4H8V9h2v2zm0-4H8V5h2v2zm10 12h-8v-2h2v-2h-2v-2h2v-2h-2V9h8v10zm-2-8h-2v2h2v-2zm0 4h-2v2h2v-2z"></path></g>
-      <g id="expand-less"><path d="M12 8l-6 6 1.41 1.41L12 10.83l4.59 4.58L18 14z"></path></g>
-      <g id="expand-more"><path d="M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6z"></path></g>
-      <g id="extension"><path d="M20.5 11H19V7c0-1.1-.9-2-2-2h-4V3.5C13 2.12 11.88 1 10.5 1S8 2.12 8 3.5V5H4c-1.1 0-1.99.9-1.99 2v3.8H3.5c1.49 0 2.7 1.21 2.7 2.7s-1.21 2.7-2.7 2.7H2V20c0 1.1.9 2 2 2h3.8v-1.5c0-1.49 1.21-2.7 2.7-2.7 1.49 0 2.7 1.21 2.7 2.7V22H17c1.1 0 2-.9 2-2v-4h1.5c1.38 0 2.5-1.12 2.5-2.5S21.88 11 20.5 11z"></path></g>
-      <g id="file-download"><path d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"></path></g>
-      <g id="fullscreen"><path d="M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z"></path></g>
-      <g id="group"><path d="M16 11c1.66 0 2.99-1.34 2.99-3S17.66 5 16 5c-1.66 0-3 1.34-3 3s1.34 3 3 3zm-8 0c1.66 0 2.99-1.34 2.99-3S9.66 5 8 5C6.34 5 5 6.34 5 8s1.34 3 3 3zm0 2c-2.33 0-7 1.17-7 3.5V19h14v-2.5c0-2.33-4.67-3.5-7-3.5zm8 0c-.29 0-.62.02-.97.05 1.16.84 1.97 1.97 1.97 3.45V19h6v-2.5c0-2.33-4.67-3.5-7-3.5z"></path></g>
-      <g id="menu"><path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z"></path></g>
-      <g id="more-vert"><path d="M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"></path></g>
-      <g id="open-in-new"><path d="M19 19H5V5h7V3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2v-7h-2v7zM14 3v2h3.59l-9.83 9.83 1.41 1.41L19 6.41V10h2V3h-7z"></path></g>
-      <g id="person"><path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"></path></g>
-      <g id="print"><path d="M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z"></path></g>
-      <g id="search"><path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"></path></g>
-      <g id="settings"><path d="M19.43 12.98c.04-.32.07-.64.07-.98s-.03-.66-.07-.98l2.11-1.65c.19-.15.24-.42.12-.64l-2-3.46c-.12-.22-.39-.3-.61-.22l-2.49 1c-.52-.4-1.08-.73-1.69-.98l-.38-2.65C14.46 2.18 14.25 2 14 2h-4c-.25 0-.46.18-.49.42l-.38 2.65c-.61.25-1.17.59-1.69.98l-2.49-1c-.23-.09-.49 0-.61.22l-2 3.46c-.13.22-.07.49.12.64l2.11 1.65c-.04.32-.07.65-.07.98s.03.66.07.98l-2.11 1.65c-.19.15-.24.42-.12.64l2 3.46c.12.22.39.3.61.22l2.49-1c.52.4 1.08.73 1.69.98l.38 2.65c.03.24.24.42.49.42h4c.25 0 .46-.18.49-.42l.38-2.65c.61-.25 1.17-.59 1.69-.98l2.49 1c.23.09.49 0 .61-.22l2-3.46c.12-.22.07-.49-.12-.64l-2.11-1.65zM12 15.5c-1.93 0-3.5-1.57-3.5-3.5s1.57-3.5 3.5-3.5 3.5 1.57 3.5 3.5-1.57 3.5-3.5 3.5z"></path></g>
-      <g id="star"><path d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z"></path></g>
-      <g id="warning"><path d="M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z"></path></g>
-    </defs>
-  </svg>
-</iron-iconset-svg>
 <dom-module id="paper-spinner-styles" assetpath="chrome://resources/polymer/v1_0/paper-spinner/" css-build="shadow">
   <template>
     <style scope="paper-spinner-styles">:host {
@@ -2179,8 +2179,7 @@
 }
 
 button.icon-button iron-icon {
-  color: var(--secondary-text-color);
-        height: 20px;
+  height: 20px;
         width: 20px;
 }
 
@@ -2268,8 +2267,7 @@
 }
 
 button.icon-button iron-icon {
-  color: var(--secondary-text-color);
-        height: 20px;
+  height: 20px;
         width: 20px;
 }
 
@@ -2376,15 +2374,13 @@
 #cancel-icon-button {
   -webkit-margin-end: 24px;
         -webkit-margin-start: 2px;
-        height: 36px;
-        min-width: 36px;
-        width: 36px;
 }
 
-#grouped-nav-container paper-icon-button {
-  --paper-icon-button-ink-color: rgba(255, 255, 255, 0.4);
-        -webkit-margin-start: 24px;
-        flex: 0 0 auto;
+paper-tabs {
+  --paper-tabs-selection-bar-color: #fff;
+        -webkit-margin-start: 32px;
+        height: calc(var(--toolbar-grouped-height) - var(--toolbar-height));
+        min-width: 300px;
 }
 
 paper-tab {
@@ -2393,23 +2389,13 @@
         text-transform: uppercase;
 }
 
-paper-tabs {
-  --paper-tabs-selection-bar-color: var(--google-blue-500);
-        height: calc(var(--toolbar-grouped-height) - var(--toolbar-height));
-        min-width: 300px;
-}
-
 #grouped-buttons-container {
   align-items: center;
         display: flex;
 }
 
-#grouped-range-buttons {
-  -webkit-margin-start: 32px;
-}
-
 #grouped-nav-container {
-  -webkit-margin-end: 24px;
+  -webkit-margin-end: 16px;
         align-items: center;
         display: flex;
         flex: 1;
@@ -2424,7 +2410,8 @@
 }
 
 #grouped-date {
-  flex: 0 1 auto;
+  -webkit-margin-end: 8px;
+        flex: 0 1 auto;
         opacity: 0.7;
         overflow: hidden;
         text-align: right;
@@ -2432,6 +2419,15 @@
         white-space: nowrap;
 }
 
+#grouped-nav-container button {
+  -webkit-margin-start: 8px;
+        flex: 0 0 auto;
+}
+
+#grouped-nav-container button[disabled] {
+  color: rgba(255, 255, 255, 0.5);
+}
+
 :host-context([dir=rtl]) .rtl-reversible {
   transform: rotate(180deg);
 }
@@ -2458,8 +2454,9 @@
       <template is="dom-if" if="[[itemsSelected_]]">
         <div id="overlay-wrapper" hidden$="[[!itemsSelected_]]">
           <div id="overlay-buttons">
-            <paper-icon-button icon="cr:clear" id="cancel-icon-button" on-tap="onClearSelectionTap_" title="$i18n{cancel}">
-            </paper-icon-button>
+            <button is="paper-icon-button-light" id="cancel-icon-button" class="icon-button" on-tap="onClearSelectionTap_" title="$i18n{cancel}">
+              <iron-icon icon="cr:clear"></iron-icon>
+            </button>
             <div id="number-selected">[[numberOfItemsSelected_(count)]]</div>
             <paper-button id="cancel-button" on-tap="onClearSelectionTap_">
               $i18n{cancel}
@@ -2473,7 +2470,7 @@
     </div>
     <template is="dom-if" if="[[isGroupedMode]]">
       <div id="grouped-buttons-container">
-        <paper-tabs attr-for-selected="value" selected="{{groupedRange}}" id="grouped-range-buttons">
+        <paper-tabs attr-for-selected="value" selected="{{groupedRange}}">
           <paper-tab value="0">$i18n{rangeAllTime}</paper-tab>
           <paper-tab value="1">$i18n{rangeWeek}</paper-tab>
           <paper-tab value="2">$i18n{rangeMonth}</paper-tab>
@@ -2482,9 +2479,15 @@
           <span id="grouped-date">
             {{getHistoryInterval_(queryStartTime, queryEndTime)}}
           </span>
-          <paper-icon-button id="today-button" icon="history:today" alt="$i18n{rangeToday}" title="$i18n{rangeToday}" on-tap="onTodayTap_" disabled="[[isToday_(groupedOffset)]]"></paper-icon-button>
-          <paper-icon-button id="prev-button" icon="history:chevron-left" alt="$i18n{rangePrevious}" title="$i18n{rangePrevious}" class="rtl-reversible" on-tap="onPrevTap_" disabled="[[!hasMoreResults]]"></paper-icon-button>
-          <paper-icon-button id="next-button" icon="cr:chevron-right" alt="$i18n{rangeNext}" title="$i18n{rangeNext}" class="rtl-reversible" on-tap="onNextTap_" disabled="[[isToday_(groupedOffset)]]"></paper-icon-button>
+          <button is="paper-icon-button-light" id="today-button" class="icon-button" title="$i18n{rangeToday}" on-tap="onTodayTap_" disabled="[[isToday_(groupedOffset)]]">
+            <iron-icon icon="history:today"></iron-icon>
+          </button>
+          <button is="paper-icon-button-light" id="prev-button" title="$i18n{rangePrevious}" class="icon-button rtl-reversible" on-tap="onPrevTap_" disabled="[[!hasMoreResults]]">
+            <iron-icon icon="history:chevron-left"></iron-icon>
+          </button>
+          <button is="paper-icon-button-light" id="next-button" title="$i18n{rangeNext}" class="icon-button rtl-reversible" on-tap="onNextTap_" disabled="[[isToday_(groupedOffset)]]">
+            <iron-icon icon="cr:chevron-right"></iron-icon>
+          </button>
         </div>
       </div>
     </template>
@@ -2753,8 +2756,7 @@
 }
 
 button.icon-button iron-icon {
-  color: var(--secondary-text-color);
-        height: 20px;
+  height: 20px;
         width: 20px;
 }
 
@@ -3064,8 +3066,7 @@
 }
 
 button.icon-button iron-icon {
-  color: var(--secondary-text-color);
-        height: 20px;
+  height: 20px;
         width: 20px;
 }
 
@@ -3175,8 +3176,7 @@
 }
 
 button.icon-button iron-icon {
-  color: var(--secondary-text-color);
-        height: 20px;
+  height: 20px;
         width: 20px;
 }
 
@@ -3458,8 +3458,7 @@
 }
 
 button.icon-button iron-icon {
-  color: var(--secondary-text-color);
-        height: 20px;
+  height: 20px;
         width: 20px;
 }
 
@@ -3651,8 +3650,7 @@
 }
 
 button.icon-button iron-icon {
-  color: var(--secondary-text-color);
-        height: 20px;
+  height: 20px;
         width: 20px;
 }
 
diff --git a/chrome/browser/resources/md_history/history_toolbar.html b/chrome/browser/resources/md_history/history_toolbar.html
index c5a31c3..b799036 100644
--- a/chrome/browser/resources/md_history/history_toolbar.html
+++ b/chrome/browser/resources/md_history/history_toolbar.html
@@ -1,6 +1,5 @@
 <link rel="import" href="chrome://resources/html/polymer.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button.html">
 <link rel="import" href="chrome://resources/cr_elements/icons.html">
 <link rel="import" href="chrome://resources/cr_elements/cr_lazy_render/cr_lazy_render.html">
 <link rel="import" href="chrome://resources/cr_elements/cr_toolbar/cr_toolbar.html">
@@ -21,6 +20,8 @@
         width: 100%;
       }
 
+      /* General toolbar layout. */
+
       cr-toolbar,
       #overlay-buttons,
       #overlay-wrapper,
@@ -62,6 +63,8 @@
         -webkit-margin-end: 12px;
       }
 
+      /* Info button and dropdown. */
+
       #info-button {
         /* Additional styles for unresolved <button>. */
         background: none;
@@ -92,6 +95,8 @@
         padding: 12px 20px;
       }
 
+      /* Selection overlay. */
+
       :host(:not([has-drawer])) #overlay-wrapper {
         -webkit-margin-start: var(--side-bar-width);
       }
@@ -113,15 +118,16 @@
       #cancel-icon-button {
         -webkit-margin-end: 24px;
         -webkit-margin-start: 2px;
-        height: 36px;
-        min-width: 36px;
-        width: 36px;
       }
 
-      #grouped-nav-container paper-icon-button {
-        --paper-icon-button-ink-color: rgba(255, 255, 255, 0.4);
-        -webkit-margin-start: 24px;
-        flex: 0 0 auto;
+      /* Grouped toolbar. */
+
+      paper-tabs {
+        /* TODO(tsergeant): Align tabs with cards. */
+        --paper-tabs-selection-bar-color: #fff;
+        -webkit-margin-start: 32px;
+        height: calc(var(--toolbar-grouped-height) - var(--toolbar-height));
+        min-width: 300px;
       }
 
       paper-tab {
@@ -130,23 +136,13 @@
         text-transform: uppercase;
       }
 
-      paper-tabs {
-        --paper-tabs-selection-bar-color: var(--google-blue-500);
-        height: calc(var(--toolbar-grouped-height) - var(--toolbar-height));
-        min-width: 300px;
-      }
-
       #grouped-buttons-container {
         align-items: center;
         display: flex;
       }
 
-      #grouped-range-buttons {
-        -webkit-margin-start: 32px;
-      }
-
       #grouped-nav-container {
-        -webkit-margin-end: 24px;
+        -webkit-margin-end: 16px;
         align-items: center;
         display: flex;
         flex: 1;
@@ -161,6 +157,7 @@
       }
 
       #grouped-date {
+        -webkit-margin-end: 8px;
         flex: 0 1 auto;
         opacity: 0.7;
         overflow: hidden;
@@ -169,6 +166,15 @@
         white-space: nowrap;
       }
 
+      #grouped-nav-container button {
+        -webkit-margin-start: 8px;
+        flex: 0 0 auto;
+      }
+
+      #grouped-nav-container button[disabled] {
+        color: rgba(255, 255, 255, 0.5);
+      }
+
       :host-context([dir=rtl]) .rtl-reversible {
         transform: rotate(180deg);
       }
@@ -208,9 +214,13 @@
       <template is="dom-if" if="[[itemsSelected_]]">
         <div id="overlay-wrapper" hidden$="[[!itemsSelected_]]">
           <div id="overlay-buttons">
-            <paper-icon-button icon="cr:clear" id="cancel-icon-button"
-                on-tap="onClearSelectionTap_" title="$i18n{cancel}">
-            </paper-icon-button>
+            <button is="paper-icon-button-light"
+                id="cancel-icon-button"
+                class="icon-button"
+                on-tap="onClearSelectionTap_"
+                title="$i18n{cancel}">
+              <iron-icon icon="cr:clear"></iron-icon>
+            </button>
             <div id="number-selected">[[numberOfItemsSelected_(count)]]</div>
             <paper-button id="cancel-button" on-tap="onClearSelectionTap_">
               $i18n{cancel}
@@ -224,8 +234,7 @@
     </div>
     <template is="dom-if" if="[[isGroupedMode]]">
       <div id="grouped-buttons-container">
-        <paper-tabs attr-for-selected="value" selected="{{groupedRange}}"
-            id="grouped-range-buttons">
+        <paper-tabs attr-for-selected="value" selected="{{groupedRange}}">
           <paper-tab value="0">$i18n{rangeAllTime}</paper-tab>
           <paper-tab value="1">$i18n{rangeWeek}</paper-tab>
           <paper-tab value="2">$i18n{rangeMonth}</paper-tab>
@@ -234,23 +243,30 @@
           <span id="grouped-date">
             {{getHistoryInterval_(queryStartTime, queryEndTime)}}
           </span>
-          <paper-icon-button id="today-button" icon="history:today"
-              alt="$i18n{rangeToday}"
+          <button is="paper-icon-button-light"
+              id="today-button"
+              class="icon-button"
               title="$i18n{rangeToday}"
               on-tap="onTodayTap_"
-              disabled="[[isToday_(groupedOffset)]]"></paper-icon-button>
-          <paper-icon-button id="prev-button" icon="history:chevron-left"
-              alt="$i18n{rangePrevious}"
+              disabled="[[isToday_(groupedOffset)]]">
+            <iron-icon icon="history:today"></iron-icon>
+          </button>
+          <button is="paper-icon-button-light"
+              id="prev-button"
               title="$i18n{rangePrevious}"
-              class="rtl-reversible"
+              class="icon-button rtl-reversible"
               on-tap="onPrevTap_"
-              disabled="[[!hasMoreResults]]"></paper-icon-button>
-          <paper-icon-button id="next-button" icon="cr:chevron-right"
-              alt="$i18n{rangeNext}"
+              disabled="[[!hasMoreResults]]">
+            <iron-icon icon="history:chevron-left"></iron-icon>
+          </button>
+          <button is="paper-icon-button-light"
+              id="next-button"
               title="$i18n{rangeNext}"
-              class="rtl-reversible"
+              class="icon-button rtl-reversible"
               on-tap="onNextTap_"
-              disabled="[[isToday_(groupedOffset)]]"></paper-icon-button>
+              disabled="[[isToday_(groupedOffset)]]">
+            <iron-icon icon="cr:chevron-right"></iron-icon>
+          </button>
         </div>
       </div>
     </template>
diff --git a/chrome/browser/resources/md_history/lazy_load.vulcanized.html b/chrome/browser/resources/md_history/lazy_load.vulcanized.html
index 9c958e04..34b3b41 100644
--- a/chrome/browser/resources/md_history/lazy_load.vulcanized.html
+++ b/chrome/browser/resources/md_history/lazy_load.vulcanized.html
@@ -107,8 +107,7 @@
 }
 
 button.icon-button iron-icon {
-  color: var(--secondary-text-color);
-        height: 20px;
+  height: 20px;
         width: 20px;
 }
 
@@ -658,8 +657,7 @@
 }
 
 button.icon-button iron-icon {
-  color: var(--secondary-text-color);
-        height: 20px;
+  height: 20px;
         width: 20px;
 }
 
@@ -711,6 +709,7 @@
 
 #right-buttons {
   -webkit-margin-end: 4px;
+        color: var(--secondary-text-color);
 }
 
 #menu-button {
@@ -845,8 +844,7 @@
 }
 
 button.icon-button iron-icon {
-  color: var(--secondary-text-color);
-        height: 20px;
+  height: 20px;
         width: 20px;
 }
 
diff --git a/chrome/browser/resources/md_history/shared_style.html b/chrome/browser/resources/md_history/shared_style.html
index 9c6d07c..fc00d7f5 100644
--- a/chrome/browser/resources/md_history/shared_style.html
+++ b/chrome/browser/resources/md_history/shared_style.html
@@ -66,7 +66,6 @@
       }
 
       button.icon-button iron-icon {
-        color: var(--secondary-text-color);
         height: 20px;
         width: 20px;
       }
diff --git a/chrome/browser/resources/md_history/synced_device_card.html b/chrome/browser/resources/md_history/synced_device_card.html
index c7fa695c..e36c0e0 100644
--- a/chrome/browser/resources/md_history/synced_device_card.html
+++ b/chrome/browser/resources/md_history/synced_device_card.html
@@ -48,6 +48,7 @@
 
       #right-buttons {
         -webkit-margin-end: 4px;
+        color: var(--secondary-text-color);
       }
 
       #menu-button {
diff --git a/chrome/browser/resources/omnibox/omnibox.js b/chrome/browser/resources/omnibox/omnibox.js
index 7fa1ef5..11c4a993 100644
--- a/chrome/browser/resources/omnibox/omnibox.js
+++ b/chrome/browser/resources/omnibox/omnibox.js
@@ -415,24 +415,26 @@
 
   function initializeProxies() {
     return importModules([
+      'mojo/public/js/bindings',
       'mojo/public/js/connection',
       'chrome/browser/ui/webui/omnibox/omnibox.mojom',
       'content/public/renderer/frame_interfaces',
     ]).then(function(modules) {
-      var connection = modules[0];
-      var mojom = modules[1];
-      var frameInterfaces = modules[2];
+      var bindings = modules[0];
+      var connection = modules[1];
+      var mojom = modules[2];
+      var frameInterfaces = modules[3];
 
       browserProxy = connection.bindHandleToProxy(
           frameInterfaces.getInterface(mojom.OmniboxPageHandler.name),
           mojom.OmniboxPageHandler);
 
       /** @constructor */
-      var OmniboxPageImpl = function() {};
+      var OmniboxPageImpl = function() {
+        this.binding = new bindings.Binding(mojom.OmniboxPage, this);
+      };
 
       OmniboxPageImpl.prototype = {
-        __proto__: mojom.OmniboxPage.stubClass.prototype,
-
         /** @override */
         handleNewAutocompleteResult: function(result) {
           progressiveAutocompleteResults.push(result);
@@ -441,12 +443,7 @@
       };
 
       pageImpl = new OmniboxPageImpl();
-
-      // Create a message pipe, with one end of the pipe already connected to
-      // JS.
-      var handle = connection.bindStubDerivedImpl(pageImpl);
-      // Send the other end of the pipe to C++.
-      browserProxy.setClientPage(handle);
+      browserProxy.setClientPage(pageImpl.binding.createInterfacePtrAndBind());
     });
   }
 
diff --git a/chrome/browser/resources/plugins.js b/chrome/browser/resources/plugins.js
index 8acef3c7..bffd6bb 100644
--- a/chrome/browser/resources/plugins.js
+++ b/chrome/browser/resources/plugins.js
@@ -227,35 +227,33 @@
 
 function initializeProxies() {
   return importModules([
+    'mojo/public/js/bindings',
     'mojo/public/js/connection',
     'chrome/browser/ui/webui/plugins/plugins.mojom',
     'content/public/renderer/frame_interfaces',
   ]).then(function(modules) {
-    var connection = modules[0];
-    var pluginsMojom = modules[1];
-    var frameInterfaces = modules[2];
+    var bindings = modules[0];
+    var connection = modules[1];
+    var pluginsMojom = modules[2];
+    var frameInterfaces = modules[3];
 
     browserProxy = connection.bindHandleToProxy(
         frameInterfaces.getInterface(pluginsMojom.PluginsPageHandler.name),
         pluginsMojom.PluginsPageHandler);
 
     /** @constructor */
-    var PluginsPageImpl = function() {};
+    var PluginsPageImpl = function() {
+      this.binding = new bindings.Binding(pluginsMojom.PluginsPage, this);
+    };
 
     PluginsPageImpl.prototype = {
-      __proto__: pluginsMojom.PluginsPage.stubClass.prototype,
-
       /** @override */
       onPluginsUpdated: function(plugins) {
         returnPluginsData({plugins: plugins});
       },
     };
     pageImpl = new PluginsPageImpl();
-
-    // Create a message pipe, with one end of the pipe already connected to JS.
-    var handle = connection.bindStubDerivedImpl(pageImpl);
-    // Send the other end of the pipe to C++.
-    browserProxy.setClientPage(handle);
+    browserProxy.setClientPage(pageImpl.binding.createInterfacePtrAndBind());
   });
 }
 
diff --git a/chrome/browser/resources/settings/about_page/channel_switcher_dialog.html b/chrome/browser/resources/settings/about_page/channel_switcher_dialog.html
index a04b0f5ab..1edbba0 100644
--- a/chrome/browser/resources/settings/about_page/channel_switcher_dialog.html
+++ b/chrome/browser/resources/settings/about_page/channel_switcher_dialog.html
@@ -9,7 +9,11 @@
 
 <dom-module id="settings-channel-switcher-dialog">
   <template>
-    <style include="settings-shared"></style>
+    <style include="settings-shared">
+      dialog {
+        width: 600px;
+      }
+    </style>
     <dialog is="cr-dialog" id="dialog">
       <div class="title">$i18n{aboutChangeChannel}</div>
       <div class="body">
@@ -19,13 +23,13 @@
         <paper-radio-group
             on-paper-radio-group-changed="onChannelSelectionChanged_">
           <paper-radio-button name="[[browserChannelEnum_.STABLE]]">
-            $i18n{aboutChannelStable}
+            $i18n{aboutChannelDialogStable}
           </paper-radio-button>
           <paper-radio-button name="[[browserChannelEnum_.BETA]]">
-            $i18n{aboutChannelBeta}
+            $i18n{aboutChannelDialogBeta}
           </paper-radio-button>
           <paper-radio-button name="[[browserChannelEnum_.DEV]]">
-            $i18n{aboutChannelDev}
+            $i18n{aboutChannelDialogDev}
           </paper-radio-button>
         </paper-radio-group>
         <div id="warning" hidden="[[!shouldShowWarning_(warning_)]]">
diff --git a/chrome/browser/safe_browsing/certificate_reporting_service.cc b/chrome/browser/safe_browsing/certificate_reporting_service.cc
index 52a20c7..0a84e0e 100644
--- a/chrome/browser/safe_browsing/certificate_reporting_service.cc
+++ b/chrome/browser/safe_browsing/certificate_reporting_service.cc
@@ -2,12 +2,20 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "base/bind_helpers.h"
 #include "base/time/clock.h"
 #include "base/time/default_clock.h"
 #include "chrome/browser/safe_browsing/certificate_reporting_service.h"
 #include "content/public/browser/browser_thread.h"
 
 namespace {
+
+// URL to upload invalid certificate chain reports. An HTTP URL is used because
+// a client seeing an invalid cert might not be able to make an HTTPS connection
+// to report it.
+const char kExtendedReportingUploadUrl[] =
+    "http://safebrowsing.googleusercontent.com/safebrowsing/clientreport/";
+
 // Compare function that orders Reports in reverse chronological order (i.e.
 // oldest item is last).
 bool ReportCompareFunc(const CertificateReportingService::Report& item1,
@@ -57,11 +65,13 @@
     std::unique_ptr<certificate_reporting::ErrorReporter> error_reporter,
     std::unique_ptr<BoundedReportList> retry_list,
     base::Clock* clock,
-    base::TimeDelta report_ttl)
+    base::TimeDelta report_ttl,
+    bool retries_enabled)
     : error_reporter_(std::move(error_reporter)),
       retry_list_(std::move(retry_list)),
-      test_clock_(clock),
+      clock_(clock),
       report_ttl_(report_ttl),
+      retries_enabled_(retries_enabled),
       current_report_id_(0),
       weak_factory_(this) {}
 
@@ -70,15 +80,15 @@
 void CertificateReportingService::Reporter::Send(
     const std::string& serialized_report) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-  base::Time now =
-      test_clock_ ? test_clock_->Now() : base::Time::NowFromSystemTime();
-  SendInternal(Report(current_report_id_++, now, serialized_report));
+  SendInternal(Report(current_report_id_++, clock_->Now(), serialized_report));
 }
 
 void CertificateReportingService::Reporter::SendPending() {
   DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-  base::Time now =
-      test_clock_ ? test_clock_->Now() : base::Time::NowFromSystemTime();
+  if (!retries_enabled_) {
+    return;
+  }
+  const base::Time now = clock_->Now();
   // Copy pending reports and clear the retry list.
   std::vector<Report> items = retry_list_->items();
   retry_list_->Clear();
@@ -118,9 +128,11 @@
                                                           const GURL& url,
                                                           int error) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-  auto it = inflight_reports_.find(report_id);
-  DCHECK(it != inflight_reports_.end());
-  retry_list_->Add(it->second);
+  if (retries_enabled_) {
+    auto it = inflight_reports_.find(report_id);
+    DCHECK(it != inflight_reports_.end());
+    retry_list_->Add(it->second);
+  }
   CHECK_GT(inflight_reports_.erase(report_id), 0u);
 }
 
@@ -128,3 +140,159 @@
   DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
   CHECK_GT(inflight_reports_.erase(report_id), 0u);
 }
+
+CertificateReportingService::CertificateReportingService(
+    scoped_refptr<net::URLRequestContextGetter> url_request_context_getter,
+    uint8_t server_public_key[/* 32 */],
+    uint32_t server_public_key_version,
+    size_t max_queued_report_count,
+    base::TimeDelta max_report_age,
+    std::unique_ptr<base::Clock> clock)
+    : enabled_(true),
+      url_request_context_(nullptr),
+      max_queued_report_count_(max_queued_report_count),
+      max_report_age_(max_report_age),
+      clock_(std::move(clock)),
+      made_send_attempt_(false),
+      server_public_key_(server_public_key),
+      server_public_key_version_(server_public_key_version) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  content::BrowserThread::PostTask(
+      content::BrowserThread::IO, FROM_HERE,
+      base::Bind(&CertificateReportingService::InitializeOnIOThread,
+                 base::Unretained(this), enabled_, url_request_context_getter,
+                 max_queued_report_count_, max_report_age_, clock_.get(),
+                 server_public_key_, server_public_key_version_));
+}
+
+CertificateReportingService::~CertificateReportingService() {
+  DCHECK(!reporter_);
+}
+
+void CertificateReportingService::Shutdown() {
+  // Shutdown will be called twice: Once after SafeBrowsing shuts down, and once
+  // when all KeyedServices shut down. All calls after the first one are no-op.
+  enabled_ = false;
+  Reset();
+}
+
+void CertificateReportingService::Send(const std::string& serialized_report) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  made_send_attempt_ = true;
+  if (!reporter_) {
+    return;
+  }
+  content::BrowserThread::PostTask(
+      content::BrowserThread::IO, FROM_HERE,
+      base::Bind(&CertificateReportingService::Reporter::Send,
+                 base::Unretained(reporter_.get()), serialized_report));
+}
+
+void CertificateReportingService::SendPending() {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  made_send_attempt_ = true;
+  if (!reporter_) {
+    return;
+  }
+  content::BrowserThread::PostTask(
+      content::BrowserThread::IO, FROM_HERE,
+      base::Bind(&CertificateReportingService::Reporter::SendPending,
+                 base::Unretained(reporter_.get())));
+}
+
+void CertificateReportingService::InitializeOnIOThread(
+    bool enabled,
+    scoped_refptr<net::URLRequestContextGetter> url_request_context_getter,
+    size_t max_queued_report_count,
+    base::TimeDelta max_report_age,
+    base::Clock* clock,
+    uint8_t* server_public_key,
+    uint32_t server_public_key_version) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+  DCHECK(!url_request_context_);
+  url_request_context_ = url_request_context_getter->GetURLRequestContext();
+  ResetOnIOThread(enabled, url_request_context_, max_queued_report_count,
+                  max_report_age, clock, server_public_key,
+                  server_public_key_version);
+}
+
+void CertificateReportingService::SetEnabled(bool enabled) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  enabled_ = enabled;
+  Reset();
+}
+
+CertificateReportingService::Reporter*
+CertificateReportingService::GetReporterForTesting() const {
+  return reporter_.get();
+}
+
+void CertificateReportingService::SetMaxQueuedReportCountForTesting(
+    size_t count) {
+  DCHECK(!made_send_attempt_);
+  max_queued_report_count_ = count;
+  Reset();
+}
+
+void CertificateReportingService::SetClockForTesting(
+    std::unique_ptr<base::Clock> clock) {
+  DCHECK(!made_send_attempt_);
+  clock_ = std::move(clock);
+  Reset();
+}
+
+void CertificateReportingService::SetMaxReportAgeForTesting(
+    base::TimeDelta max_report_age) {
+  DCHECK(!made_send_attempt_);
+  max_report_age_ = max_report_age;
+  Reset();
+}
+
+// static
+GURL CertificateReportingService::GetReportingURLForTesting() {
+  return GURL(kExtendedReportingUploadUrl);
+}
+
+void CertificateReportingService::Reset() {
+  content::BrowserThread::PostTask(
+      content::BrowserThread::IO, FROM_HERE,
+      base::Bind(&CertificateReportingService::ResetOnIOThread,
+                 base::Unretained(this), enabled_, url_request_context_,
+                 max_queued_report_count_, max_report_age_, clock_.get(),
+                 server_public_key_, server_public_key_version_));
+}
+
+void CertificateReportingService::ResetOnIOThread(
+    bool enabled,
+    net::URLRequestContext* url_request_context,
+    size_t max_queued_report_count,
+    base::TimeDelta max_report_age,
+    base::Clock* clock,
+    uint8_t* const server_public_key,
+    uint32_t server_public_key_version) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+  // url_request_context_ is null during shutdown.
+  if (!enabled || !url_request_context) {
+    reporter_.reset(nullptr);
+    return;
+  }
+  std::unique_ptr<certificate_reporting::ErrorReporter> error_reporter;
+  if (server_public_key) {
+    // Only used in tests.
+    std::unique_ptr<net::ReportSender> report_sender(new net::ReportSender(
+        url_request_context, net::ReportSender::DO_NOT_SEND_COOKIES));
+    error_reporter.reset(new certificate_reporting::ErrorReporter(
+        GURL(kExtendedReportingUploadUrl), server_public_key,
+        server_public_key_version, std::move(report_sender)));
+  } else {
+    error_reporter.reset(new certificate_reporting::ErrorReporter(
+        url_request_context, GURL(kExtendedReportingUploadUrl),
+        net::ReportSender::DO_NOT_SEND_COOKIES));
+  }
+
+  reporter_.reset(
+      new Reporter(std::move(error_reporter),
+                   std::unique_ptr<BoundedReportList>(
+                       new BoundedReportList(max_queued_report_count)),
+                   clock, max_report_age, true /* retries_enabled */));
+}
diff --git a/chrome/browser/safe_browsing/certificate_reporting_service.h b/chrome/browser/safe_browsing/certificate_reporting_service.h
index 4c1e4cd2..6c45e7e 100644
--- a/chrome/browser/safe_browsing/certificate_reporting_service.h
+++ b/chrome/browser/safe_browsing/certificate_reporting_service.h
@@ -16,16 +16,31 @@
 #include "base/time/time.h"
 #include "components/certificate_reporting/error_reporter.h"
 #include "components/keyed_service/core/keyed_service.h"
+#include "net/url_request/url_request_context_getter.h"
 
 namespace base {
 class Clock;
 }
 
+namespace net {
+class URLRequestContextGetter;
+}
+
 // This service initiates uploads of invalid certificate reports and retries any
-// failed uploads.
+// failed uploads. Each report is retried until it's older than a certain time
+// to live (TTL). Reports older than this TTL are dropped and no more retried,
+// so that the retry list doesn't grow indefinitely.
+//
+// Lifetime and dependencies:
+//
+// CertificateReportingService uses the url request context from SafeBrowsing
+// service. SafeBrowsing service is created before CertificateReportingService,
+// but is also shut down before any KeyedService is shut down. This means that
+// CertificateReportingService cannot depend on SafeBrowsing's url request being
+// available at all times, and it should know when SafeBrowsing shuts down.
 class CertificateReportingService : public KeyedService {
  public:
-  // Represent a report to be sent.
+  // Represents a report to be sent.
   struct Report {
     int report_id;
     base::Time creation_time;
@@ -64,6 +79,8 @@
 
     std::vector<Report> items_;
     base::ThreadChecker thread_checker_;
+
+    DISALLOW_COPY_AND_ASSIGN(BoundedReportList);
   };
 
   // Class that handles report uploads and implements the upload retry logic.
@@ -73,7 +90,8 @@
         std::unique_ptr<certificate_reporting::ErrorReporter> error_reporter_,
         std::unique_ptr<BoundedReportList> retry_list,
         base::Clock* clock,
-        base::TimeDelta report_ttl);
+        base::TimeDelta report_ttl,
+        bool retries_enabled);
     ~Reporter();
 
     // Sends a report. If the send fails, the report will be added to the retry
@@ -96,16 +114,105 @@
 
     std::unique_ptr<certificate_reporting::ErrorReporter> error_reporter_;
     std::unique_ptr<BoundedReportList> retry_list_;
-    base::Clock* test_clock_;
+    base::Clock* clock_;
+    // Maximum age of a queued report. Reports older than this are discarded in
+    // the next SendPending() call.
     const base::TimeDelta report_ttl_;
+    const bool retries_enabled_;
+    // Current report id, starting from zero and monotonically incrementing.
     int current_report_id_;
 
     std::map<int, Report> inflight_reports_;
 
     base::WeakPtrFactory<Reporter> weak_factory_;
 
-    DISALLOW_IMPLICIT_CONSTRUCTORS(Reporter);
+    DISALLOW_COPY_AND_ASSIGN(Reporter);
   };
+
+  CertificateReportingService(
+      scoped_refptr<net::URLRequestContextGetter> url_request_context_getter,
+      uint8_t server_public_key[/* 32 */],
+      uint32_t server_public_key_version,
+      size_t max_queued_report_count,
+      base::TimeDelta max_report_age,
+      std::unique_ptr<base::Clock> clock);
+
+  ~CertificateReportingService() override;
+
+  // KeyedService implementation:
+  void Shutdown() override;
+
+  // Sends a serialized report. If the report upload fails, the upload is
+  // retried at a future time.
+  void Send(const std::string& serialized_report);
+
+  // Sends pending reports that are in the retry queue.
+  void SendPending();
+
+  // Enables or disables reporting. When disabled, pending report queue is
+  // cleared and incoming reports are ignored. Reporting is enabled by default
+  // once the service is initialized.
+  void SetEnabled(bool enabled);
+
+  // Getters and setters for testing.
+  Reporter* GetReporterForTesting() const;
+  void SetMaxQueuedReportCountForTesting(size_t max_report_count);
+  void SetClockForTesting(std::unique_ptr<base::Clock> clock);
+  void SetMaxReportAgeForTesting(base::TimeDelta max_report_age);
+
+  static GURL GetReportingURLForTesting();
+
+ private:
+  void Reset();
+
+  void InitializeOnIOThread(
+      bool enabled,
+      scoped_refptr<net::URLRequestContextGetter> url_request_context_getter,
+      size_t max_queued_report_count,
+      base::TimeDelta max_report_age,
+      base::Clock* clock,
+      uint8_t* server_public_key,
+      uint32_t server_public_key_version);
+
+  // Resets the reporter on the IO thread. Changes in SafeBrowsing or extended
+  // reporting enabled states cause the reporter to be reset.
+  // If |enabled| is false or |url_request_context_getter| is null, report is
+  // set to null, effectively cancelling all in flight uploads and clearing the
+  // pending reports queue.
+  void ResetOnIOThread(bool enabled,
+                       net::URLRequestContext* url_request_context,
+                       size_t max_queued_report_count,
+                       base::TimeDelta max_report_age,
+                       base::Clock* clock,
+                       uint8_t* server_public_key,
+                       uint32_t server_public_key_version);
+
+  // If true, reporting is enabled. When SafeBrowsing preferences change, this
+  // might be set to false.
+  bool enabled_;
+
+  net::URLRequestContext* url_request_context_;
+  std::unique_ptr<Reporter> reporter_;
+
+  // Maximum number of reports to be queued for retry.
+  size_t max_queued_report_count_;
+
+  // Maximum age of the reports to be queued for retry, from the time the
+  // certificate error was first encountered by the user. Any report older than
+  // this age is ignored and is not re-uploaded.
+  base::TimeDelta max_report_age_;
+
+  std::unique_ptr<base::Clock> clock_;
+
+  // Whether a send has ever been made. Used to verify that test setters are
+  // only called after initialization.
+  bool made_send_attempt_;
+
+  // Encryption parameters.
+  uint8_t* server_public_key_;
+  uint32_t server_public_key_version_;
+
+  DISALLOW_COPY_AND_ASSIGN(CertificateReportingService);
 };
 
 #endif  // CHROME_BROWSER_SAFE_BROWSING_CERTIFICATE_REPORTING_SERVICE_H_
diff --git a/chrome/browser/safe_browsing/certificate_reporting_service_factory.cc b/chrome/browser/safe_browsing/certificate_reporting_service_factory.cc
index bed32fd..fc1eab1 100644
--- a/chrome/browser/safe_browsing/certificate_reporting_service_factory.cc
+++ b/chrome/browser/safe_browsing/certificate_reporting_service_factory.cc
@@ -29,7 +29,8 @@
 
 KeyedService* CertificateReportingServiceFactory::BuildServiceInstanceFor(
     content::BrowserContext* profile) const {
-  return new CertificateReportingService();
+  // TODO(crbug.com/554323): Create a real CertificateReportingService here.
+  return nullptr;
 }
 
 content::BrowserContext*
diff --git a/chrome/browser/safe_browsing/certificate_reporting_service_test_utils.cc b/chrome/browser/safe_browsing/certificate_reporting_service_test_utils.cc
new file mode 100644
index 0000000..780f8d50
--- /dev/null
+++ b/chrome/browser/safe_browsing/certificate_reporting_service_test_utils.cc
@@ -0,0 +1,386 @@
+// 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 "chrome/browser/safe_browsing/certificate_reporting_service_test_utils.h"
+
+#include "base/threading/thread_task_runner_handle.h"
+#include "components/certificate_reporting/encrypted_cert_logger.pb.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/test/test_utils.h"
+#include "crypto/curve25519.h"
+#include "net/base/upload_bytes_element_reader.h"
+#include "net/base/upload_data_stream.h"
+#include "net/test/url_request/url_request_failed_job.h"
+#include "net/test/url_request/url_request_mock_data_job.h"
+#include "net/url_request/url_request_filter.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+const uint32_t kServerPublicKeyTestVersion = 16;
+
+void SetUpURLHandlersOnIOThread(
+    std::unique_ptr<net::URLRequestInterceptor> url_request_interceptor) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+  net::URLRequestFilter* filter = net::URLRequestFilter::GetInstance();
+  filter->AddUrlInterceptor(
+      CertificateReportingService::GetReportingURLForTesting(),
+      std::move(url_request_interceptor));
+}
+
+std::string GetUploadData(net::URLRequest* request) {
+  const net::UploadDataStream* stream = request->get_upload();
+  EXPECT_TRUE(stream);
+  EXPECT_TRUE(stream->GetElementReaders());
+  EXPECT_EQ(1u, stream->GetElementReaders()->size());
+  const net::UploadBytesElementReader* reader =
+      (*stream->GetElementReaders())[0]->AsBytesReader();
+  return std::string(reader->bytes(), reader->length());
+}
+
+std::string GetReportContents(net::URLRequest* request,
+                              const uint8_t* server_private_key) {
+  std::string serialized_report(GetUploadData(request));
+  certificate_reporting::EncryptedCertLoggerRequest encrypted_request;
+  EXPECT_TRUE(encrypted_request.ParseFromString(serialized_report));
+  EXPECT_EQ(kServerPublicKeyTestVersion,
+            encrypted_request.server_public_key_version());
+  EXPECT_EQ(certificate_reporting::EncryptedCertLoggerRequest::
+                AEAD_ECDH_AES_128_CTR_HMAC_SHA256,
+            encrypted_request.algorithm());
+  std::string decrypted_report;
+  certificate_reporting::ErrorReporter::DecryptErrorReport(
+      server_private_key, encrypted_request, &decrypted_report);
+  return decrypted_report;
+}
+
+}  // namespace
+
+namespace certificate_reporting_test_utils {
+
+DelayableCertReportURLRequestJob::DelayableCertReportURLRequestJob(
+    net::URLRequest* request,
+    net::NetworkDelegate* network_delegate)
+    : net::URLRequestJob(request, network_delegate), weak_factory_(this) {}
+
+DelayableCertReportURLRequestJob::~DelayableCertReportURLRequestJob() {}
+
+base::WeakPtr<DelayableCertReportURLRequestJob>
+DelayableCertReportURLRequestJob::GetWeakPtr() {
+  return weak_factory_.GetWeakPtr();
+}
+
+void DelayableCertReportURLRequestJob::Start() {
+  started_ = true;
+  if (delayed_) {
+    // Do nothing until Resume() is called.
+    return;
+  }
+  Resume();
+}
+
+int DelayableCertReportURLRequestJob::ReadRawData(net::IOBuffer* buf,
+                                                  int buf_size) {
+  // Report sender ignores responses. Return empty response.
+  return 0;
+}
+
+int DelayableCertReportURLRequestJob::GetResponseCode() const {
+  // Report sender ignores responses. Return empty response.
+  return 200;
+}
+
+void DelayableCertReportURLRequestJob::GetResponseInfo(
+    net::HttpResponseInfo* info) {
+  // Report sender ignores responses. Return empty response.
+}
+
+void DelayableCertReportURLRequestJob::Resume() {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+  DCHECK(delayed_);
+  if (!started_) {
+    // If Start() hasn't been called yet, then unset |delayed_| so
+    // that when Start() is called, the request will begin
+    // immediately.
+    delayed_ = false;
+    return;
+  }
+  // Start reading asynchronously as would a normal network request.
+  base::ThreadTaskRunnerHandle::Get()->PostTask(
+      FROM_HERE,
+      base::Bind(&DelayableCertReportURLRequestJob::NotifyHeadersComplete,
+                 weak_factory_.GetWeakPtr()));
+}
+
+CertReportJobInterceptor::CertReportJobInterceptor(
+    ReportSendingResult expected_report_result,
+    const uint8_t* server_private_key)
+    : expected_report_result_(expected_report_result),
+      server_private_key_(server_private_key),
+      weak_factory_(this) {}
+
+CertReportJobInterceptor::~CertReportJobInterceptor() {}
+
+net::URLRequestJob* CertReportJobInterceptor::MaybeInterceptRequest(
+    net::URLRequest* request,
+    net::NetworkDelegate* network_delegate) const {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+
+  const std::string uploaded_report =
+      GetReportContents(request, server_private_key_);
+  content::BrowserThread::PostTask(
+      content::BrowserThread::UI, FROM_HERE,
+      base::Bind(&CertReportJobInterceptor::RequestCreated,
+                 weak_factory_.GetWeakPtr(), uploaded_report,
+                 expected_report_result_));
+
+  if (expected_report_result_ == REPORTS_FAIL) {
+    return new net::URLRequestFailedJob(request, network_delegate,
+                                        net::ERR_SSL_PROTOCOL_ERROR);
+  } else if (expected_report_result_ == REPORTS_DELAY) {
+    DCHECK(!delayed_request_) << "Supports only one delayed request at a time";
+    DelayableCertReportURLRequestJob* job =
+        new DelayableCertReportURLRequestJob(request, network_delegate);
+    delayed_request_ = job->GetWeakPtr();
+    return job;
+  }
+  // Successful url request job.
+  return new net::URLRequestMockDataJob(request, network_delegate, "some data",
+                                        1, false);
+}
+
+void CertReportJobInterceptor::SetFailureMode(
+    ReportSendingResult expected_report_result) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  content::BrowserThread::PostTask(
+      content::BrowserThread::IO, FROM_HERE,
+      base::Bind(&CertReportJobInterceptor::SetFailureModeOnIOThread,
+                 weak_factory_.GetWeakPtr(), expected_report_result));
+}
+
+void CertReportJobInterceptor::Resume() {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  content::BrowserThread::PostTask(
+      content::BrowserThread::IO, FROM_HERE,
+      base::Bind(&CertReportJobInterceptor::ResumeOnIOThread,
+                 base::Unretained(this)));
+}
+
+const std::set<std::string>& CertReportJobInterceptor::successful_reports()
+    const {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  return successful_reports_;
+}
+
+const std::set<std::string>& CertReportJobInterceptor::failed_reports() const {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  return failed_reports_;
+}
+
+const std::set<std::string>& CertReportJobInterceptor::delayed_reports() const {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  return delayed_reports_;
+}
+
+void CertReportJobInterceptor::ClearObservedReports() {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  successful_reports_.clear();
+  failed_reports_.clear();
+  delayed_reports_.clear();
+}
+
+void CertReportJobInterceptor::SetFailureModeOnIOThread(
+    ReportSendingResult expected_report_result) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+  expected_report_result_ = expected_report_result;
+}
+
+void CertReportJobInterceptor::ResumeOnIOThread() {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+  EXPECT_EQ(REPORTS_DELAY, expected_report_result_);
+  if (delayed_request_)
+    delayed_request_->Resume();
+}
+
+void CertReportJobInterceptor::RequestCreated(
+    const std::string& uploaded_report,
+    ReportSendingResult expected_report_result) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  switch (expected_report_result) {
+    case REPORTS_SUCCESSFUL:
+      successful_reports_.insert(uploaded_report);
+      break;
+    case REPORTS_FAIL:
+      failed_reports_.insert(uploaded_report);
+      break;
+    case REPORTS_DELAY:
+      delayed_reports_.insert(uploaded_report);
+      break;
+  }
+}
+
+CertificateReportingServiceTestNetworkDelegate::
+    CertificateReportingServiceTestNetworkDelegate(
+        const base::Callback<void()>& url_request_destroyed_callback)
+    : url_request_destroyed_callback_(url_request_destroyed_callback) {}
+
+CertificateReportingServiceTestNetworkDelegate::
+    ~CertificateReportingServiceTestNetworkDelegate() {}
+
+void CertificateReportingServiceTestNetworkDelegate::OnURLRequestDestroyed(
+    net::URLRequest* request) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+  content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
+                                   url_request_destroyed_callback_);
+}
+
+CertificateReportingServiceTestBase::ReportExpectation::ReportExpectation() {}
+
+CertificateReportingServiceTestBase::ReportExpectation::ReportExpectation(
+    const ReportExpectation& other) = default;
+
+CertificateReportingServiceTestBase::ReportExpectation::~ReportExpectation() {}
+
+// static
+CertificateReportingServiceTestBase::ReportExpectation
+CertificateReportingServiceTestBase::ReportExpectation::Successful(
+    const std::set<std::string>& reports) {
+  ReportExpectation expectation;
+  expectation.successful_reports = reports;
+  return expectation;
+}
+
+// static
+CertificateReportingServiceTestBase::ReportExpectation
+CertificateReportingServiceTestBase::ReportExpectation::Failed(
+    const std::set<std::string>& reports) {
+  ReportExpectation expectation;
+  expectation.failed_reports = reports;
+  return expectation;
+}
+
+// static
+CertificateReportingServiceTestBase::ReportExpectation
+CertificateReportingServiceTestBase::ReportExpectation::Delayed(
+    const std::set<std::string>& reports) {
+  ReportExpectation expectation;
+  expectation.delayed_reports = reports;
+  return expectation;
+}
+
+CertificateReportingServiceTestBase::CertificateReportingServiceTestBase()
+    : num_request_deletions_to_wait_for_(0), num_deleted_requests_(0) {
+  memset(server_private_key_, 1, sizeof(server_private_key_));
+  crypto::curve25519::ScalarBaseMult(server_private_key_, server_public_key_);
+}
+
+CertificateReportingServiceTestBase::~CertificateReportingServiceTestBase() {}
+
+void CertificateReportingServiceTestBase::SetUpInterceptor() {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  url_request_interceptor_ =
+      new CertReportJobInterceptor(REPORTS_FAIL, server_private_key_);
+  content::BrowserThread::PostTask(
+      content::BrowserThread::IO, FROM_HERE,
+      base::Bind(
+          &CertificateReportingServiceTestBase::SetUpInterceptorOnIOThread,
+          base::Unretained(this),
+          base::Passed(std::unique_ptr<net::URLRequestInterceptor>(
+              url_request_interceptor_))));
+}
+
+void CertificateReportingServiceTestBase::TearDownInterceptor() {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  content::BrowserThread::PostTask(
+      content::BrowserThread::IO, FROM_HERE,
+      base::Bind(
+          &CertificateReportingServiceTestBase::TearDownInterceptorOnIOThread,
+          base::Unretained(this)));
+}
+
+// Changes the behavior of report uploads to fail or succeed.
+void CertificateReportingServiceTestBase::SetFailureMode(
+    ReportSendingResult expected_report_result) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  url_request_interceptor_->SetFailureMode(expected_report_result);
+}
+
+void CertificateReportingServiceTestBase::ResumeDelayedRequest() {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  url_request_interceptor_->Resume();
+}
+
+void CertificateReportingServiceTestBase::WaitForRequestsDestroyed(
+    const ReportExpectation& expectation) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  DCHECK(!run_loop_);
+
+  const int num_request_deletions_to_wait_for =
+      expectation.successful_reports.size() +
+      expectation.failed_reports.size() + expectation.delayed_reports.size();
+
+  ASSERT_LE(num_deleted_requests_, num_request_deletions_to_wait_for)
+      << "Observed unexpected report";
+  if (num_deleted_requests_ < num_request_deletions_to_wait_for) {
+    num_request_deletions_to_wait_for_ = num_request_deletions_to_wait_for;
+    run_loop_.reset(new base::RunLoop());
+    run_loop_->Run();
+    run_loop_.reset(nullptr);
+    EXPECT_EQ(0, num_deleted_requests_);
+    EXPECT_EQ(0, num_request_deletions_to_wait_for_);
+  } else if (num_deleted_requests_ == num_request_deletions_to_wait_for) {
+    num_deleted_requests_ = 0;
+    num_request_deletions_to_wait_for_ = 0;
+  }
+  EXPECT_EQ(expectation.successful_reports,
+            url_request_interceptor_->successful_reports());
+  EXPECT_EQ(expectation.failed_reports,
+            url_request_interceptor_->failed_reports());
+  EXPECT_EQ(expectation.delayed_reports,
+            url_request_interceptor_->delayed_reports());
+  url_request_interceptor_->ClearObservedReports();
+}
+
+uint8_t* CertificateReportingServiceTestBase::server_public_key() {
+  return server_public_key_;
+}
+
+uint32_t CertificateReportingServiceTestBase::server_public_key_version()
+    const {
+  return kServerPublicKeyTestVersion;
+}
+
+net::NetworkDelegate* CertificateReportingServiceTestBase::network_delegate() {
+  return network_delegate_.get();
+}
+
+void CertificateReportingServiceTestBase::SetUpInterceptorOnIOThread(
+    std::unique_ptr<net::URLRequestInterceptor> url_request_interceptor) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+  network_delegate_.reset(new CertificateReportingServiceTestNetworkDelegate(
+      base::Bind(&CertificateReportingServiceTestBase::OnURLRequestDestroyed,
+                 base::Unretained(this))));
+  SetUpURLHandlersOnIOThread(std::move(url_request_interceptor));
+}
+
+void CertificateReportingServiceTestBase::TearDownInterceptorOnIOThread() {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+  network_delegate_.reset(nullptr);
+}
+
+void CertificateReportingServiceTestBase::OnURLRequestDestroyed() {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  num_deleted_requests_++;
+  if (!run_loop_) {
+    return;
+  }
+  EXPECT_LE(num_deleted_requests_, num_request_deletions_to_wait_for_);
+  if (num_deleted_requests_ == num_request_deletions_to_wait_for_) {
+    num_request_deletions_to_wait_for_ = 0;
+    num_deleted_requests_ = 0;
+    run_loop_->Quit();
+  }
+}
+
+}  // namespace certificate_reporting_test_utils
diff --git a/chrome/browser/safe_browsing/certificate_reporting_service_test_utils.h b/chrome/browser/safe_browsing/certificate_reporting_service_test_utils.h
new file mode 100644
index 0000000..1d2f6cc
--- /dev/null
+++ b/chrome/browser/safe_browsing/certificate_reporting_service_test_utils.h
@@ -0,0 +1,199 @@
+// 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 CHROME_BROWSER_SAFE_BROWSING_CERTIFICATE_REPORTING_SERVICE_TEST_UTILS_H_
+#define CHROME_BROWSER_SAFE_BROWSING_CERTIFICATE_REPORTING_SERVICE_TEST_UTILS_H_
+
+#include <set>
+
+#include "base/macros.h"
+#include "base/run_loop.h"
+#include "chrome/browser/safe_browsing/certificate_reporting_service.h"
+#include "content/public/test/test_browser_thread.h"
+#include "content/public/test/test_browser_thread_bundle.h"
+#include "net/base/network_delegate_impl.h"
+#include "net/url_request/url_request_interceptor.h"
+#include "net/url_request/url_request_job.h"
+
+namespace net {
+class NetworkDelegate;
+}
+
+namespace certificate_reporting_test_utils {
+
+// Failure mode of the report sending attempts.
+enum ReportSendingResult {
+  // Report send attempts should be successful.
+  REPORTS_SUCCESSFUL,
+  // Report send attempts should fail.
+  REPORTS_FAIL,
+  // Report send attempts should hang until explicitly resumed.
+  REPORTS_DELAY,
+};
+
+// A URLRequestJob that can be delayed until Resume() is called. Returns an
+// empty response. If Resume() is called before a request is made, then the
+// request will not be delayed.
+class DelayableCertReportURLRequestJob : public net::URLRequestJob {
+ public:
+  DelayableCertReportURLRequestJob(net::URLRequest* request,
+                                   net::NetworkDelegate* network_delegate);
+  ~DelayableCertReportURLRequestJob() override;
+
+  base::WeakPtr<DelayableCertReportURLRequestJob> GetWeakPtr();
+
+  // net::URLRequestJob methods:
+  void Start() override;
+  int ReadRawData(net::IOBuffer* buf, int buf_size) override;
+  int GetResponseCode() const override;
+  void GetResponseInfo(net::HttpResponseInfo* info) override;
+
+  // Resumes a previously started request that was delayed. If no
+  // request has been started yet, then when Start() is called it will
+  // not delay.
+  void Resume();
+
+ private:
+  bool delayed_ = true;
+  bool started_ = false;
+  base::WeakPtrFactory<DelayableCertReportURLRequestJob> weak_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(DelayableCertReportURLRequestJob);
+};
+
+// A job interceptor that returns a failed, succesful or delayed request job.
+// Used to simulate report uploads that fail, succeed or hang.
+class CertReportJobInterceptor : public net::URLRequestInterceptor {
+ public:
+  CertReportJobInterceptor(ReportSendingResult expected_report_result,
+                           const uint8_t* server_private_key);
+  ~CertReportJobInterceptor() override;
+
+  // net::URLRequestInterceptor method:
+  net::URLRequestJob* MaybeInterceptRequest(
+      net::URLRequest* request,
+      net::NetworkDelegate* network_delegate) const override;
+
+  // Sets the failure mode for reports. Must be called on the UI thread.
+  void SetFailureMode(ReportSendingResult expected_report_result);
+  // Resumes any hanging URL request. Must be called on the UI thread.
+  void Resume();
+
+  // These must be called on the UI thread.
+  const std::set<std::string>& successful_reports() const;
+  const std::set<std::string>& failed_reports() const;
+  const std::set<std::string>& delayed_reports() const;
+  void ClearObservedReports();
+
+ private:
+  void SetFailureModeOnIOThread(ReportSendingResult expected_report_result);
+  void ResumeOnIOThread();
+  void RequestCreated(const std::string& uploaded_report,
+                      ReportSendingResult expected_report_result);
+
+  std::set<std::string> successful_reports_;
+  std::set<std::string> failed_reports_;
+  std::set<std::string> delayed_reports_;
+
+  ReportSendingResult expected_report_result_;
+
+  // Private key to decrypt certificate reports.
+  const uint8_t* server_private_key_;
+
+  mutable base::WeakPtr<DelayableCertReportURLRequestJob> delayed_request_ =
+      nullptr;
+  mutable base::WeakPtrFactory<CertReportJobInterceptor> weak_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(CertReportJobInterceptor);
+};
+
+// A network delegate used to observe URL request destructions. The tests check
+// that no outstanding URL request is present during tear down.
+class CertificateReportingServiceTestNetworkDelegate
+    : public net::NetworkDelegateImpl {
+ public:
+  CertificateReportingServiceTestNetworkDelegate(
+      const base::Callback<void()>& url_request_destroyed_callback);
+  ~CertificateReportingServiceTestNetworkDelegate() override;
+
+  // net::NetworkDelegate method:
+  void OnURLRequestDestroyed(net::URLRequest* request) override;
+
+ private:
+  base::Callback<void()> url_request_destroyed_callback_;
+};
+
+// Base class for CertificateReportingService tests. Sets up an interceptor to
+// keep track of reports that are being sent.
+class CertificateReportingServiceTestBase {
+ protected:
+  CertificateReportingServiceTestBase();
+  virtual ~CertificateReportingServiceTestBase();
+
+  // Syntactic sugar for wrapping report expectations in a more readable way.
+  // Passed to WaitForRequestDeletions() as input.
+  // Example:
+  // The following expects report0 and report1 to be successfully sent and their
+  // URL requests to be deleted:
+  // WaitForRequestDeletions(
+  //     ReportExpectation::Successful("report0, report1"));
+  struct ReportExpectation {
+    ReportExpectation();
+    ReportExpectation(const ReportExpectation& other);
+    ~ReportExpectation();
+    // Returns an expectation where all reports in |reports| succeed.
+    static ReportExpectation Successful(const std::set<std::string>& reports);
+    // Returns an expectation where all reports in |reports| fail.
+    static ReportExpectation Failed(const std::set<std::string>& reports);
+    // Returns an expectation where all reports in |reports| are delayed.
+    static ReportExpectation Delayed(const std::set<std::string>& reports);
+    std::set<std::string> successful_reports;
+    std::set<std::string> failed_reports;
+    std::set<std::string> delayed_reports;
+  };
+
+  void SetUpInterceptor();
+  void TearDownInterceptor();
+
+  // Changes the behavior of report uploads to fail, succeed or hang.
+  void SetFailureMode(ReportSendingResult expected_report_result);
+
+  // Resumes delayed report request. Failure mode should be REPORTS_DELAY when
+  // calling this method.
+  void ResumeDelayedRequest();
+
+  // Waits for the URL requests for the expected reports to be destroyed.
+  // Doesn't block if all requests have already been destroyed.
+  void WaitForRequestsDestroyed(const ReportExpectation& expectation);
+
+  uint8_t* server_public_key();
+  uint32_t server_public_key_version() const;
+
+  net::NetworkDelegate* network_delegate();
+
+  CertReportJobInterceptor* interceptor() { return url_request_interceptor_; }
+
+ private:
+  void SetUpInterceptorOnIOThread(
+      std::unique_ptr<net::URLRequestInterceptor> url_request_interceptor);
+  void TearDownInterceptorOnIOThread();
+  void OnURLRequestDestroyed();
+
+  CertReportJobInterceptor* url_request_interceptor_;
+
+  uint8_t server_public_key_[32];
+  uint8_t server_private_key_[32];
+
+  std::unique_ptr<CertificateReportingServiceTestNetworkDelegate>
+      network_delegate_;
+
+  int num_request_deletions_to_wait_for_;
+  int num_deleted_requests_;
+  std::unique_ptr<base::RunLoop> run_loop_;
+  DISALLOW_COPY_AND_ASSIGN(CertificateReportingServiceTestBase);
+};
+
+}  // namespace certificate_reporting_test_utils
+
+#endif  // CHROME_BROWSER_SAFE_BROWSING_CERTIFICATE_REPORTING_SERVICE_TEST_UTILS_H_
diff --git a/chrome/browser/safe_browsing/certificate_reporting_service_unittest.cc b/chrome/browser/safe_browsing/certificate_reporting_service_unittest.cc
index f7d4c8f..07de07b 100644
--- a/chrome/browser/safe_browsing/certificate_reporting_service_unittest.cc
+++ b/chrome/browser/safe_browsing/certificate_reporting_service_unittest.cc
@@ -6,18 +6,38 @@
 
 #include <string>
 
+#include "base/bind.h"
+#include "base/bind_helpers.h"
 #include "base/run_loop.h"
+#include "base/single_thread_task_runner.h"
 #include "base/test/simple_test_clock.h"
+#include "base/test/thread_test_helper.h"
 #include "base/time/clock.h"
 #include "base/time/time.h"
+#include "chrome/browser/safe_browsing/certificate_reporting_service_test_utils.h"
+#include "content/public/browser/browser_thread.h"
 #include "content/public/test/test_browser_thread.h"
+#include "content/public/test/test_browser_thread_bundle.h"
 #include "net/base/network_delegate_impl.h"
 #include "net/test/url_request/url_request_failed_job.h"
 #include "net/test/url_request/url_request_mock_data_job.h"
+#include "net/url_request/url_request_filter.h"
 #include "net/url_request/url_request_test_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-TEST(CertificateReportingServiceTest, BoundedReportList) {
+namespace {
+
+// Maximum number of reports kept in the certificate reporting service's retry
+// queue.
+const size_t kMaxReportCountInQueue = 3;
+
+void ClearURLHandlers() {
+  net::URLRequestFilter::GetInstance()->ClearHandlers();
+}
+
+}  // namespace
+
+TEST(CertificateReportingServiceReportListTest, BoundedReportList) {
   // Create a report list with maximum of 2 items.
   CertificateReportingService::BoundedReportList list(2 /* max_size */);
   EXPECT_EQ(0u, list.items().size());
@@ -56,7 +76,8 @@
   EXPECT_EQ("report2_five_minutes_old", list.items()[1].serialized_report);
 }
 
-class CertificateReportingServiceReporterTest : public ::testing::Test {
+class CertificateReportingServiceReporterOnIOThreadTest
+    : public ::testing::Test {
  public:
   void SetUp() override {
     message_loop_.reset(new base::MessageLoopForIO());
@@ -68,6 +89,8 @@
     net::URLRequestMockDataJob::AddUrlHandler();
   }
 
+  void TearDown() override { ClearURLHandlers(); }
+
  protected:
   net::URLRequestContextGetter* url_request_context_getter() {
     return url_request_context_getter_.get();
@@ -80,7 +103,8 @@
   scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
 };
 
-TEST_F(CertificateReportingServiceReporterTest, Reporter) {
+TEST_F(CertificateReportingServiceReporterOnIOThreadTest,
+       Reporter_RetriesEnabled) {
   std::unique_ptr<base::SimpleTestClock> clock(new base::SimpleTestClock());
   base::Time reference_time = base::Time::Now();
   clock->SetNow(reference_time);
@@ -95,11 +119,13 @@
   CertificateReportingService::BoundedReportList* list =
       new CertificateReportingService::BoundedReportList(2);
 
+  // Create a reporter with retries enabled.
   CertificateReportingService::Reporter reporter(
       std::unique_ptr<certificate_reporting::ErrorReporter>(
           certificate_error_reporter),
       std::unique_ptr<CertificateReportingService::BoundedReportList>(list),
-      clock.get(), base::TimeDelta::FromSeconds(100));
+      clock.get(), base::TimeDelta::FromSeconds(100),
+      true /* retries_enabled */);
   EXPECT_EQ(0u, list->items().size());
   EXPECT_EQ(0u, reporter.inflight_report_count_for_testing());
 
@@ -172,3 +198,371 @@
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(0u, list->items().size());
 }
+
+// Same as above, but retries are disabled.
+TEST_F(CertificateReportingServiceReporterOnIOThreadTest,
+       Reporter_RetriesDisabled) {
+  std::unique_ptr<base::SimpleTestClock> clock(new base::SimpleTestClock());
+  base::Time reference_time = base::Time::Now();
+  clock->SetNow(reference_time);
+
+  const GURL kFailureURL =
+      net::URLRequestFailedJob::GetMockHttpsUrl(net::ERR_SSL_PROTOCOL_ERROR);
+  certificate_reporting::ErrorReporter* certificate_error_reporter =
+      new certificate_reporting::ErrorReporter(
+          url_request_context_getter()->GetURLRequestContext(), kFailureURL,
+          net::ReportSender::DO_NOT_SEND_COOKIES);
+
+  CertificateReportingService::BoundedReportList* list =
+      new CertificateReportingService::BoundedReportList(2);
+
+  // Create a reporter with retries disabled.
+  CertificateReportingService::Reporter reporter(
+      std::unique_ptr<certificate_reporting::ErrorReporter>(
+          certificate_error_reporter),
+      std::unique_ptr<CertificateReportingService::BoundedReportList>(list),
+      clock.get(), base::TimeDelta::FromSeconds(100),
+      false /* retries_enabled */);
+  EXPECT_EQ(0u, list->items().size());
+  EXPECT_EQ(0u, reporter.inflight_report_count_for_testing());
+
+  // Sending a failed report will not put the report in the retry list.
+  reporter.Send("report1");
+  EXPECT_EQ(1u, reporter.inflight_report_count_for_testing());
+  base::RunLoop().RunUntilIdle();
+
+  EXPECT_EQ(0u, reporter.inflight_report_count_for_testing());
+  ASSERT_EQ(0u, list->items().size());
+
+  // Sending a second failed report will also not put it in the retry list.
+  clock->Advance(base::TimeDelta::FromSeconds(10));
+  reporter.Send("report2");
+  base::RunLoop().RunUntilIdle();
+  ASSERT_EQ(0u, list->items().size());
+
+  // Send pending reports. Nothing should be sent.
+  clock->Advance(base::TimeDelta::FromSeconds(10));
+  reporter.SendPending();
+  base::RunLoop().RunUntilIdle();
+  ASSERT_EQ(0u, list->items().size());
+}
+
+class CertificateReportingServiceTest
+    : public ::testing::Test,
+      public certificate_reporting_test_utils::
+          CertificateReportingServiceTestBase {
+ public:
+  CertificateReportingServiceTest()
+      : CertificateReportingServiceTestBase(),
+        thread_bundle_(content::TestBrowserThreadBundle::REAL_IO_THREAD),
+        io_task_runner_(content::BrowserThread::GetTaskRunnerForThread(
+            content::BrowserThread::IO)) {}
+
+  ~CertificateReportingServiceTest() override {}
+
+  void SetUp() override {
+    SetUpInterceptor();
+    WaitForIOThread();
+
+    content::BrowserThread::PostTask(
+        content::BrowserThread::IO, FROM_HERE,
+        base::Bind(
+            &CertificateReportingServiceTest::SetUpURLRequestContextOnIOThread,
+            base::Unretained(this)));
+    WaitForIOThread();
+
+    clock_ = new base::SimpleTestClock();
+    service_.reset(new CertificateReportingService(
+        url_request_context_getter(), server_public_key(),
+        server_public_key_version(), kMaxReportCountInQueue,
+        base::TimeDelta::FromHours(24), std::unique_ptr<base::Clock>(clock_)));
+    // Wait for service reset.
+    WaitForIOThread();
+  }
+
+  void SetUpURLRequestContextOnIOThread() {
+    std::unique_ptr<net::TestURLRequestContext> url_request_context(
+        new net::TestURLRequestContext(true));
+    url_request_context->set_network_delegate(network_delegate());
+    url_request_context->Init();
+    url_request_context_getter_ = new net::TestURLRequestContextGetter(
+        io_task_runner_, std::move(url_request_context));
+  }
+
+  void TearDown() override {
+    WaitForIOThread();
+    EXPECT_TRUE(interceptor()->successful_reports().empty());
+    EXPECT_TRUE(interceptor()->failed_reports().empty());
+    EXPECT_TRUE(interceptor()->delayed_reports().empty());
+    EXPECT_EQ(0u, service()
+                      ->GetReporterForTesting()
+                      ->inflight_report_count_for_testing());
+
+    service_->Shutdown();
+    WaitForIOThread();
+
+    service_.reset(nullptr);
+    content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
+                                     base::Bind(&ClearURLHandlers));
+    TearDownInterceptor();
+  }
+
+ protected:
+  net::URLRequestContextGetter* url_request_context_getter() {
+    return url_request_context_getter_.get();
+  }
+
+  void WaitForIOThread() {
+    scoped_refptr<base::ThreadTestHelper> io_helper(
+        new base::ThreadTestHelper(io_task_runner_));
+    ASSERT_TRUE(io_helper->Run());
+  }
+
+  // Sets service enabled state and waits for a reset event.
+  void SetServiceEnabledAndWait(bool enabled) {
+    service()->SetEnabled(enabled);
+    WaitForIOThread();
+  }
+
+  void AdvanceClock(base::TimeDelta delta) {
+    content::BrowserThread::PostTask(
+        content::BrowserThread::IO, FROM_HERE,
+        base::Bind(&base::SimpleTestClock::Advance, base::Unretained(clock_),
+                   delta));
+  }
+
+  void SetNow(base::Time now) {
+    content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
+                                     base::Bind(&base::SimpleTestClock::SetNow,
+                                                base::Unretained(clock_), now));
+  }
+
+  CertificateReportingService* service() { return service_.get(); }
+
+ private:
+  // Must be initialized before url_request_context_getter_
+  content::TestBrowserThreadBundle thread_bundle_;
+
+  scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
+  scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
+
+  std::unique_ptr<CertificateReportingService> service_;
+  base::SimpleTestClock* clock_;
+};
+
+TEST_F(CertificateReportingServiceTest, Send) {
+  WaitForIOThread();
+  // Let all reports fail.
+  SetFailureMode(
+      certificate_reporting_test_utils::ReportSendingResult::REPORTS_FAIL);
+
+  // Send two reports. Both should fail and get queued.
+  service()->Send("report0");
+  WaitForRequestsDestroyed(ReportExpectation::Failed({"report0"}));
+
+  service()->Send("report1");
+  WaitForRequestsDestroyed(ReportExpectation::Failed({"report1"}));
+
+  // Send pending reports. Previously queued reports should be observed. They
+  // will also be queued again.
+  service()->SendPending();
+  WaitForRequestsDestroyed(ReportExpectation::Failed({"report0", "report1"}));
+
+  // Let all reports succeed.
+  SetFailureMode(certificate_reporting_test_utils::ReportSendingResult::
+                     REPORTS_SUCCESSFUL);
+
+  // Send a third report. This should not be queued.
+  service()->Send("report2");
+  WaitForRequestsDestroyed(ReportExpectation::Successful({"report2"}));
+
+  // Send pending reports. Previously failed and queued two reports should be
+  // observed.
+  service()->SendPending();
+  WaitForRequestsDestroyed(
+      ReportExpectation::Successful({"report0", "report1"}));
+}
+
+TEST_F(CertificateReportingServiceTest, Disabled_ShouldNotSend) {
+  // Let all reports succeed.
+  SetFailureMode(certificate_reporting_test_utils::ReportSendingResult::
+                     REPORTS_SUCCESSFUL);
+
+  // Disable the service.
+  SetServiceEnabledAndWait(false);
+
+  // Send a report. Report attempt should be cancelled and no sent reports
+  // should be observed.
+  service()->Send("report0");
+
+  // Enable the service and send a report again.
+  SetServiceEnabledAndWait(true);
+
+  service()->Send("report1");
+  WaitForRequestsDestroyed(ReportExpectation::Successful({"report1"}));
+}
+
+TEST_F(CertificateReportingServiceTest, Disabled_ShouldClearPendingReports) {
+  // Let all reports fail.
+  SetFailureMode(
+      certificate_reporting_test_utils::ReportSendingResult::REPORTS_FAIL);
+
+  service()->Send("report0");
+  WaitForRequestsDestroyed(ReportExpectation::Failed({"report0"}));
+
+  // Disable the service.
+  SetServiceEnabledAndWait(false);
+
+  // Sending has no effect while disabled, wait for a single cancelled event.
+  service()->SendPending();
+
+  // Re-enable the service and send pending reports. Pending reports should have
+  // been cleared when the service was disabled, so no report should be seen.
+  SetServiceEnabledAndWait(true);
+
+  // Sending with empty queue has no effect.
+  service()->SendPending();
+}
+
+TEST_F(CertificateReportingServiceTest, DontSendOldReports) {
+  SetNow(base::Time::Now());
+  // Let all reports fail.
+  SetFailureMode(
+      certificate_reporting_test_utils::ReportSendingResult::REPORTS_FAIL);
+
+  // Send a report.
+  service()->Send("report0");
+  WaitForRequestsDestroyed(ReportExpectation::Failed({"report0"}));
+
+  // Advance the clock a bit and trigger another report.
+  AdvanceClock(base::TimeDelta::FromHours(5));
+
+  service()->Send("report1");
+  WaitForRequestsDestroyed(ReportExpectation::Failed({"report1"}));
+
+  // Advance the clock to 20 hours, putting it 25 hours ahead of the reference
+  // time. This makes the report0 older than max age (24 hours). The report1 is
+  // now 20 hours old.
+  AdvanceClock(base::TimeDelta::FromHours(20));
+  // Send pending reports. report0 should be discarded since it's too old.
+  // report1 should be queued again.
+  service()->SendPending();
+  WaitForRequestsDestroyed(ReportExpectation::Failed({"report1"}));
+
+  // Send a third report.
+  service()->Send("report2");
+  WaitForRequestsDestroyed(ReportExpectation::Failed({"report2"}));
+
+  // Advance the clock 5 hours. The report1 will now be 25 hours old.
+  AdvanceClock(base::TimeDelta::FromHours(5));
+  // Send pending reports. report1 should be discarded since it's too old.
+  // report2 should be queued again.
+  service()->SendPending();
+  WaitForRequestsDestroyed(ReportExpectation::Failed({"report2"}));
+
+  // Advance the clock 20 hours again so that report2 is 25 hours old and is
+  // older than max age (24 hours)
+  AdvanceClock(base::TimeDelta::FromHours(20));
+  // Send pending reports. report2 should be discarded since it's too old. No
+  // other reports remain.
+  service()->SendPending();
+}
+
+TEST_F(CertificateReportingServiceTest, DiscardOldReports) {
+  SetNow(base::Time::Now());
+  // Let all reports fail.
+  SetFailureMode(
+      certificate_reporting_test_utils::ReportSendingResult::REPORTS_FAIL);
+
+  // Send a failed report.
+  service()->Send("report0");
+  WaitForRequestsDestroyed(ReportExpectation::Failed({"report0"}));
+
+  // Send three more reports within five hours of each other. After this:
+  // report0 is 0 hours after reference time (15 hours old).
+  // report1 is 5 hours after reference time (10 hours old).
+  // report2 is 10 hours after reference time (5 hours old).
+  // report3 is 15 hours after reference time (0 hours old).
+  AdvanceClock(base::TimeDelta::FromHours(5));
+  service()->Send("report1");
+
+  AdvanceClock(base::TimeDelta::FromHours(5));
+  service()->Send("report2");
+
+  AdvanceClock(base::TimeDelta::FromHours(5));
+  service()->Send("report3");
+  WaitForRequestsDestroyed(
+      ReportExpectation::Failed({"report1", "report2", "report3"}));
+
+  // Send pending reports. Four reports were generated above, but the service
+  // only queues three reports, so the very first one should be dropped since
+  // it's the oldest.
+  service()->SendPending();
+  WaitForRequestsDestroyed(
+      ReportExpectation::Failed({"report1", "report2", "report3"}));
+
+  // Let all reports succeed.
+  SetFailureMode(certificate_reporting_test_utils::ReportSendingResult::
+                     REPORTS_SUCCESSFUL);
+
+  // Advance the clock by 15 hours. Current time is now 30 hours after reference
+  // time. The ages of reports are now as follows:
+  // report1 is 25 hours old.
+  // report2 is 20 hours old.
+  // report3 is 15 hours old.
+  AdvanceClock(base::TimeDelta::FromHours(15));
+  // Send pending reports. Only report2 and report3 should be sent, report1
+  // should be ignored because it's too old.
+  service()->SendPending();
+  WaitForRequestsDestroyed(
+      ReportExpectation::Successful({"report2", "report3"}));
+
+  // Do a final send. No reports should be sent.
+  service()->SendPending();
+}
+
+// A delayed report should successfully upload when it's resumed.
+TEST_F(CertificateReportingServiceTest, Delayed_Resumed) {
+  // Let reports hang.
+  SetFailureMode(
+      certificate_reporting_test_utils::ReportSendingResult::REPORTS_DELAY);
+  // Send a report. The report upload hangs, so no error or success callbacks
+  // should be called.
+  service()->Send("report0");
+
+  // Resume the report upload and run the callbacks. The report should be
+  // successfully sent.
+  ResumeDelayedRequest();
+  WaitForRequestsDestroyed(ReportExpectation::Delayed({"report0"}));
+}
+
+// Delayed reports should cleaned when the service is reset.
+TEST_F(CertificateReportingServiceTest, Delayed_Reset) {
+  // Let reports hang.
+  SetFailureMode(
+      certificate_reporting_test_utils::ReportSendingResult::REPORTS_DELAY);
+  // Send a report. The report is triggered but hangs, so no error or success
+  // callbacks should be called.
+  service()->Send("report0");
+
+  // Disable the service. This should reset the reporting service and
+  // clear all pending reports.
+  SetServiceEnabledAndWait(false);
+
+  // Resume delayed report. No report should be observed since the service
+  // should have reset and all pending reports should be cleared. If any report
+  // is observed, the next WaitForRequestsDestroyed() will fail.
+  ResumeDelayedRequest();
+
+  // Enable the service.
+  SetServiceEnabledAndWait(true);
+
+  // Send a report. The report is triggered but hangs, so no error or success
+  // callbacks should be called. The report id is again 0 since the pending
+  // report queue has been cleared above.
+  service()->Send("report1");
+
+  // Resume delayed report. The report should be observed.
+  ResumeDelayedRequest();
+  WaitForRequestsDestroyed(ReportExpectation::Delayed({"report0", "report1"}));
+}
diff --git a/chrome/browser/safe_browsing/srt_fetcher_win.cc b/chrome/browser/safe_browsing/srt_fetcher_win.cc
index 2711ba2..6bdb1f1 100644
--- a/chrome/browser/safe_browsing/srt_fetcher_win.cc
+++ b/chrome/browser/safe_browsing/srt_fetcher_win.cc
@@ -632,10 +632,13 @@
     ProfileIOData* io_data = ProfileIOData::FromResourceContext(
         profile_->GetResourceContext());
     net::HttpRequestHeaders headers;
+    // Note: It's fine to pass in |is_signed_in| false, which does not affect
+    // transmission of experiment ids coming from the variations server.
+    bool is_signed_in = false;
     variations::AppendVariationHeaders(
         url_fetcher_->GetOriginalURL(), io_data->IsOffTheRecord(),
         ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled(),
-        &headers);
+        is_signed_in, &headers);
     url_fetcher_->SetExtraRequestHeaders(headers.ToString());
     url_fetcher_->Start();
   }
diff --git a/chrome/browser/search/search_unittest.cc b/chrome/browser/search/search_unittest.cc
index 335905e..1761130 100644
--- a/chrome/browser/search/search_unittest.cc
+++ b/chrome/browser/search/search_unittest.cc
@@ -443,7 +443,6 @@
   std::map<std::string, bool> hosts;
   hosts["foo.com"] = false;
   url_filter->SetManualHosts(&hosts);
-  url_filter->SetEnabled(true);
 
   EXPECT_EQ(GURL(chrome::kChromeSearchLocalNtpUrl),
             GetNewTabPageURL(profile()));
diff --git a/chrome/browser/search_engines/template_url_service_factory.cc b/chrome/browser/search_engines/template_url_service_factory.cc
index 464441b..e2d9366 100644
--- a/chrome/browser/search_engines/template_url_service_factory.cc
+++ b/chrome/browser/search_engines/template_url_service_factory.cc
@@ -23,8 +23,9 @@
 #include "components/search_engines/default_search_manager.h"
 #include "components/search_engines/search_engines_pref_names.h"
 #include "components/search_engines/template_url_service.h"
+#include "rlz/features/features.h"
 
-#if defined(ENABLE_RLZ)
+#if BUILDFLAG(ENABLE_RLZ)
 #include "components/rlz/rlz_tracker.h"
 #endif
 
@@ -43,7 +44,7 @@
 std::unique_ptr<KeyedService> TemplateURLServiceFactory::BuildInstanceFor(
     content::BrowserContext* context) {
   base::Closure dsp_change_callback;
-#if defined(ENABLE_RLZ)
+#if BUILDFLAG(ENABLE_RLZ)
   dsp_change_callback = base::Bind(
       base::IgnoreResult(&rlz::RLZTracker::RecordProductEvent), rlz_lib::CHROME,
       rlz::RLZTracker::ChromeOmnibox(), rlz_lib::SET_TO_GOOGLE);
diff --git a/chrome/browser/search_engines/ui_thread_search_terms_data.cc b/chrome/browser/search_engines/ui_thread_search_terms_data.cc
index 6ae87fa..9a31685 100644
--- a/chrome/browser/search_engines/ui_thread_search_terms_data.cc
+++ b/chrome/browser/search_engines/ui_thread_search_terms_data.cc
@@ -25,10 +25,11 @@
 #include "components/search/search.h"
 #include "components/version_info/version_info.h"
 #include "content/public/browser/browser_thread.h"
+#include "rlz/features/features.h"
 #include "ui/base/device_form_factor.h"
 #include "url/gurl.h"
 
-#if defined(ENABLE_RLZ)
+#if BUILDFLAG(ENABLE_RLZ)
 #include "components/rlz/rlz_tracker.h"
 #endif
 
@@ -74,7 +75,7 @@
   DCHECK(!BrowserThread::IsThreadInitialized(BrowserThread::UI) ||
       BrowserThread::CurrentlyOn(BrowserThread::UI));
   base::string16 rlz_string;
-#if defined(ENABLE_RLZ)
+#if BUILDFLAG(ENABLE_RLZ)
   // For organic brandcodes do not use rlz at all. Empty brandcode usually
   // means a chromium install. This is ok.
   std::string brand;
diff --git a/chrome/browser/supervised_user/supervised_user_resource_throttle.cc b/chrome/browser/supervised_user/supervised_user_resource_throttle.cc
index 53df77ad..a0695f6 100644
--- a/chrome/browser/supervised_user/supervised_user_resource_throttle.cc
+++ b/chrome/browser/supervised_user/supervised_user_resource_throttle.cc
@@ -117,7 +117,7 @@
     const SupervisedUserURLFilter* url_filter) {
   // Only treat main frame requests (ignoring subframes and subresources).
   bool is_main_frame = resource_type == content::RESOURCE_TYPE_MAIN_FRAME;
-  if (!is_main_frame || !url_filter->enabled())
+  if (!is_main_frame)
     return nullptr;
 
   // Can't use base::MakeUnique because the constructor is private.
diff --git a/chrome/browser/supervised_user/supervised_user_resource_throttle_browsertest.cc b/chrome/browser/supervised_user/supervised_user_resource_throttle_browsertest.cc
index 90955a67..c19e8d29 100644
--- a/chrome/browser/supervised_user/supervised_user_resource_throttle_browsertest.cc
+++ b/chrome/browser/supervised_user/supervised_user_resource_throttle_browsertest.cc
@@ -136,28 +136,3 @@
   ASSERT_TRUE(content::ExecuteScriptAndExtractBool(tab, "loaded2()", &loaded2));
   EXPECT_TRUE(loaded2);
 }
-
-class SupervisedUserResourceThrottleNotSupervisedTest
-    : public SupervisedUserResourceThrottleTest {
- protected:
-  SupervisedUserResourceThrottleNotSupervisedTest() {}
-  ~SupervisedUserResourceThrottleNotSupervisedTest() override {}
-
- private:
-  // Overridden to do nothing, so that the supervised user ID will be empty.
-  void SetUpCommandLine(base::CommandLine* command_line) override {}
-};
-
-IN_PROC_BROWSER_TEST_F(SupervisedUserResourceThrottleNotSupervisedTest,
-                       DontBlock) {
-  BlockHost(kExampleHost);
-
-  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
-
-  GURL blocked_url = embedded_test_server()->GetURL(
-      kExampleHost, "/supervised_user/simple.html");
-  ui_test_utils::NavigateToURL(browser(), blocked_url);
-  // Even though the URL is marked as blocked, the load should go through, since
-  // the user isn't supervised.
-  EXPECT_FALSE(tab->ShowingInterstitialPage());
-}
diff --git a/chrome/browser/supervised_user/supervised_user_service.cc b/chrome/browser/supervised_user/supervised_user_service.cc
index a470f3e..324f525d6 100644
--- a/chrome/browser/supervised_user/supervised_user_service.cc
+++ b/chrome/browser/supervised_user/supervised_user_service.cc
@@ -441,13 +441,6 @@
   return io_url_filter_.get();
 }
 
-void SupervisedUserService::URLFilterContext::SetEnabled(bool enabled) {
-  ui_url_filter_->SetEnabled(enabled);
-  BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
-                          base::Bind(&SupervisedUserURLFilter::SetEnabled,
-                                     io_url_filter_, enabled));
-}
-
 void SupervisedUserService::URLFilterContext::SetDefaultFilteringBehavior(
     SupervisedUserURLFilter::FilteringBehavior behavior) {
   ui_url_filter_->SetDefaultFilteringBehavior(behavior);
@@ -679,8 +672,6 @@
     BrowserList::RemoveObserver(this);
 #endif
   }
-
-  url_filter_context_.SetEnabled(active_);
 }
 
 #if !defined(OS_ANDROID)
diff --git a/chrome/browser/supervised_user/supervised_user_service.h b/chrome/browser/supervised_user/supervised_user_service.h
index b461177..b896f63a5 100644
--- a/chrome/browser/supervised_user/supervised_user_service.h
+++ b/chrome/browser/supervised_user/supervised_user_service.h
@@ -250,7 +250,6 @@
     SupervisedUserURLFilter* ui_url_filter() const;
     SupervisedUserURLFilter* io_url_filter() const;
 
-    void SetEnabled(bool enabled);
     void SetDefaultFilteringBehavior(
         SupervisedUserURLFilter::FilteringBehavior behavior);
     void LoadWhitelists(
diff --git a/chrome/browser/supervised_user/supervised_user_url_filter.cc b/chrome/browser/supervised_user/supervised_user_url_filter.cc
index dfece48..5318b1b 100644
--- a/chrome/browser/supervised_user/supervised_user_url_filter.cc
+++ b/chrome/browser/supervised_user/supervised_user_url_filter.cc
@@ -231,8 +231,7 @@
 }  // namespace
 
 SupervisedUserURLFilter::SupervisedUserURLFilter()
-    : enabled_(false),
-      default_behavior_(ALLOW),
+    : default_behavior_(ALLOW),
       contents_(new Contents()),
       blacklist_(nullptr),
       amp_cache_path_regex_(kAmpCachePathPattern),
@@ -324,16 +323,6 @@
   return trimmed_host == trimmed_pattern;
 }
 
-void SupervisedUserURLFilter::SetEnabled(bool enabled) {
-  if (enabled_ == enabled)
-    return;
-
-  enabled_ = enabled;
-
-  for (Observer& observer : observers_)
-    observer.OnSiteListUpdated();
-}
-
 SupervisedUserURLFilter::FilteringBehavior
 SupervisedUserURLFilter::GetFilteringBehaviorForURL(const GURL& url) const {
   supervised_user_error_page::FilteringBehaviorReason reason;
@@ -354,11 +343,6 @@
     supervised_user_error_page::FilteringBehaviorReason* reason) const {
   DCHECK(CalledOnValidThread());
 
-  if (!enabled_) {
-    *reason = supervised_user_error_page::DEFAULT;
-    return ALLOW;
-  }
-
   GURL effective_url = GetEmbeddedURL(url);
   if (!effective_url.is_valid())
     effective_url = url;
@@ -661,10 +645,8 @@
 void SupervisedUserURLFilter::SetContents(std::unique_ptr<Contents> contents) {
   DCHECK(CalledOnValidThread());
   contents_ = std::move(contents);
-  if (enabled_) {
-    for (Observer& observer : observers_)
-      observer.OnSiteListUpdated();
-  }
+  for (Observer& observer : observers_)
+    observer.OnSiteListUpdated();
 }
 
 void SupervisedUserURLFilter::CheckCallback(
diff --git a/chrome/browser/supervised_user/supervised_user_url_filter.h b/chrome/browser/supervised_user/supervised_user_url_filter.h
index e11c50cc..0b34d37 100644
--- a/chrome/browser/supervised_user/supervised_user_url_filter.h
+++ b/chrome/browser/supervised_user/supervised_user_url_filter.h
@@ -61,11 +61,7 @@
 
   class Observer {
    public:
-    // Called whenever the filter changes.
-    // TODO(treib,bauerb): Rename to OnURLFilterUpdated.
     virtual void OnSiteListUpdated() = 0;
-    // Called whenever a check started via
-    // GetFilteringBehaviorForURLWithAsyncChecks completes.
     virtual void OnURLChecked(
         const GURL& url,
         FilteringBehavior behavior,
@@ -110,13 +106,6 @@
   static bool HostMatchesPattern(const std::string& canonical_host,
                                  const std::string& pattern);
 
-  // Returns whether the filter is enabled. If this is false, all URL checks
-  // will return ALLOW.
-  bool enabled() const { return enabled_; }
-
-  // Enables or disables the filter. Notifies observers if the state changed.
-  void SetEnabled(bool enabled);
-
   // Returns the filtering behavior for a given URL, based on the default
   // behavior and whether it is on a site list.
   FilteringBehavior GetFilteringBehaviorForURL(const GURL& url) const;
@@ -209,10 +198,6 @@
   // This is mutable to allow notification in const member functions.
   mutable base::ObserverList<Observer> observers_;
 
-  // Whether this filter is enabled. True for supervised user profiles, false
-  // otherwise.
-  bool enabled_;
-
   FilteringBehavior default_behavior_;
   std::unique_ptr<Contents> contents_;
 
diff --git a/chrome/browser/supervised_user/supervised_user_url_filter_unittest.cc b/chrome/browser/supervised_user/supervised_user_url_filter_unittest.cc
index bbac7bae..e306abc 100644
--- a/chrome/browser/supervised_user/supervised_user_url_filter_unittest.cc
+++ b/chrome/browser/supervised_user/supervised_user_url_filter_unittest.cc
@@ -22,7 +22,6 @@
  public:
   SupervisedUserURLFilterTest() : filter_(new SupervisedUserURLFilter) {
     filter_->SetDefaultFilteringBehavior(SupervisedUserURLFilter::BLOCK);
-    filter_->SetEnabled(true);
     filter_->AddObserver(this);
   }
 
@@ -69,11 +68,6 @@
   EXPECT_TRUE(IsURLWhitelisted("chrome://extensions/"));
   EXPECT_TRUE(IsURLWhitelisted("chrome-extension://foo/main.html"));
   EXPECT_TRUE(IsURLWhitelisted("file:///home/chronos/user/Downloads/img.jpg"));
-
-  // If the filter is disabled, everything should be allowed.
-  filter_->SetEnabled(false);
-  EXPECT_TRUE(IsURLWhitelisted("http://google.com"));
-  EXPECT_TRUE(IsURLWhitelisted("http://notgoogle.com/"));
 }
 
 TEST_F(SupervisedUserURLFilterTest, EffectiveURL) {
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index 559b0fa..7ff8530a 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -12,6 +12,7 @@
 import("//media/media_options.gni")
 import("//ppapi/features/features.gni")
 import("//printing/features/features.gni")
+import("//rlz/features/features.gni")
 import("//ui/base/ui_features.gni")
 
 config("ui_warnings") {
@@ -572,6 +573,7 @@
     "//net:net_with_v8",
     "//ppapi/features",
     "//printing/features",
+    "//rlz/features",
     "//services/service_manager/runner/common",
     "//skia",
     "//storage/browser",
@@ -1892,8 +1894,14 @@
       # apart from aura::Window, which is also not supported).
       if (!is_mac) {
         sources += [
-          "views/ime_driver_mus.cc",
-          "views/ime_driver_mus.h",
+          "views/ime_driver/ime_driver_mus.cc",
+          "views/ime_driver/ime_driver_mus.h",
+          "views/ime_driver/input_method_bridge_chromeos.cc",
+          "views/ime_driver/input_method_bridge_chromeos.h",
+          "views/ime_driver/remote_text_input_client.cc",
+          "views/ime_driver/remote_text_input_client.h",
+          "views/ime_driver/simple_input_method.cc",
+          "views/ime_driver/simple_input_method.h",
           "views/tabs/window_finder_mus.cc",
           "views/tabs/window_finder_mus.h",
         ]
@@ -2061,8 +2069,6 @@
       "window_sizer/window_sizer_aura.cc",
     ]
     deps += [
-      # aura uses some of ash resources.
-      "//ash/resources",
       "//ui/aura",
       "//ui/keyboard",
       "//ui/keyboard:keyboard_with_content",
diff --git a/chrome/browser/ui/android/autofill/autofill_popup_view_android.cc b/chrome/browser/ui/android/autofill/autofill_popup_view_android.cc
index 3046b58..6795ac7 100644
--- a/chrome/browser/ui/android/autofill/autofill_popup_view_android.cc
+++ b/chrome/browser/ui/android/autofill/autofill_popup_view_android.cc
@@ -94,7 +94,7 @@
           controller_->layout_model().GetIconResourceID(suggestion.icon));
     }
 
-    bool deletable =
+    bool is_deletable =
         controller_->GetRemovalConfirmationText(i, nullptr, nullptr);
     bool is_label_multiline =
         suggestion.frontend_id ==
@@ -102,11 +102,16 @@
         suggestion.frontend_id == POPUP_ITEM_ID_CREDIT_CARD_SIGNIN_PROMO;
     Java_AutofillPopupBridge_addToAutofillSuggestionArray(
         env, data_array, i, value, label, android_icon_id,
-        suggestion.frontend_id, deletable, is_label_multiline);
+        controller_->layout_model().IsIconAtStart(suggestion.frontend_id),
+        suggestion.frontend_id, is_deletable, is_label_multiline,
+        suggestion.is_value_bold);
   }
 
-  Java_AutofillPopupBridge_show(env, java_object_, data_array,
-                                controller_->IsRTL());
+  Java_AutofillPopupBridge_show(
+      env, java_object_, data_array, controller_->IsRTL(),
+      controller_->layout_model().GetBackgroundColor(),
+      controller_->layout_model().GetDividerColor(),
+      controller_->layout_model().GetDropdownItemHeight());
 }
 
 void AutofillPopupViewAndroid::SuggestionSelected(
diff --git a/chrome/browser/ui/app_list/app_list_controller_delegate.cc b/chrome/browser/ui/app_list/app_list_controller_delegate.cc
index eef8d47a..fa717e49 100644
--- a/chrome/browser/ui/app_list/app_list_controller_delegate.cc
+++ b/chrome/browser/ui/app_list/app_list_controller_delegate.cc
@@ -22,13 +22,14 @@
 #include "extensions/common/manifest_handlers/options_page_info.h"
 #include "extensions/common/manifest_url_handlers.h"
 #include "net/base/url_util.h"
+#include "rlz/features/features.h"
 #include "ui/app_list/app_list_folder_item.h"
 #include "ui/app_list/app_list_item.h"
 #include "ui/app_list/app_list_model.h"
 #include "ui/app_list/app_list_switches.h"
 #include "ui/gfx/geometry/rect.h"
 
-#if defined(ENABLE_RLZ)
+#if BUILDFLAG(ENABLE_RLZ)
 #include "components/rlz/rlz_tracker.h"  // nogncheck
 #endif
 
@@ -203,7 +204,7 @@
 }
 
 void AppListControllerDelegate::OnSearchStarted() {
-#if defined(ENABLE_RLZ)
+#if BUILDFLAG(ENABLE_RLZ)
   rlz::RLZTracker::RecordAppListSearch();
 #endif
 }
diff --git a/chrome/browser/ui/autofill/autofill_popup_controller_impl.cc b/chrome/browser/ui/autofill/autofill_popup_controller_impl.cc
index bcdcaf6f..169aac1 100644
--- a/chrome/browser/ui/autofill/autofill_popup_controller_impl.cc
+++ b/chrome/browser/ui/autofill/autofill_popup_controller_impl.cc
@@ -70,7 +70,7 @@
                                                    container_view,
                                                    web_contents)),
       view_(NULL),
-      layout_model_(this),
+      layout_model_(this, delegate->IsCreditCardPopup()),
       delegate_(delegate),
       weak_ptr_factory_(this) {
   ClearState();
diff --git a/chrome/browser/ui/autofill/autofill_popup_layout_model.cc b/chrome/browser/ui/autofill/autofill_popup_layout_model.cc
index 5364cb6..c93e702 100644
--- a/chrome/browser/ui/autofill/autofill_popup_layout_model.cc
+++ b/chrome/browser/ui/autofill/autofill_popup_layout_model.cc
@@ -10,10 +10,12 @@
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/ui/autofill/autofill_popup_view.h"
 #include "chrome/browser/ui/autofill/popup_constants.h"
+#include "components/autofill/core/browser/autofill_experiments.h"
 #include "components/autofill/core/browser/popup_item_ids.h"
 #include "components/autofill/core/browser/suggestion.h"
 #include "components/autofill/core/common/autofill_util.h"
 #include "components/grit/components_scaled_resources.h"
+#include "third_party/skia/include/core/SkColor.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/gfx/color_palette.h"
 #include "ui/gfx/color_utils.h"
@@ -70,8 +72,8 @@
 }  // namespace
 
 AutofillPopupLayoutModel::AutofillPopupLayoutModel(
-    AutofillPopupViewDelegate* delegate)
-    : delegate_(delegate) {
+    AutofillPopupViewDelegate* delegate, bool is_credit_card_popup)
+    : delegate_(delegate), is_credit_card_popup_(is_credit_card_popup) {
 #if !defined(OS_ANDROID)
   smaller_font_list_ =
       normal_font_list_.DeriveWithSizeDelta(kSmallerFontSizeDelta);
@@ -282,4 +284,28 @@
   return gfx::ToEnclosingRect(delegate_->element_bounds());
 }
 
+bool AutofillPopupLayoutModel::IsPopupLayoutExperimentEnabled() const {
+  return is_credit_card_popup_ &&
+      IsAutofillCreditCardPopupLayoutExperimentEnabled();
+}
+
+SkColor AutofillPopupLayoutModel::GetBackgroundColor() const {
+  return is_credit_card_popup_ ?
+      GetCreditCardPopupBackgroundColor() : SK_ColorTRANSPARENT;
+}
+
+SkColor AutofillPopupLayoutModel::GetDividerColor() const {
+  return is_credit_card_popup_ ?
+      GetCreditCardPopupDividerColor() : SK_ColorTRANSPARENT;
+}
+
+unsigned int AutofillPopupLayoutModel::GetDropdownItemHeight() const {
+  return GetPopupDropdownItemHeight();
+}
+
+bool AutofillPopupLayoutModel::IsIconAtStart(int frontend_id) const {
+  return frontend_id == POPUP_ITEM_ID_HTTP_NOT_SECURE_WARNING_MESSAGE ||
+      (is_credit_card_popup_ && IsIconInCreditCardPopupAtStart());
+}
+
 }  // namespace autofill
diff --git a/chrome/browser/ui/autofill/autofill_popup_layout_model.h b/chrome/browser/ui/autofill/autofill_popup_layout_model.h
index b3a2c73..6e31077 100644
--- a/chrome/browser/ui/autofill/autofill_popup_layout_model.h
+++ b/chrome/browser/ui/autofill/autofill_popup_layout_model.h
@@ -25,7 +25,9 @@
 // TODO(mathp): investigate moving ownership of this class to the view.
 class AutofillPopupLayoutModel {
  public:
-  explicit AutofillPopupLayoutModel(AutofillPopupViewDelegate* delegate);
+  AutofillPopupLayoutModel(AutofillPopupViewDelegate* delegate,
+                           bool is_credit_card_popup);
+
   ~AutofillPopupLayoutModel();
 
   // The minimum amount of padding between the Autofill name and subtext,
@@ -92,6 +94,27 @@
   // resource isn't recognized.
   int GetIconResourceID(const base::string16& resource_name) const;
 
+  // Returns whether |GetBackgroundColor, GetDividerColor| returns a custom
+  // color configured in an experiment to tweak autofill popup layout.
+  bool IsPopupLayoutExperimentEnabled() const;
+
+  // Returns the background color for the autofill popup, or
+  // |SK_ColorTRANSPARENT| if not in an experiment to tweak autofill popup
+  // layout.
+  SkColor GetBackgroundColor() const;
+
+  // Returns the divider color for the autofill popup, or
+  // |SK_ColorTRANSPARENT| if not in an experiment to tweak autofill popup
+  // layout.
+  SkColor GetDividerColor() const;
+
+  // Returns the dropdown item height, or 0 if the dropdown item height isn't
+  // configured in an experiment to tweak autofill popup layout.
+  unsigned int GetDropdownItemHeight() const;
+
+  // Returns true if suggestion icon must be displayed before suggestion text.
+  bool IsIconAtStart(int frontend_id) const;
+
  private:
   // Returns the enclosing rectangle for the element_bounds.
   const gfx::Rect RoundedElementBounds() const;
@@ -116,6 +139,8 @@
 
   AutofillPopupViewDelegate* delegate_;  // Weak reference.
 
+  const bool is_credit_card_popup_;
+
   DISALLOW_COPY_AND_ASSIGN(AutofillPopupLayoutModel);
 };
 
diff --git a/chrome/browser/ui/autofill/autofill_popup_layout_model_unittest.cc b/chrome/browser/ui/autofill/autofill_popup_layout_model_unittest.cc
index 47b408a7..920a88a 100644
--- a/chrome/browser/ui/autofill/autofill_popup_layout_model_unittest.cc
+++ b/chrome/browser/ui/autofill/autofill_popup_layout_model_unittest.cc
@@ -74,7 +74,8 @@
     ChromeRenderViewHostTestHarness::SetUp();
 
     delegate_.reset(new TestAutofillPopupViewDelegate(web_contents()));
-    layout_model_.reset(new AutofillPopupLayoutModel(delegate_.get()));
+    layout_model_.reset(new AutofillPopupLayoutModel(
+        delegate_.get(), false /* is_credit_card_field */));
   }
 
   AutofillPopupLayoutModel* layout_model() { return layout_model_.get(); }
diff --git a/chrome/browser/ui/browser_commands.cc b/chrome/browser/ui/browser_commands.cc
index 077e483..285a3828 100644
--- a/chrome/browser/ui/browser_commands.cc
+++ b/chrome/browser/ui/browser_commands.cc
@@ -87,6 +87,7 @@
 #include "extensions/features/features.h"
 #include "net/base/escape.h"
 #include "printing/features/features.h"
+#include "rlz/features/features.h"
 #include "ui/events/keycodes/keyboard_codes.h"
 
 #if BUILDFLAG(ENABLE_EXTENSIONS)
@@ -110,7 +111,7 @@
 #endif  // BUILDFLAG(ENABLE_PRINT_PREVIEW)
 #endif  // BUILDFLAG(ENABLE_PRINTING)
 
-#if defined(ENABLE_RLZ)
+#if BUILDFLAG(ENABLE_RLZ)
 #include "components/rlz/rlz_tracker.h"  // nogncheck
 #endif
 
@@ -473,7 +474,7 @@
   content::RecordAction(UserMetricsAction("Home"));
 
   std::string extra_headers;
-#if defined(ENABLE_RLZ)
+#if BUILDFLAG(ENABLE_RLZ)
   // If the home page is a Google home page, add the RLZ header to the request.
   PrefService* pref_service = browser->profile()->GetPrefs();
   if (pref_service) {
@@ -483,7 +484,7 @@
           rlz::RLZTracker::ChromeHomePage());
     }
   }
-#endif  // defined(ENABLE_RLZ)
+#endif  // BUILDFLAG(ENABLE_RLZ)
 
   GURL url = browser->profile()->GetHomePage();
 
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.h b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.h
index e390147..5f4fe0b 100644
--- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.h
+++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.h
@@ -294,10 +294,10 @@
   base::scoped_nsobject<BookmarkContextMenuCocoaController>
       contextMenuController_;
 
-  // Weak pointer to the pulsed button for the currently pulsing node. We need
-  // to store this as it may not be possible to determine the pulsing button if
-  // the pulsing node is deleted. Nil if there is no pulsing node.
-  BookmarkButton* pulsingButton_;
+  // The pulsed button for the currently pulsing node. We need to store this as
+  // it may not be possible to determine the pulsing button if the pulsing node
+  // is deleted. Nil if there is no pulsing node.
+  base::scoped_nsobject<BookmarkButton> pulsingButton_;
 
   // Specifically watch the currently pulsing node. This lets us stop pulsing
   // when anything happens to the node. Null if there is no pulsing node.
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.mm
index 51c7bce..d3b2c4f1 100644
--- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.mm
+++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.mm
@@ -361,7 +361,8 @@
 - (void)startPulsingBookmarkNode:(const BookmarkNode*)node {
   [self stopPulsingBookmarkNode];
 
-  pulsingButton_ = [self bookmarkButtonToPulseForNode:node];
+  pulsingButton_.reset([self bookmarkButtonToPulseForNode:node],
+                       base::scoped_policy::RETAIN);
   if (!pulsingButton_)
     return;
 
@@ -379,7 +380,7 @@
     return;
 
   [pulsingButton_ setPulseIsStuckOn:NO];
-  pulsingButton_ = nil;
+  pulsingButton_.reset();
   pulsingBookmarkObserver_.reset();
 }
 
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller_unittest.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller_unittest.mm
index c0056eb..a182b0f 100644
--- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller_unittest.mm
@@ -1568,6 +1568,46 @@
   EXPECT_TRUE([view isHidden]);
 }
 
+// Simulate coarse browser window width change and ensure that the bookmark
+// buttons that should be visible are visible.
+TEST_F(BookmarkBarControllerTest, RedistributeButtonsOnBarAsNeeded) {
+  // Hide the apps shortcut.
+  profile()->GetPrefs()->SetBoolean(
+      bookmarks::prefs::kShowAppsShortcutInBookmarkBar, false);
+  ASSERT_TRUE([bar_ appsPageShortcutButtonIsHidden]);
+
+  // Add three buttons to the bookmark bar.
+  BookmarkModel* model = BookmarkModelFactory::GetForBrowserContext(profile());
+  const BookmarkNode* root = model->bookmark_bar_node();
+  // Make long labels to test coarse resizes. After 16 digits, text eliding
+  // starts.
+  const std::string model_string(
+      "0000000000000000 1111111111111111 2222222222222222 ");
+  bookmarks::test::AddNodesFromModelString(model, root, model_string);
+  NSRect frame = [[bar_ view] frame];
+  frame.size.width = 400;  // Typical minimum browser size.
+  [[bar_ view] setFrame:frame];
+  EXPECT_EQ(2, [bar_ displayedButtonCount]);
+
+  {
+    base::mac::ScopedNSAutoreleasePool pool;
+    frame.size.width = 800;
+    [[bar_ view] setFrame:frame];
+    EXPECT_EQ(3, [bar_ displayedButtonCount]);
+
+    const BookmarkNode* last = model->bookmark_bar_node()->GetChild(2);
+    EXPECT_TRUE(last);
+    [bar_ startPulsingBookmarkNode:last];
+
+    frame.size.width = 400;
+    [[bar_ view] setFrame:frame];
+    EXPECT_EQ(2, [bar_ displayedButtonCount]);
+  }
+
+  // Regression test for http://crbug.com/616051.
+  [bar_ stopPulsingBookmarkNode];
+}
+
 // Simiulate browser window width change and ensure that the bookmark buttons
 // that should be visible are visible.
 // Appears to fail on Mac 10.11 bot on the waterfall; http://crbug.com/612640.
diff --git a/chrome/browser/ui/cocoa/profiles/avatar_base_controller.h b/chrome/browser/ui/cocoa/profiles/avatar_base_controller.h
index 05e33de..30bb569 100644
--- a/chrome/browser/ui/cocoa/profiles/avatar_base_controller.h
+++ b/chrome/browser/ui/cocoa/profiles/avatar_base_controller.h
@@ -35,7 +35,6 @@
   // as AvatarButtonErrorController.
   std::unique_ptr<ProfileUpdateObserver> profileObserver_;
 
- @private
   // The menu controller, if the menu is open.
   BaseBubbleController* menuController_;
 }
@@ -59,8 +58,6 @@
 
 @interface AvatarBaseController (ExposedForTesting)
 - (BaseBubbleController*)menuController;
-
-- (BOOL)isCtrlPressed;
 @end
 
 class ProfileUpdateObserver : public ProfileAttributesStorage::Observer,
diff --git a/chrome/browser/ui/cocoa/profiles/avatar_base_controller.mm b/chrome/browser/ui/cocoa/profiles/avatar_base_controller.mm
index fde4c663..a3e0d5a1 100644
--- a/chrome/browser/ui/cocoa/profiles/avatar_base_controller.mm
+++ b/chrome/browser/ui/cocoa/profiles/avatar_base_controller.mm
@@ -171,13 +171,6 @@
   profiles::TutorialMode tutorialMode;
   profiles::BubbleViewModeFromAvatarBubbleMode(
       mode, &viewMode, &tutorialMode);
-  // Don't start creating the view if it would be an empty fast user switcher.
-  // It has to happen here to prevent the view system from creating an empty
-  // container.
-  if (viewMode == profiles::BUBBLE_VIEW_MODE_FAST_PROFILE_CHOOSER &&
-      !profiles::HasProfileSwitchTargets(browser_->profile())) {
-    return;
-  }
 
   menuController_ =
       [[ProfileChooserController alloc] initWithBrowser:browser_
@@ -197,29 +190,9 @@
   ProfileMetrics::LogProfileOpenMethod(ProfileMetrics::ICON_AVATAR_BUBBLE);
 }
 
-- (BOOL)isCtrlPressed {
-  return [NSEvent modifierFlags] & NSControlKeyMask ? YES : NO;
-}
-
 - (IBAction)buttonClicked:(id)sender {
-  BrowserWindow::AvatarBubbleMode mode =
-      BrowserWindow::AVATAR_BUBBLE_MODE_DEFAULT;
-  if ([self isCtrlPressed])
-    mode = BrowserWindow::AVATAR_BUBBLE_MODE_FAST_USER_SWITCH;
-
   [self showAvatarBubbleAnchoredAt:button_
-                          withMode:mode
-                   withServiceType:signin::GAIA_SERVICE_TYPE_NONE
-                   fromAccessPoint:signin_metrics::AccessPoint::
-                                       ACCESS_POINT_AVATAR_BUBBLE_SIGN_IN];
-}
-
-- (IBAction)buttonRightClicked:(id)sender {
-  BrowserWindow::AvatarBubbleMode mode =
-      BrowserWindow::AVATAR_BUBBLE_MODE_FAST_USER_SWITCH;
-
-  [self showAvatarBubbleAnchoredAt:button_
-                          withMode:mode
+                          withMode:BrowserWindow::AVATAR_BUBBLE_MODE_DEFAULT
                    withServiceType:signin::GAIA_SERVICE_TYPE_NONE
                    fromAccessPoint:signin_metrics::AccessPoint::
                                        ACCESS_POINT_AVATAR_BUBBLE_SIGN_IN];
diff --git a/chrome/browser/ui/cocoa/profiles/avatar_button_controller.mm b/chrome/browser/ui/cocoa/profiles/avatar_button_controller.mm
index 13e7fab..7bc7e0d 100644
--- a/chrome/browser/ui/cocoa/profiles/avatar_button_controller.mm
+++ b/chrome/browser/ui/cocoa/profiles/avatar_button_controller.mm
@@ -185,7 +185,7 @@
       [avatarButton setAutoresizingMask:NSViewMinXMargin | NSViewMinYMargin];
     [avatarButton setTarget:self];
     [avatarButton setAction:@selector(buttonClicked:)];
-    [avatarButton setRightAction:@selector(buttonRightClicked:)];
+    [avatarButton setRightAction:@selector(buttonClicked:)];
 
     // Check if the account already has an authentication or sync error and
     // initialize the avatar button UI.
@@ -298,12 +298,13 @@
                           withMode:(BrowserWindow::AvatarBubbleMode)mode
                    withServiceType:(signin::GAIAServiceType)serviceType
                    fromAccessPoint:(signin_metrics::AccessPoint)accessPoint {
-  AvatarButton* button = base::mac::ObjCCastStrict<AvatarButton>(button_);
-  [button setIsActive:YES];
   [super showAvatarBubbleAnchoredAt:anchor
                            withMode:mode
                     withServiceType:serviceType
                     fromAccessPoint:accessPoint];
+
+  AvatarButton* button = base::mac::ObjCCastStrict<AvatarButton>(button_);
+  [button setIsActive:[[menuController_ window] isVisible]];
 }
 
 - (void)bubbleWillClose:(NSNotification*)notif {
diff --git a/chrome/browser/ui/cocoa/profiles/avatar_button_controller_unittest.mm b/chrome/browser/ui/cocoa/profiles/avatar_button_controller_unittest.mm
index 015cfbd5..8e7d6d3 100644
--- a/chrome/browser/ui/cocoa/profiles/avatar_button_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/profiles/avatar_button_controller_unittest.mm
@@ -29,31 +29,6 @@
 - (void)setErrorStatus:(BOOL)hasError;
 @end
 
-// Subclassing AvatarButtonController to be able to control the state of
-// keyboard modifierFlags.
-@interface AvatarButtonControllerForTesting : AvatarButtonController {
- @private
-  bool isCtrlPressed_;
-}
-@end
-
-@interface AvatarButtonControllerForTesting (ExposedForTesting)
-- (void)setIsCtrlPressed:(BOOL)isPressed;
-- (BOOL)isCtrlPressed;
-@end
-
-@implementation AvatarButtonControllerForTesting
-- (void)setIsCtrlPressed:(BOOL)isPressed {
-  isCtrlPressed_ = isPressed;
-}
-
-- (BOOL)isCtrlPressed {
- // Always report that Cmd is not pressed since that's the case we're testing
- // and otherwise running the test while holding the Cmd key makes it fail.
- return isCtrlPressed_;
-}
-@end
-
 class AvatarButtonControllerTest : public CocoaProfileTest {
  public:
   void SetUp() override {
@@ -63,8 +38,7 @@
     ASSERT_TRUE(browser());
 
     controller_.reset(
-        [[AvatarButtonControllerForTesting alloc] initWithBrowser:browser()]);
-    [controller_ setIsCtrlPressed:false];
+        [[AvatarButtonController alloc] initWithBrowser:browser()]);
   }
 
   void TearDown() override {
@@ -76,10 +50,10 @@
 
   NSView* view() { return [controller_ view]; }
 
-  AvatarButtonControllerForTesting* controller() { return controller_.get(); }
+  AvatarButtonController* controller() { return controller_.get(); }
 
  private:
-  base::scoped_nsobject<AvatarButtonControllerForTesting> controller_;
+  base::scoped_nsobject<AvatarButtonController> controller_;
 };
 
 TEST_F(AvatarButtonControllerTest, GenericButtonShown) {
@@ -130,32 +104,3 @@
   [menu close];
   EXPECT_FALSE([controller() menuController]);
 }
-
-TEST_F(AvatarButtonControllerTest, DontOpenFastSwitcherWithoutTarget) {
-  EXPECT_FALSE([controller() menuController]);
-
-  [controller() setIsCtrlPressed:YES];
-  [button() performClick:button()];
-
-  // If there's only one profile and the fast user switcher is requested,
-  // nothing should happen.
-  EXPECT_FALSE([controller() menuController]);
-}
-
-TEST_F(AvatarButtonControllerTest, OpenFastUserSwitcherWithTarget) {
-  testing_profile_manager()->CreateTestingProfile("batman");
-  EXPECT_FALSE([controller() menuController]);
-
-  [controller() setIsCtrlPressed:YES];
-  [button() performClick:button()];
-
-  BaseBubbleController* menu = [controller() menuController];
-  EXPECT_TRUE(menu);
-  EXPECT_TRUE([menu isKindOfClass:[ProfileChooserController class]]);
-
-  // Do not animate out because that is hard to test around.
-  static_cast<InfoBubbleWindow*>(menu.window).allowedAnimations =
-      info_bubble::kAnimateNone;
-  [menu close];
-  EXPECT_FALSE([controller() menuController]);
-}
diff --git a/chrome/browser/ui/cocoa/website_settings/website_settings_bubble_controller.h b/chrome/browser/ui/cocoa/website_settings/website_settings_bubble_controller.h
index 10bfdff..f59a72bf 100644
--- a/chrome/browser/ui/cocoa/website_settings/website_settings_bubble_controller.h
+++ b/chrome/browser/ui/cocoa/website_settings/website_settings_bubble_controller.h
@@ -8,7 +8,7 @@
 
 #include "base/mac/scoped_nsobject.h"
 #include "base/macros.h"
-#import "chrome/browser/ui/cocoa/base_bubble_controller.h"
+#import "chrome/browser/ui/cocoa/omnibox_decoration_bubble_controller.h"
 #include "chrome/browser/ui/website_settings/website_settings_ui.h"
 #include "content/public/browser/web_contents_observer.h"
 
@@ -31,7 +31,7 @@
 //
 // TODO(palmer): Normalize all WebsiteSettings*, SiteSettings*, PageInfo*, et c.
 // to OriginInfo*.
-@interface WebsiteSettingsBubbleController : BaseBubbleController {
+@interface WebsiteSettingsBubbleController : OmniboxDecorationBubbleController {
  @private
   content::WebContents* webContents_;
 
diff --git a/chrome/browser/ui/cocoa/website_settings/website_settings_bubble_controller.mm b/chrome/browser/ui/cocoa/website_settings/website_settings_bubble_controller.mm
index 23152e05..df64d4e3 100644
--- a/chrome/browser/ui/cocoa/website_settings/website_settings_bubble_controller.mm
+++ b/chrome/browser/ui/cocoa/website_settings/website_settings_bubble_controller.mm
@@ -235,6 +235,12 @@
   return self;
 }
 
+- (LocationBarDecoration*)decorationForBubble {
+  BrowserWindowController* controller = [[self parentWindow] windowController];
+  LocationBarViewMac* location_bar = [controller locationBarBridge];
+  return location_bar ? location_bar->GetPageInfoDecoration() : nullptr;
+}
+
 - (Profile*)profile {
   return Profile::FromBrowserContext(webContents_->GetBrowserContext());
 }
diff --git a/chrome/browser/ui/layout_constants.cc b/chrome/browser/ui/layout_constants.cc
index 9611f19..264409f 100644
--- a/chrome/browser/ui/layout_constants.cc
+++ b/chrome/browser/ui/layout_constants.cc
@@ -9,91 +9,47 @@
 #include "ui/base/material_design/material_design_controller.h"
 
 int GetLayoutConstant(LayoutConstant constant) {
-  const int kFindBarVerticalOffset[] = {6, 6};
-  const int kLocationBarBorderThickness[] = {1, 1};
-  const int kLocationBarBubbleFontVerticalPadding[] = {2, 4};
-  const int kLocationBarBubbleVerticalPadding[] = {3, 3};
-  const int kLocationBarBubbleAnchorVerticalInset[] = {6, 8};
-  const int kLocationBarHeight[] = {28, 32};
-  const int kLocationBarHorizontalPadding[] = {6, 6};
-  const int kLocationBarVerticalPadding[] = {1, 1};
-  const int kOmniboxFontPixelSize[] = {14, 14};
-  const int kTabFaviconTitleSpacing[] = {6, 6};
-  const int kTabHeight[] = {29, 33};
-  const int kTabPinnedContentWidth[] = {23, 23};
-  const int kTabstripNewTabButtonOverlap[] = {5, 6};
-  const int kTabstripTabOverlap[] = {16, 16};
-  const int kToolbarStandardSpacing[] = {4, 8};
-  const int kToolbarElementPadding[] = {0, 8};
-  const int kToolbarLocationBarRightPadding[] = {4, 8};
-
-  const int mode = ui::MaterialDesignController::GetMode();
+  const bool hybrid = ui::MaterialDesignController::GetMode() ==
+                      ui::MaterialDesignController::MATERIAL_HYBRID;
   switch (constant) {
-    case AVATAR_ICON_PADDING:
-      return 4;
-    case FIND_BAR_TOOLBAR_OVERLAP:
-      return kFindBarVerticalOffset[mode];
-    case LOCATION_BAR_BORDER_THICKNESS:
-      return kLocationBarBorderThickness[mode];
     case LOCATION_BAR_BUBBLE_FONT_VERTICAL_PADDING:
-      return kLocationBarBubbleFontVerticalPadding[mode];
-    case LOCATION_BAR_BUBBLE_VERTICAL_PADDING:
-      return kLocationBarBubbleVerticalPadding[mode];
+      return hybrid ? 4 : 2;
     case LOCATION_BAR_BUBBLE_ANCHOR_VERTICAL_INSET:
       if (ui::MaterialDesignController::IsSecondaryUiMaterial())
         return 1;
-      return kLocationBarBubbleAnchorVerticalInset[mode];
+      return hybrid ? 8 : 6;
     case LOCATION_BAR_HEIGHT:
-      return kLocationBarHeight[mode];
-    case LOCATION_BAR_HORIZONTAL_PADDING:
-      return kLocationBarHorizontalPadding[mode];
-    case LOCATION_BAR_VERTICAL_PADDING:
-      return kLocationBarVerticalPadding[mode];
-    case OMNIBOX_FONT_PIXEL_SIZE:
-      return kOmniboxFontPixelSize[mode];
+      return hybrid ? 32 : 28;
     case TABSTRIP_NEW_TAB_BUTTON_OVERLAP:
-      return kTabstripNewTabButtonOverlap[mode];
-    case TABSTRIP_TAB_OVERLAP:
-      return kTabstripTabOverlap[mode];
-    case TAB_FAVICON_TITLE_SPACING:
-      return kTabFaviconTitleSpacing[mode];
+      return hybrid ? 6 : 5;
     case TAB_HEIGHT:
-      return kTabHeight[mode];
-    case TAB_PINNED_CONTENT_WIDTH:
-      return kTabPinnedContentWidth[mode];
-    case TOOLBAR_BUTTON_PADDING:
-      return 6;
+      return hybrid ? 33 : 29;
     case TOOLBAR_ELEMENT_PADDING:
-      return kToolbarElementPadding[mode];
-    case TOOLBAR_LOCATION_BAR_RIGHT_PADDING:
-      return kToolbarLocationBarRightPadding[mode];
+      return hybrid ? 8 : 0;
     case TOOLBAR_STANDARD_SPACING:
-      return kToolbarStandardSpacing[mode];
+      return hybrid ? 8 : 4;
   }
   NOTREACHED();
   return 0;
 }
 
 gfx::Insets GetLayoutInsets(LayoutInset inset) {
+  const bool hybrid = ui::MaterialDesignController::GetMode() ==
+                      ui::MaterialDesignController::MATERIAL_HYBRID;
   switch (inset) {
-    case TAB: {
-      const bool hybrid = ui::MaterialDesignController::GetMode() ==
-                          ui::MaterialDesignController::MATERIAL_HYBRID;
+    case TAB:
       return gfx::Insets(1, hybrid ? 18 : 16);
-    }
   }
   NOTREACHED();
   return gfx::Insets();
 }
 
 gfx::Size GetLayoutSize(LayoutSize size) {
-  const int kNewTabButtonWidth[] = {36, 39};
-  const int kNewTabButtonHeight[] = {18, 21};
-
-  const int mode = ui::MaterialDesignController::GetMode();
+  const bool hybrid = ui::MaterialDesignController::GetMode() ==
+                      ui::MaterialDesignController::MATERIAL_HYBRID;
   switch (size) {
     case NEW_TAB_BUTTON:
-      return gfx::Size(kNewTabButtonWidth[mode], kNewTabButtonHeight[mode]);
+      return hybrid ? gfx::Size(39, 21) : gfx::Size(36, 18);
   }
   NOTREACHED();
   return gfx::Size();
diff --git a/chrome/browser/ui/layout_constants.h b/chrome/browser/ui/layout_constants.h
index 9f380c3..b51bdcba 100644
--- a/chrome/browser/ui/layout_constants.h
+++ b/chrome/browser/ui/layout_constants.h
@@ -9,22 +9,10 @@
 #include "ui/gfx/geometry/size.h"
 
 enum LayoutConstant {
-  // The padding on the left, right, and bottom of the avatar icon.
-  AVATAR_ICON_PADDING,
-
-  // Vertical offset from top of content to the top of find bar.
-  FIND_BAR_TOOLBAR_OVERLAP,
-
-  // The thickness of the location bar's border.
-  LOCATION_BAR_BORDER_THICKNESS,
-
   // The vertical padding between the edge of a location bar bubble and its
   // contained text.
   LOCATION_BAR_BUBBLE_FONT_VERTICAL_PADDING,
 
-  // The additional vertical padding of a bubble.
-  LOCATION_BAR_BUBBLE_VERTICAL_PADDING,
-
   // The vertical inset to apply to the bounds of a location bar bubble's anchor
   // view, to bring the bubble closer to the anchor.  This compensates for the
   // space between the bottoms of most such views and the visible bottoms of the
@@ -34,43 +22,17 @@
   // The height to be occupied by the LocationBar.
   LOCATION_BAR_HEIGHT,
 
-  // Space between items in the location bar, as well as between items and the
-  // edges.
-  LOCATION_BAR_HORIZONTAL_PADDING,
-
-  // Space between the location bar edge and contents.
-  LOCATION_BAR_VERTICAL_PADDING,
-
-  // The font size to use in the location bar and omnibox dropdown, in pixels.
-  OMNIBOX_FONT_PIXEL_SIZE,
-
   // The amount of overlap between the last tab and the new tab button.
   TABSTRIP_NEW_TAB_BUTTON_OVERLAP,
 
-  // The amount of overlap between two adjacent tabs.
-  TABSTRIP_TAB_OVERLAP,
-
-  // The horizontal space between a tab's favicon and its title.
-  TAB_FAVICON_TITLE_SPACING,
-
   // The height of a tab, including outer strokes.  In non-100% scales this is
   // slightly larger than the apparent height of the tab, as the top stroke is
   // drawn as a 1-px line flush with the bottom of the tab's topmost DIP.
   TAB_HEIGHT,
 
-  // Width available for content inside a pinned tab.
-  TAB_PINNED_CONTENT_WIDTH,
-
-  // Padding inside toolbar button, between its border and image.
-  TOOLBAR_BUTTON_PADDING,
-
   // Additional horizontal padding between the elements in the toolbar.
   TOOLBAR_ELEMENT_PADDING,
 
-  // Padding between the right edge of the location bar and the left edge of the
-  // app menu icon when the browser actions container is not present.
-  TOOLBAR_LOCATION_BAR_RIGHT_PADDING,
-
   // The horizontal space between most items in the toolbar.
   TOOLBAR_STANDARD_SPACING,
 };
diff --git a/chrome/browser/ui/startup/startup_browser_creator_impl.cc b/chrome/browser/ui/startup/startup_browser_creator_impl.cc
index b088b96..214243e 100644
--- a/chrome/browser/ui/startup/startup_browser_creator_impl.cc
+++ b/chrome/browser/ui/startup/startup_browser_creator_impl.cc
@@ -103,6 +103,7 @@
 #include "extensions/common/extension.h"
 #include "extensions/common/extension_set.h"
 #include "net/base/network_change_notifier.h"
+#include "rlz/features/features.h"
 #include "ui/base/l10n/l10n_util.h"
 
 #if defined(OS_MACOSX)
@@ -117,7 +118,7 @@
 #include "chrome/browser/shell_integration_win.h"
 #endif
 
-#if defined(ENABLE_RLZ)
+#if BUILDFLAG(ENABLE_RLZ)
 #include "components/rlz/rlz_tracker.h"  // nogncheck
 #endif
 
@@ -471,12 +472,12 @@
                                    : WindowOpenDisposition::NEW_BACKGROUND_TAB;
     params.tabstrip_add_types = add_types;
 
-#if defined(ENABLE_RLZ)
+#if BUILDFLAG(ENABLE_RLZ)
     if (process_startup && google_util::IsGoogleHomePageUrl(tabs[i].url)) {
       params.extra_headers = rlz::RLZTracker::GetAccessPointHttpHeader(
           rlz::RLZTracker::ChromeHomePage());
     }
-#endif  // defined(ENABLE_RLZ)
+#endif  // BUILDFLAG(ENABLE_RLZ)
 
     chrome::Navigate(&params);
 
diff --git a/chrome/browser/ui/views/ash/OWNERS b/chrome/browser/ui/views/ash/OWNERS
index f19e7650..6c1a33b 100644
--- a/chrome/browser/ui/views/ash/OWNERS
+++ b/chrome/browser/ui/views/ash/OWNERS
@@ -1,2 +1,4 @@
 derat@chromium.org
 sky@chromium.org
+jamescook@chromium.org
+erg@chromium.org
diff --git a/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.cc b/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.cc
index f158192..83f63ce 100644
--- a/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.cc
+++ b/chrome/browser/ui/views/chrome_browser_main_extra_parts_views.cc
@@ -6,7 +6,7 @@
 
 #include "chrome/browser/ui/views/chrome_constrained_window_views_client.h"
 #include "chrome/browser/ui/views/chrome_views_delegate.h"
-#include "chrome/browser/ui/views/ime_driver_mus.h"
+#include "chrome/browser/ui/views/ime_driver/ime_driver_mus.h"
 #include "components/constrained_window/constrained_window_views.h"
 
 #if defined(USE_AURA)
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view.h b/chrome/browser/ui/views/frame/browser_non_client_frame_view.h
index 9fbced7..c09ae08 100644
--- a/chrome/browser/ui/views/frame/browser_non_client_frame_view.h
+++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view.h
@@ -17,6 +17,9 @@
 class BrowserNonClientFrameView : public views::NonClientFrameView,
                                   public ProfileAttributesStorage::Observer {
  public:
+  // The padding on the left, right, and bottom of the avatar icon.
+  static constexpr int kAvatarIconPadding = 4;
+
   BrowserNonClientFrameView(BrowserFrame* frame, BrowserView* browser_view);
   ~BrowserNonClientFrameView() override;
 
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc
index b137776..6fb936b 100644
--- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc
+++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc
@@ -408,10 +408,11 @@
 // BrowserNonClientFrameViewAsh, private:
 
 int BrowserNonClientFrameViewAsh::GetTabStripLeftInset() const {
-  const int pad = GetLayoutConstant(AVATAR_ICON_PADDING);
   const int avatar_right =
-      profile_indicator_icon() ? (pad + GetIncognitoAvatarIcon().width()) : 0;
-  return avatar_right + pad;
+      profile_indicator_icon()
+          ? (kAvatarIconPadding + GetIncognitoAvatarIcon().width())
+          : 0;
+  return avatar_right + kAvatarIconPadding;
 }
 
 int BrowserNonClientFrameViewAsh::GetTabStripRightInset() const {
@@ -448,9 +449,9 @@
 #endif
 
   const gfx::ImageSkia incognito_icon = GetIncognitoAvatarIcon();
-  const int pad = GetLayoutConstant(AVATAR_ICON_PADDING);
-  const int avatar_bottom =
-      GetTopInset(false) + browser_view()->GetTabStripHeight() - pad;
+  const int avatar_bottom = GetTopInset(false) +
+                            browser_view()->GetTabStripHeight() -
+                            kAvatarIconPadding;
   int avatar_y = avatar_bottom - incognito_icon.height();
 
   // Hide the incognito icon in immersive fullscreen when the tab light bar is
@@ -458,8 +459,8 @@
   // recognizable.
   const bool avatar_visible = !UseImmersiveLightbarHeaderStyle();
   const int avatar_height = avatar_visible ? (avatar_bottom - avatar_y) : 0;
-  profile_indicator_icon()->SetBounds(pad, avatar_y, incognito_icon.width(),
-                                      avatar_height);
+  profile_indicator_icon()->SetBounds(kAvatarIconPadding, avatar_y,
+                                      incognito_icon.width(), avatar_height);
   profile_indicator_icon()->SetVisible(avatar_visible);
 }
 
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_mus.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_mus.cc
index 58cf38f8..8c303f6 100644
--- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_mus.cc
+++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_mus.cc
@@ -371,11 +371,12 @@
 }
 
 int BrowserNonClientFrameViewMus::GetTabStripLeftInset() const {
-  const int pad = GetLayoutConstant(AVATAR_ICON_PADDING);
-  const int avatar_right = profile_indicator_icon()
-      ? (pad + GetIncognitoAvatarIcon().width())
-      : 0;
-  return avatar_right + pad + frame_values().normal_insets.left();
+  const int avatar_right =
+      profile_indicator_icon()
+          ? (kAvatarIconPadding + GetIncognitoAvatarIcon().width())
+          : 0;
+  return avatar_right + kAvatarIconPadding +
+         frame_values().normal_insets.left();
 }
 
 int BrowserNonClientFrameViewMus::GetTabStripRightInset() const {
@@ -424,9 +425,8 @@
   DCHECK(browser_view()->IsTabStripVisible());
 #endif
   gfx::ImageSkia incognito_icon = GetIncognitoAvatarIcon();
-  const int pad = GetLayoutConstant(AVATAR_ICON_PADDING);
-  int avatar_bottom =
-      GetTopInset(false) + browser_view()->GetTabStripHeight() - pad;
+  int avatar_bottom = GetTopInset(false) + browser_view()->GetTabStripHeight() -
+                      kAvatarIconPadding;
   int avatar_y = avatar_bottom - incognito_icon.height();
 
   // Hide the incognito icon in immersive fullscreen when the tab light bar is
@@ -435,7 +435,8 @@
   bool avatar_visible = !UseImmersiveLightbarHeaderStyle();
   int avatar_height = avatar_visible ? incognito_icon.height() : 0;
 
-  gfx::Rect avatar_bounds(pad, avatar_y, incognito_icon.width(), avatar_height);
+  gfx::Rect avatar_bounds(kAvatarIconPadding, avatar_y, incognito_icon.width(),
+                          avatar_height);
   profile_indicator_icon()->SetBoundsRect(avatar_bounds);
   profile_indicator_icon()->SetVisible(avatar_visible);
 }
diff --git a/chrome/browser/ui/views/frame/browser_view_layout.cc b/chrome/browser/ui/views/frame/browser_view_layout.cc
index 18c70c1..11214a86 100644
--- a/chrome/browser/ui/views/frame/browser_view_layout.cc
+++ b/chrome/browser/ui/views/frame/browser_view_layout.cc
@@ -12,7 +12,6 @@
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/find_bar/find_bar.h"
 #include "chrome/browser/ui/find_bar/find_bar_controller.h"
-#include "chrome/browser/ui/layout_constants.h"
 #include "chrome/browser/ui/search/search_model.h"
 #include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h"
 #include "chrome/browser/ui/views/download/download_shelf_view.h"
@@ -222,10 +221,8 @@
     find_bar_y = top_container_bounds.bottom();
   } else {
     // Overlap the find bar atop |top_container_|.
-    // The find bar should look connected to the top container when material
-    // design is not enabled.
-    find_bar_y = top_container_bounds.bottom() -
-                 GetLayoutConstant(FIND_BAR_TOOLBAR_OVERLAP);
+    const int kTopOverlap = 6;
+    find_bar_y = top_container_bounds.bottom() - kTopOverlap;
   }
 
   // Grow the height of |bounding_box| by the height of any elements between
diff --git a/chrome/browser/ui/views/frame/browser_view_unittest.cc b/chrome/browser/ui/views/frame/browser_view_unittest.cc
index 470136e0..a12611c 100644
--- a/chrome/browser/ui/views/frame/browser_view_unittest.cc
+++ b/chrome/browser/ui/views/frame/browser_view_unittest.cc
@@ -7,7 +7,6 @@
 #include "base/macros.h"
 #include "chrome/app/chrome_command_ids.h"
 #include "chrome/browser/ui/browser_commands.h"
-#include "chrome/browser/ui/layout_constants.h"
 #include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h"
 #include "chrome/browser/ui/views/frame/browser_view_layout.h"
 #include "chrome/browser/ui/views/frame/test_with_browser_view.h"
diff --git a/chrome/browser/ui/views/frame/glass_browser_frame_view.cc b/chrome/browser/ui/views/frame/glass_browser_frame_view.cc
index 0ceb12d4..d78a8b72 100644
--- a/chrome/browser/ui/views/frame/glass_browser_frame_view.cc
+++ b/chrome/browser/ui/views/frame/glass_browser_frame_view.cc
@@ -139,8 +139,7 @@
 
 gfx::Rect GlassBrowserFrameView::GetBoundsForTabStrip(
     views::View* tabstrip) const {
-  const int x =
-      incognito_bounds_.right() + GetLayoutConstant(AVATAR_ICON_PADDING);
+  const int x = incognito_bounds_.right() + kAvatarIconPadding;
   int end_x = width() - ClientBorderThickness(false);
   if (!CaptionButtonsOnLeadingEdge()) {
     end_x = std::min(MinimizeButtonX(), end_x) -
@@ -739,7 +738,6 @@
 }
 
 void GlassBrowserFrameView::LayoutIncognitoIcon() {
-  const int pad = GetLayoutConstant(AVATAR_ICON_PADDING);
   const gfx::Size size(GetIncognitoAvatarIcon().size());
   int x = ClientBorderThickness(false);
   // In RTL, the icon needs to start after the caption buttons.
@@ -749,11 +747,12 @@
                                      kProfileSwitcherButtonOffset)
                                   : 0);
   }
-  const int bottom =
-      GetTopInset(false) + browser_view()->GetTabStripHeight() - pad;
+  const int bottom = GetTopInset(false) + browser_view()->GetTabStripHeight() -
+                     kAvatarIconPadding;
   incognito_bounds_.SetRect(
-      x + (profile_indicator_icon() ? pad : 0), bottom - size.height(),
-      profile_indicator_icon() ? size.width() : 0, size.height());
+      x + (profile_indicator_icon() ? kAvatarIconPadding : 0),
+      bottom - size.height(), profile_indicator_icon() ? size.width() : 0,
+      size.height());
   if (profile_indicator_icon())
     profile_indicator_icon()->SetBoundsRect(incognito_bounds_);
 }
diff --git a/chrome/browser/ui/views/frame/opaque_browser_frame_view_layout.cc b/chrome/browser/ui/views/frame/opaque_browser_frame_view_layout.cc
index 36ed8cc..398fcf0 100644
--- a/chrome/browser/ui/views/frame/opaque_browser_frame_view_layout.cc
+++ b/chrome/browser/ui/views/frame/opaque_browser_frame_view_layout.cc
@@ -107,7 +107,7 @@
 gfx::Rect OpaqueBrowserFrameViewLayout::GetBoundsForTabStrip(
     const gfx::Size& tabstrip_preferred_size,
     int available_width) const {
-  int x = leading_button_start_ + GetLayoutConstant(AVATAR_ICON_PADDING);
+  int x = leading_button_start_ + OpaqueBrowserFrameView::kAvatarIconPadding;
   available_width -= x + NewTabCaptionSpacing() + trailing_button_start_;
   return gfx::Rect(x, GetTabStripInsetsTop(false), std::max(0, available_width),
                    tabstrip_preferred_size.height());
@@ -369,7 +369,7 @@
   trailing_button_start_ = std::max(trailing_button_start_, min_button_width);
 
   if (incognito_icon_) {
-    const int pad = GetLayoutConstant(AVATAR_ICON_PADDING);
+    constexpr int pad = OpaqueBrowserFrameView::kAvatarIconPadding;
     const gfx::Size size(delegate_->GetIncognitoAvatarIcon().size());
     const int incognito_width = pad + size.width();
     int x;
diff --git a/chrome/browser/ui/views/frame/opaque_browser_frame_view_layout_unittest.cc b/chrome/browser/ui/views/frame/opaque_browser_frame_view_layout_unittest.cc
index 156121c..bc18be5 100644
--- a/chrome/browser/ui/views/frame/opaque_browser_frame_view_layout_unittest.cc
+++ b/chrome/browser/ui/views/frame/opaque_browser_frame_view_layout_unittest.cc
@@ -236,7 +236,7 @@
           (maximized ? OBFVL::kCaptionSpacing
                      : -GetLayoutSize(NEW_TAB_BUTTON).width());
     }
-    int tabstrip_x = GetLayoutConstant(AVATAR_ICON_PADDING);
+    int tabstrip_x = OpaqueBrowserFrameView::kAvatarIconPadding;
     if (show_caption_buttons && caption_buttons_on_left) {
       int right_of_close =
           maximized ? kMaximizedExtraCloseWidth : OBFVL::kFrameBorderThickness;
diff --git a/chrome/browser/ui/views/ime_driver/ime_driver_mus.cc b/chrome/browser/ui/views/ime_driver/ime_driver_mus.cc
new file mode 100644
index 0000000..763cbd90
--- /dev/null
+++ b/chrome/browser/ui/views/ime_driver/ime_driver_mus.cc
@@ -0,0 +1,58 @@
+// 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 "chrome/browser/ui/views/ime_driver/ime_driver_mus.h"
+
+#include "content/public/browser/browser_thread.h"
+#include "content/public/common/service_manager_connection.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
+#include "services/service_manager/public/cpp/connector.h"
+#include "services/ui/public/interfaces/constants.mojom.h"
+#include "services/ui/public/interfaces/ime/ime.mojom.h"
+#include "ui/base/ime/ime_bridge.h"
+
+#if defined(OS_CHROMEOS)
+#include "chrome/browser/ui/views/ime_driver/input_method_bridge_chromeos.h"
+#else
+#include "chrome/browser/ui/views/ime_driver/simple_input_method.h"
+#endif  // defined(OS_CHROMEOS)
+
+IMEDriver::IMEDriver() {
+  ui::IMEBridge::Initialize();
+}
+
+IMEDriver::~IMEDriver() {}
+
+// static
+void IMEDriver::Register() {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  ui::mojom::IMEDriverPtr ime_driver_ptr;
+  mojo::MakeStrongBinding(base::MakeUnique<IMEDriver>(),
+                          GetProxy(&ime_driver_ptr));
+  ui::mojom::IMERegistrarPtr ime_registrar;
+  content::ServiceManagerConnection::GetForProcess()
+      ->GetConnector()
+      ->ConnectToInterface(ui::mojom::kServiceName, &ime_registrar);
+  ime_registrar->RegisterDriver(std::move(ime_driver_ptr));
+}
+
+void IMEDriver::StartSession(
+    int32_t session_id,
+    ui::mojom::TextInputClientPtr client,
+    ui::mojom::InputMethodRequest input_method_request) {
+#if defined(OS_CHROMEOS)
+  input_method_bindings_[session_id] =
+      base::MakeUnique<mojo::Binding<ui::mojom::InputMethod>>(
+          new InputMethodBridge(std::move(client)),
+          std::move(input_method_request));
+#else
+  input_method_bindings_[session_id] =
+      base::MakeUnique<mojo::Binding<ui::mojom::InputMethod>>(
+          new SimpleInputMethod());
+#endif
+}
+
+void IMEDriver::CancelSession(int32_t session_id) {
+  input_method_bindings_.erase(session_id);
+}
diff --git a/chrome/browser/ui/views/ime_driver_mus.h b/chrome/browser/ui/views/ime_driver/ime_driver_mus.h
similarity index 82%
rename from chrome/browser/ui/views/ime_driver_mus.h
rename to chrome/browser/ui/views/ime_driver/ime_driver_mus.h
index bc70b37..e81d34d 100644
--- a/chrome/browser/ui/views/ime_driver_mus.h
+++ b/chrome/browser/ui/views/ime_driver/ime_driver_mus.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_IME_DRIVER_MUS_H_
-#define CHROME_BROWSER_UI_VIEWS_IME_DRIVER_MUS_H_
+#ifndef CHROME_BROWSER_UI_VIEWS_IME_DRIVER_IME_DRIVER_MUS_H_
+#define CHROME_BROWSER_UI_VIEWS_IME_DRIVER_IME_DRIVER_MUS_H_
 
 #include <stdint.h>
 
@@ -15,14 +15,13 @@
 
 class IMEDriver : public ui::mojom::IMEDriver {
  public:
+  IMEDriver();
   ~IMEDriver() override;
 
   // Instantiate the IME driver and register it to the UI service.
   static void Register();
 
  private:
-  IMEDriver();
-
   // ui::mojom::IMEDriver:
   void StartSession(
       int32_t session_id,
@@ -36,4 +35,4 @@
   DISALLOW_COPY_AND_ASSIGN(IMEDriver);
 };
 
-#endif  // CHROME_BROWSER_UI_VIEWS_IME_DRIVER_MUS_H_
+#endif  // CHROME_BROWSER_UI_VIEWS_IME_DRIVER_IME_DRIVER_MUS_H_
diff --git a/chrome/browser/ui/views/ime_driver/input_method_bridge_chromeos.cc b/chrome/browser/ui/views/ime_driver/input_method_bridge_chromeos.cc
new file mode 100644
index 0000000..76869b1c
--- /dev/null
+++ b/chrome/browser/ui/views/ime_driver/input_method_bridge_chromeos.cc
@@ -0,0 +1,48 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/views/ime_driver/input_method_bridge_chromeos.h"
+
+#include "chrome/browser/ui/views/ime_driver/remote_text_input_client.h"
+
+InputMethodBridge::InputMethodBridge(ui::mojom::TextInputClientPtr client)
+    : client_(base::MakeUnique<RemoteTextInputClient>(std::move(client))),
+      input_method_chromeos_(
+          base::MakeUnique<ui::InputMethodChromeOS>(nullptr)) {
+  input_method_chromeos_->SetFocusedTextInputClient(client_.get());
+}
+
+InputMethodBridge::~InputMethodBridge() {}
+
+void InputMethodBridge::OnTextInputModeChanged(
+    ui::mojom::TextInputMode text_input_mode) {
+  // TODO(moshayedi): crbug.com/631527. Consider removing this, as
+  // ui::InputMethodChromeOS doesn't have this.
+}
+
+void InputMethodBridge::OnTextInputTypeChanged(
+    ui::mojom::TextInputType text_input_type) {
+  input_method_chromeos_->OnTextInputTypeChanged(client_.get());
+}
+
+void InputMethodBridge::OnCaretBoundsChanged(const gfx::Rect& caret_bounds) {
+  input_method_chromeos_->OnCaretBoundsChanged(client_.get());
+}
+
+void InputMethodBridge::ProcessKeyEvent(
+    std::unique_ptr<ui::Event> event,
+    const ProcessKeyEventCallback& callback) {
+  DCHECK(event->IsKeyEvent());
+  ui::KeyEvent* key_event = event->AsKeyEvent();
+  if (!key_event->is_char()) {
+    input_method_chromeos_->DispatchKeyEvent(
+        key_event, base::MakeUnique<base::Callback<void(bool)>>(callback));
+  } else {
+    callback.Run(false);
+  }
+}
+
+void InputMethodBridge::CancelComposition() {
+  input_method_chromeos_->CancelComposition(client_.get());
+}
diff --git a/chrome/browser/ui/views/ime_driver/input_method_bridge_chromeos.h b/chrome/browser/ui/views/ime_driver/input_method_bridge_chromeos.h
new file mode 100644
index 0000000..d757a75
--- /dev/null
+++ b/chrome/browser/ui/views/ime_driver/input_method_bridge_chromeos.h
@@ -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.
+
+#ifndef CHROME_BROWSER_UI_VIEWS_IME_DRIVER_INPUT_METHOD_BRIDGE_CHROMEOS_H_
+#define CHROME_BROWSER_UI_VIEWS_IME_DRIVER_INPUT_METHOD_BRIDGE_CHROMEOS_H_
+
+#include "services/ui/public/interfaces/ime/ime.mojom.h"
+#include "ui/base/ime/input_method_chromeos.h"
+
+// This bridges between mojo InputMethod API and ui::InputMethodChromeOS. It
+// forwards the received events to an instance of ui::InputMethodChromeOS.
+class InputMethodBridge : public ui::mojom::InputMethod {
+ public:
+  explicit InputMethodBridge(ui::mojom::TextInputClientPtr client);
+  ~InputMethodBridge() override;
+
+  // ui::mojom::InputMethod:
+  void OnTextInputModeChanged(
+      ui::mojom::TextInputMode text_input_mode) override;
+  void OnTextInputTypeChanged(
+      ui::mojom::TextInputType text_input_type) override;
+  void OnCaretBoundsChanged(const gfx::Rect& caret_bounds) override;
+  void ProcessKeyEvent(std::unique_ptr<ui::Event> key_event,
+                       const ProcessKeyEventCallback& callback) override;
+  void CancelComposition() override;
+
+ private:
+  std::unique_ptr<ui::TextInputClient> client_;
+  std::unique_ptr<ui::InputMethodChromeOS> input_method_chromeos_;
+
+  DISALLOW_COPY_AND_ASSIGN(InputMethodBridge);
+};
+
+#endif  // CHROME_BROWSER_UI_VIEWS_IME_DRIVER_INPUT_METHOD_BRIDGE_CHROMEOS_H_
diff --git a/chrome/browser/ui/views/ime_driver/input_method_bridge_chromeos_unittest.cc b/chrome/browser/ui/views/ime_driver/input_method_bridge_chromeos_unittest.cc
new file mode 100644
index 0000000..9d7cc668
--- /dev/null
+++ b/chrome/browser/ui/views/ime_driver/input_method_bridge_chromeos_unittest.cc
@@ -0,0 +1,200 @@
+// 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 <stdint.h>
+
+#include "base/bind.h"
+#include "base/macros.h"
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
+#include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/ui/views/ime_driver/input_method_bridge_chromeos.h"
+#include "content/public/test/test_browser_thread_bundle.h"
+#include "mojo/public/cpp/bindings/binding.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/base/ime/ime_bridge.h"
+#include "ui/events/event.h"
+#include "ui/events/event_constants.h"
+#include "ui/events/event_utils.h"
+#include "ui/events/keycodes/dom/dom_code.h"
+#include "ui/events/keycodes/dom/dom_key.h"
+#include "ui/events/keycodes/keyboard_code_conversion.h"
+#include "ui/events/keycodes/keyboard_codes.h"
+
+enum class CompositionEventType {
+  SET,
+  CONFIRM,
+  CLEAR,
+  INSERT_TEXT,
+  INSERT_CHAR
+};
+
+struct CompositionEvent {
+  CompositionEventType type;
+  base::string16 text_data;
+  base::char16 char_data;
+};
+
+class TestTextInputClient : public ui::mojom::TextInputClient {
+ public:
+  explicit TestTextInputClient(ui::mojom::TextInputClientRequest request)
+      : binding_(this, std::move(request)) {}
+
+  CompositionEvent WaitUntilCompositionEvent() {
+    if (!receieved_event_.has_value()) {
+      run_loop_ = base::MakeUnique<base::RunLoop>();
+      run_loop_->Run();
+      run_loop_.reset();
+    }
+    CompositionEvent result = receieved_event_.value();
+    receieved_event_.reset();
+    return result;
+  }
+
+ private:
+  void SetCompositionText(const ui::CompositionText& composition) override {
+    CompositionEvent ev = {CompositionEventType::SET, composition.text, 0};
+    receieved_event_ = ev;
+    if (run_loop_)
+      run_loop_->Quit();
+  }
+  void ConfirmCompositionText() override {
+    CompositionEvent ev = {CompositionEventType::CONFIRM, base::string16(), 0};
+    receieved_event_ = ev;
+    if (run_loop_)
+      run_loop_->Quit();
+  }
+  void ClearCompositionText() override {
+    CompositionEvent ev = {CompositionEventType::CLEAR, base::string16(), 0};
+    receieved_event_ = ev;
+    if (run_loop_)
+      run_loop_->Quit();
+  }
+  void InsertText(const std::string& text) override {
+    CompositionEvent ev = {CompositionEventType::INSERT_TEXT,
+                           base::UTF8ToUTF16(text), 0};
+    receieved_event_ = ev;
+    if (run_loop_)
+      run_loop_->Quit();
+  }
+  void InsertChar(std::unique_ptr<ui::Event> event) override {
+    ASSERT_TRUE(event->IsKeyEvent());
+    CompositionEvent ev = {CompositionEventType::INSERT_CHAR, base::string16(),
+                           event->AsKeyEvent()->GetCharacter()};
+    receieved_event_ = ev;
+    if (run_loop_)
+      run_loop_->Quit();
+  }
+
+  mojo::Binding<ui::mojom::TextInputClient> binding_;
+  std::unique_ptr<base::RunLoop> run_loop_;
+  base::Optional<CompositionEvent> receieved_event_;
+
+  DISALLOW_COPY_AND_ASSIGN(TestTextInputClient);
+};
+
+class InputMethodBridgeChromeOSTest : public testing::Test {
+ public:
+  InputMethodBridgeChromeOSTest()
+      : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) {}
+  ~InputMethodBridgeChromeOSTest() override {}
+
+  void SetUp() override {
+    ui::IMEBridge::Initialize();
+
+    ui::mojom::TextInputClientPtr client_ptr;
+    client_ = base::MakeUnique<TestTextInputClient>(GetProxy(&client_ptr));
+    input_method_ = base::MakeUnique<InputMethodBridge>(std::move(client_ptr));
+  }
+
+  bool ProcessKeyEvent(std::unique_ptr<ui::Event> event) {
+    handled_.reset();
+
+    input_method_->ProcessKeyEvent(
+        std::move(event),
+        base::Bind(&InputMethodBridgeChromeOSTest::ProcessKeyEventCallback,
+                   base::Unretained(this)));
+
+    if (!handled_.has_value()) {
+      run_loop_ = base::MakeUnique<base::RunLoop>();
+      run_loop_->Run();
+      run_loop_.reset();
+    }
+
+    return handled_.value();
+  }
+
+  std::unique_ptr<ui::Event> UnicodeKeyPress(ui::KeyboardCode vkey,
+                                             ui::DomCode code,
+                                             int flags,
+                                             base::char16 character) const {
+    return base::MakeUnique<ui::KeyEvent>(ui::ET_KEY_PRESSED, vkey, code, flags,
+                                          ui::DomKey::FromCharacter(character),
+                                          ui::EventTimeForNow());
+  }
+
+ protected:
+  void ProcessKeyEventCallback(bool handled) {
+    handled_ = handled;
+    if (run_loop_)
+      run_loop_->Quit();
+  }
+
+  content::TestBrowserThreadBundle thread_bundle_;
+  std::unique_ptr<TestTextInputClient> client_;
+  std::unique_ptr<InputMethodBridge> input_method_;
+  std::unique_ptr<base::RunLoop> run_loop_;
+  base::Optional<bool> handled_;
+
+  DISALLOW_COPY_AND_ASSIGN(InputMethodBridgeChromeOSTest);
+};
+
+// Tests if hexadecimal composition provided by ui::CharacterComposer works
+// correctly. ui::CharacterComposer is tried if no input method extensions
+// have been registered yet.
+TEST_F(InputMethodBridgeChromeOSTest, HexadecimalComposition) {
+  struct {
+    ui::KeyboardCode vkey;
+    ui::DomCode code;
+    int flags;
+    base::char16 character;
+    std::string composition_text;
+  } kTestSequence[] = {
+      {ui::VKEY_U, ui::DomCode::US_U, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN,
+       'U', "u"},
+      {ui::VKEY_3, ui::DomCode::DIGIT3, 0, '3', "u3"},
+      {ui::VKEY_0, ui::DomCode::DIGIT0, 0, '0', "u30"},
+      {ui::VKEY_4, ui::DomCode::DIGIT4, 0, '4', "u304"},
+      {ui::VKEY_2, ui::DomCode::DIGIT2, 0, '2', "u3042"},
+  };
+
+  // Send the Ctrl-Shift-U,3,4,0,2 sequence.
+  for (size_t i = 0; i < arraysize(kTestSequence); i++) {
+    EXPECT_TRUE(ProcessKeyEvent(
+        UnicodeKeyPress(kTestSequence[i].vkey, kTestSequence[i].code,
+                        kTestSequence[i].flags, kTestSequence[i].character)));
+    CompositionEvent ev = client_->WaitUntilCompositionEvent();
+    EXPECT_EQ(CompositionEventType::SET, ev.type);
+    EXPECT_EQ(base::UTF8ToUTF16(kTestSequence[i].composition_text),
+              ev.text_data);
+  }
+
+  // Press the return key and verify that the composition text was converted
+  // to the desired text.
+  EXPECT_TRUE(ProcessKeyEvent(
+      UnicodeKeyPress(ui::VKEY_RETURN, ui::DomCode::ENTER, 0, '\r')));
+  CompositionEvent ev = client_->WaitUntilCompositionEvent();
+  EXPECT_EQ(CompositionEventType::INSERT_TEXT, ev.type);
+  EXPECT_EQ(base::string16(1, 0x3042), ev.text_data);
+}
+
+// Test that Ctrl-C, Ctrl-X, and Ctrl-V are not handled.
+TEST_F(InputMethodBridgeChromeOSTest, ClipboardAccelerators) {
+  EXPECT_FALSE(ProcessKeyEvent(UnicodeKeyPress(ui::VKEY_C, ui::DomCode::US_C,
+                                               ui::EF_CONTROL_DOWN, 'C')));
+  EXPECT_FALSE(ProcessKeyEvent(UnicodeKeyPress(ui::VKEY_X, ui::DomCode::US_X,
+                                               ui::EF_CONTROL_DOWN, 'X')));
+  EXPECT_FALSE(ProcessKeyEvent(UnicodeKeyPress(ui::VKEY_V, ui::DomCode::US_V,
+                                               ui::EF_CONTROL_DOWN, 'V')));
+}
diff --git a/chrome/browser/ui/views/ime_driver/remote_text_input_client.cc b/chrome/browser/ui/views/ime_driver/remote_text_input_client.cc
new file mode 100644
index 0000000..b7705ad0
--- /dev/null
+++ b/chrome/browser/ui/views/ime_driver/remote_text_input_client.cc
@@ -0,0 +1,163 @@
+// 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.
+
+// Reduce number of log messages by logging each NOTIMPLEMENTED() only once.
+// This has to be before any other includes, else default is picked up.
+// See base/logging.h for details on this.
+#define NOTIMPLEMENTED_POLICY 5
+
+#include "chrome/browser/ui/views/ime_driver/remote_text_input_client.h"
+
+#include "base/strings/utf_string_conversions.h"
+
+RemoteTextInputClient::RemoteTextInputClient(
+    ui::mojom::TextInputClientPtr remote_client)
+    : remote_client_(std::move(remote_client)) {}
+
+RemoteTextInputClient::~RemoteTextInputClient() {}
+
+void RemoteTextInputClient::SetCompositionText(
+    const ui::CompositionText& composition) {
+  remote_client_->SetCompositionText(composition);
+}
+
+void RemoteTextInputClient::ConfirmCompositionText() {
+  remote_client_->ConfirmCompositionText();
+}
+
+void RemoteTextInputClient::ClearCompositionText() {
+  remote_client_->ClearCompositionText();
+}
+
+void RemoteTextInputClient::InsertText(const base::string16& text) {
+  remote_client_->InsertText(base::UTF16ToUTF8(text));
+}
+
+void RemoteTextInputClient::InsertChar(const ui::KeyEvent& event) {
+  remote_client_->InsertChar(ui::Event::Clone(event));
+}
+
+ui::TextInputType RemoteTextInputClient::GetTextInputType() const {
+  // TODO(moshayedi): crbug.com/631527.
+  NOTIMPLEMENTED();
+  return ui::TEXT_INPUT_TYPE_TEXT;
+}
+
+ui::TextInputMode RemoteTextInputClient::GetTextInputMode() const {
+  // TODO(moshayedi): crbug.com/631527.
+  NOTIMPLEMENTED();
+  return ui::TEXT_INPUT_MODE_DEFAULT;
+}
+
+base::i18n::TextDirection RemoteTextInputClient::GetTextDirection() const {
+  // TODO(moshayedi): crbug.com/631527.
+  NOTIMPLEMENTED();
+  return base::i18n::UNKNOWN_DIRECTION;
+}
+
+int RemoteTextInputClient::GetTextInputFlags() const {
+  // TODO(moshayedi): crbug.com/631527.
+  NOTIMPLEMENTED();
+  return 0;
+}
+
+bool RemoteTextInputClient::CanComposeInline() const {
+  // If we return false here, ui::InputMethodChromeOS will try to create a
+  // composition window. But here we are at IMEDriver, and composition
+  // window shouldn't be created by IMEDriver.
+  return true;
+}
+
+gfx::Rect RemoteTextInputClient::GetCaretBounds() const {
+  // TODO(moshayedi): crbug.com/631527.
+  NOTIMPLEMENTED();
+  return gfx::Rect();
+}
+
+bool RemoteTextInputClient::GetCompositionCharacterBounds(
+    uint32_t index,
+    gfx::Rect* rect) const {
+  // TODO(moshayedi): crbug.com/631527.
+  NOTIMPLEMENTED();
+  return false;
+}
+
+bool RemoteTextInputClient::HasCompositionText() const {
+  // TODO(moshayedi): crbug.com/631527.
+  NOTIMPLEMENTED();
+  return false;
+}
+
+bool RemoteTextInputClient::GetTextRange(gfx::Range* range) const {
+  // TODO(moshayedi): crbug.com/631527.
+  NOTIMPLEMENTED();
+  return false;
+}
+
+bool RemoteTextInputClient::GetCompositionTextRange(gfx::Range* range) const {
+  // TODO(moshayedi): crbug.com/631527.
+  NOTIMPLEMENTED();
+  return false;
+}
+
+bool RemoteTextInputClient::GetSelectionRange(gfx::Range* range) const {
+  // TODO(moshayedi): crbug.com/631527.
+  NOTIMPLEMENTED();
+  return false;
+}
+
+bool RemoteTextInputClient::SetSelectionRange(const gfx::Range& range) {
+  // TODO(moshayedi): crbug.com/631527.
+  NOTIMPLEMENTED();
+  return false;
+}
+
+bool RemoteTextInputClient::DeleteRange(const gfx::Range& range) {
+  // TODO(moshayedi): crbug.com/631527.
+  NOTIMPLEMENTED();
+  return false;
+}
+
+bool RemoteTextInputClient::GetTextFromRange(const gfx::Range& range,
+                                             base::string16* text) const {
+  // TODO(moshayedi): crbug.com/631527.
+  NOTIMPLEMENTED();
+  return false;
+}
+
+void RemoteTextInputClient::OnInputMethodChanged() {
+  // TODO(moshayedi): crbug.com/631527.
+  NOTIMPLEMENTED();
+}
+
+bool RemoteTextInputClient::ChangeTextDirectionAndLayoutAlignment(
+    base::i18n::TextDirection direction) {
+  // TODO(moshayedi): crbug.com/631527.
+  NOTIMPLEMENTED();
+  return false;
+}
+
+void RemoteTextInputClient::ExtendSelectionAndDelete(size_t before,
+                                                     size_t after) {
+  // TODO(moshayedi): crbug.com/631527.
+  NOTIMPLEMENTED();
+}
+
+void RemoteTextInputClient::EnsureCaretNotInRect(const gfx::Rect& rect) {
+  // TODO(moshayedi): crbug.com/631527.
+  NOTIMPLEMENTED();
+}
+
+bool RemoteTextInputClient::IsTextEditCommandEnabled(
+    ui::TextEditCommand command) const {
+  // TODO(moshayedi): crbug.com/631527.
+  NOTIMPLEMENTED();
+  return false;
+}
+
+void RemoteTextInputClient::SetTextEditCommandForNextKeyEvent(
+    ui::TextEditCommand command) {
+  // TODO(moshayedi): crbug.com/631527.
+  NOTIMPLEMENTED();
+}
diff --git a/chrome/browser/ui/views/ime_driver/remote_text_input_client.h b/chrome/browser/ui/views/ime_driver/remote_text_input_client.h
new file mode 100644
index 0000000..056be5f1
--- /dev/null
+++ b/chrome/browser/ui/views/ime_driver/remote_text_input_client.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 CHROME_BROWSER_UI_VIEWS_IME_DRIVER_REMOTE_TEXT_INPUT_CLIENT_H_
+#define CHROME_BROWSER_UI_VIEWS_IME_DRIVER_REMOTE_TEXT_INPUT_CLIENT_H_
+
+#include "services/ui/public/interfaces/ime/ime.mojom.h"
+#include "ui/base/ime/text_input_client.h"
+
+// This implementation of ui::TextInputClient sends all updates via mojo IPC to
+// a remote client. This is intended to be passed to the overrides of
+// ui::InputMethod::SetFocusedTextInputClient().
+class RemoteTextInputClient : public ui::TextInputClient {
+ public:
+  explicit RemoteTextInputClient(ui::mojom::TextInputClientPtr remote_client);
+  ~RemoteTextInputClient() override;
+
+ private:
+  // ui::TextInputClient:
+  void SetCompositionText(const ui::CompositionText& composition) override;
+  void ConfirmCompositionText() override;
+  void ClearCompositionText() override;
+  void InsertText(const base::string16& text) override;
+  void InsertChar(const ui::KeyEvent& event) override;
+  ui::TextInputType GetTextInputType() const override;
+  ui::TextInputMode GetTextInputMode() const override;
+  base::i18n::TextDirection GetTextDirection() const override;
+  int GetTextInputFlags() const override;
+  bool CanComposeInline() const override;
+  gfx::Rect GetCaretBounds() const override;
+  bool GetCompositionCharacterBounds(uint32_t index,
+                                     gfx::Rect* rect) const override;
+  bool HasCompositionText() const override;
+  bool GetTextRange(gfx::Range* range) const override;
+  bool GetCompositionTextRange(gfx::Range* range) const override;
+  bool GetSelectionRange(gfx::Range* range) const override;
+  bool SetSelectionRange(const gfx::Range& range) override;
+  bool DeleteRange(const gfx::Range& range) override;
+  bool GetTextFromRange(const gfx::Range& range,
+                        base::string16* text) const override;
+  void OnInputMethodChanged() override;
+  bool ChangeTextDirectionAndLayoutAlignment(
+      base::i18n::TextDirection direction) override;
+  void ExtendSelectionAndDelete(size_t before, size_t after) override;
+  void EnsureCaretNotInRect(const gfx::Rect& rect) override;
+  bool IsTextEditCommandEnabled(ui::TextEditCommand command) const override;
+  void SetTextEditCommandForNextKeyEvent(ui::TextEditCommand command) override;
+
+  ui::mojom::TextInputClientPtr remote_client_;
+
+  DISALLOW_COPY_AND_ASSIGN(RemoteTextInputClient);
+};
+
+#endif  // CHROME_BROWSER_UI_VIEWS_IME_DRIVER_REMOTE_TEXT_INPUT_CLIENT_H_
diff --git a/chrome/browser/ui/views/ime_driver/simple_input_method.cc b/chrome/browser/ui/views/ime_driver/simple_input_method.cc
new file mode 100644
index 0000000..e040d2c
--- /dev/null
+++ b/chrome/browser/ui/views/ime_driver/simple_input_method.cc
@@ -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.
+
+#include "chrome/browser/ui/views/ime_driver/simple_input_method.h"
+
+SimpleInputMethod::SimpleInputMethod() {}
+
+SimpleInputMethod::~SimpleInputMethod() {}
+
+void SimpleInputMethod::OnTextInputModeChanged(
+    ui::mojom::TextInputMode text_input_mode) {}
+
+void SimpleInputMethod::OnTextInputTypeChanged(
+    ui::mojom::TextInputType text_input_type) {}
+
+void SimpleInputMethod::OnCaretBoundsChanged(const gfx::Rect& caret_bounds) {}
+
+void SimpleInputMethod::ProcessKeyEvent(
+    std::unique_ptr<ui::Event> key_event,
+    const ProcessKeyEventCallback& callback) {
+  callback.Run(false);
+}
+
+void SimpleInputMethod::CancelComposition() {}
diff --git a/chrome/browser/ui/views/ime_driver/simple_input_method.h b/chrome/browser/ui/views/ime_driver/simple_input_method.h
new file mode 100644
index 0000000..c488cce
--- /dev/null
+++ b/chrome/browser/ui/views/ime_driver/simple_input_method.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 CHROME_BROWSER_UI_VIEWS_IME_DRIVER_SIMPLE_INPUT_METHOD_H_
+#define CHROME_BROWSER_UI_VIEWS_IME_DRIVER_SIMPLE_INPUT_METHOD_H_
+
+#include "services/ui/public/interfaces/ime/ime.mojom.h"
+
+// This is to be used on platforms where a proper implementation of
+// ui::mojom::InputMethod is missing. It doesn't handle any events and calls
+// the callback with false, which will result in client code handling events
+// locally.
+class SimpleInputMethod : public ui::mojom::InputMethod {
+ public:
+  SimpleInputMethod();
+  ~SimpleInputMethod() override;
+
+  // ui::mojom::InputMethod:
+  void OnTextInputModeChanged(
+      ui::mojom::TextInputMode text_input_mode) override;
+  void OnTextInputTypeChanged(
+      ui::mojom::TextInputType text_input_type) override;
+  void OnCaretBoundsChanged(const gfx::Rect& caret_bounds) override;
+  void ProcessKeyEvent(std::unique_ptr<ui::Event> key_event,
+                       const ProcessKeyEventCallback& callback) override;
+  void CancelComposition() override;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(SimpleInputMethod);
+};
+
+#endif  // CHROME_BROWSER_UI_VIEWS_IME_DRIVER_SIMPLE_INPUT_METHOD_H_
diff --git a/chrome/browser/ui/views/ime_driver_mus.cc b/chrome/browser/ui/views/ime_driver_mus.cc
deleted file mode 100644
index 2b618861..0000000
--- a/chrome/browser/ui/views/ime_driver_mus.cc
+++ /dev/null
@@ -1,77 +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 "chrome/browser/ui/views/ime_driver_mus.h"
-
-#include "content/public/browser/browser_thread.h"
-#include "content/public/common/service_manager_connection.h"
-#include "mojo/public/cpp/bindings/strong_binding.h"
-#include "services/service_manager/public/cpp/connector.h"
-#include "services/ui/public/interfaces/constants.mojom.h"
-#include "services/ui/public/interfaces/ime/ime.mojom.h"
-
-namespace {
-
-class InputMethod : public ui::mojom::InputMethod {
- public:
-  explicit InputMethod(ui::mojom::TextInputClientPtr client)
-      : client_(std::move(client)) {}
-  ~InputMethod() override {}
-
- private:
-  // ui::mojom::InputMethod:
-  void OnTextInputModeChanged(
-      ui::mojom::TextInputMode text_input_mode) override {}
-  void OnTextInputTypeChanged(
-      ui::mojom::TextInputType text_input_type) override {}
-  void OnCaretBoundsChanged(const gfx::Rect& caret_bounds) override {}
-  void ProcessKeyEvent(std::unique_ptr<ui::Event> key_event,
-                       const ProcessKeyEventCallback& callback) override {
-    DCHECK(key_event->IsKeyEvent());
-
-    if (key_event->AsKeyEvent()->is_char()) {
-      client_->InsertChar(std::move(key_event));
-      callback.Run(true);
-    } else {
-      callback.Run(false);
-    }
-  }
-  void CancelComposition() override {}
-
-  ui::mojom::TextInputClientPtr client_;
-
-  DISALLOW_COPY_AND_ASSIGN(InputMethod);
-};
-
-}  // namespace
-
-IMEDriver::~IMEDriver() {}
-
-// static
-void IMEDriver::Register() {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  ui::mojom::IMEDriverPtr ime_driver_ptr;
-  mojo::MakeStrongBinding(base::WrapUnique(new IMEDriver),
-                          GetProxy(&ime_driver_ptr));
-  ui::mojom::IMERegistrarPtr ime_registrar;
-  content::ServiceManagerConnection::GetForProcess()
-      ->GetConnector()
-      ->ConnectToInterface(ui::mojom::kServiceName, &ime_registrar);
-  ime_registrar->RegisterDriver(std::move(ime_driver_ptr));
-}
-
-void IMEDriver::StartSession(
-    int32_t session_id,
-    ui::mojom::TextInputClientPtr client,
-    ui::mojom::InputMethodRequest input_method_request) {
-  input_method_bindings_[session_id] =
-      base::MakeUnique<mojo::Binding<ui::mojom::InputMethod>>(
-          new InputMethod(std::move(client)), std::move(input_method_request));
-}
-
-IMEDriver::IMEDriver() {}
-
-void IMEDriver::CancelSession(int32_t session_id) {
-  input_method_bindings_.erase(session_id);
-}
diff --git a/chrome/browser/ui/views/location_bar/background_with_1_px_border.cc b/chrome/browser/ui/views/location_bar/background_with_1_px_border.cc
index d489a3b..82f5226 100644
--- a/chrome/browser/ui/views/location_bar/background_with_1_px_border.cc
+++ b/chrome/browser/ui/views/location_bar/background_with_1_px_border.cc
@@ -4,7 +4,6 @@
 
 #include "chrome/browser/ui/views/location_bar/background_with_1_px_border.h"
 
-#include "chrome/browser/ui/layout_constants.h"
 #include "third_party/skia/include/core/SkPaint.h"
 #include "third_party/skia/include/core/SkPath.h"
 #include "third_party/skia/include/pathops/SkPathOps.h"
@@ -27,14 +26,13 @@
   const float scale = canvas->UndoDeviceScaleFactor();
   border_rect_f.Scale(scale);
   // Draw the border as a 1px thick line aligned with the inside edge of the
-  // LOCATION_BAR_BORDER_THICKNESS region. This line needs to be snapped to the
+  // kLocationBarBorderThicknessDip region. This line needs to be snapped to the
   // pixel grid, so the result of the scale-up needs to be snapped to an integer
   // value. Using floor() instead of round() ensures that, for non-integral
   // scale factors, the border will still be drawn inside the BORDER_THICKNESS
   // region instead of being partially inside it.
-  border_rect_f.Inset(gfx::InsetsF(
-      std::floor(GetLayoutConstant(LOCATION_BAR_BORDER_THICKNESS) * scale) -
-      0.5f));
+  border_rect_f.Inset(
+      gfx::InsetsF(std::floor(kLocationBarBorderThicknessDip * scale) - 0.5f));
 
   SkPath path;
   const SkScalar scaled_corner_radius =
diff --git a/chrome/browser/ui/views/location_bar/background_with_1_px_border.h b/chrome/browser/ui/views/location_bar/background_with_1_px_border.h
index 6904579..1512527 100644
--- a/chrome/browser/ui/views/location_bar/background_with_1_px_border.h
+++ b/chrome/browser/ui/views/location_bar/background_with_1_px_border.h
@@ -25,6 +25,9 @@
   // Corner radius of the inside edge of the roundrect border stroke.
   static constexpr int kCornerRadius = 2;
 
+  // The thickness of the location bar's border in DIP.
+  static constexpr int kLocationBarBorderThicknessDip = 1;
+
   BackgroundWith1PxBorder(SkColor background, SkColor border);
 
   void Paint(gfx::Canvas* canvas, views::View* view) const override;
diff --git a/chrome/browser/ui/views/location_bar/content_setting_image_view.cc b/chrome/browser/ui/views/location_bar/content_setting_image_view.cc
index 3b5f6cb..c914e2cd 100644
--- a/chrome/browser/ui/views/location_bar/content_setting_image_view.cc
+++ b/chrome/browser/ui/views/location_bar/content_setting_image_view.cc
@@ -8,7 +8,6 @@
 #include "chrome/browser/themes/theme_properties.h"
 #include "chrome/browser/ui/content_settings/content_setting_bubble_model.h"
 #include "chrome/browser/ui/content_settings/content_setting_image_model.h"
-#include "chrome/browser/ui/layout_constants.h"
 #include "chrome/browser/ui/views/content_setting_bubble_contents.h"
 #include "chrome/browser/ui/views/location_bar/location_bar_view.h"
 #include "chrome/grit/theme_resources.h"
@@ -163,9 +162,8 @@
 
 bool ContentSettingImageView::ShouldShowLabel() const {
   return (!IsShrinking() ||
-          (width() >
-           (image()->GetPreferredSize().width() +
-            2 * GetLayoutConstant(LOCATION_BAR_HORIZONTAL_PADDING)))) &&
+          (width() > (image()->GetPreferredSize().width() +
+                      2 * LocationBarView::kHorizontalPadding))) &&
          (slide_animator_.is_animating() || pause_animation_);
 }
 
diff --git a/chrome/browser/ui/views/location_bar/icon_label_bubble_view.cc b/chrome/browser/ui/views/location_bar/icon_label_bubble_view.cc
index 65804a0..9d1ff7d 100644
--- a/chrome/browser/ui/views/location_bar/icon_label_bubble_view.cc
+++ b/chrome/browser/ui/views/location_bar/icon_label_bubble_view.cc
@@ -4,7 +4,7 @@
 
 #include "chrome/browser/ui/views/location_bar/icon_label_bubble_view.h"
 
-#include "chrome/browser/ui/layout_constants.h"
+#include "chrome/browser/ui/views/location_bar/location_bar_view.h"
 #include "ui/accessibility/ax_node_data.h"
 #include "ui/gfx/canvas.h"
 #include "ui/gfx/color_utils.h"
@@ -42,7 +42,7 @@
   // the bubble should be smaller, so use an empty border to shrink down the
   // content bounds so the background gets painted correctly.
   SetBorder(views::CreateEmptyBorder(
-      gfx::Insets(GetLayoutConstant(LOCATION_BAR_BUBBLE_VERTICAL_PADDING), 0)));
+      gfx::Insets(LocationBarView::kBubbleVerticalPadding, 0)));
 
   // Flip the canvas in RTL so the separator is drawn on the correct side.
   EnableCanvasFlippingForRTLUI(true);
@@ -94,7 +94,7 @@
 
 void IconLabelBubbleView::Layout() {
   // Compute the image bounds. Leading and trailing padding are the same.
-  int image_x = GetLayoutConstant(LOCATION_BAR_HORIZONTAL_PADDING);
+  int image_x = LocationBarView::kHorizontalPadding;
   int bubble_trailing_padding = image_x;
 
   // If ShouldShowLabel() is true, then either we show a label in the
@@ -192,7 +192,7 @@
     // enough to show the icon. We don't want to shrink all the way back to
     // zero, since this would mean the view would completely disappear and then
     // pop back to an icon after the animation finishes.
-    const int max_width = GetLayoutConstant(LOCATION_BAR_HORIZONTAL_PADDING) +
+    const int max_width = LocationBarView::kHorizontalPadding +
                           image_->GetPreferredSize().width() +
                           GetInternalSpacing() + label_width + post_label_width;
     const int current_width = WidthMultiplier() * max_width;
@@ -205,13 +205,12 @@
 int IconLabelBubbleView::GetInternalSpacing() const {
   return image_->GetPreferredSize().IsEmpty()
              ? 0
-             : GetLayoutConstant(LOCATION_BAR_HORIZONTAL_PADDING);
+             : LocationBarView::kHorizontalPadding;
 }
 
 int IconLabelBubbleView::GetPostSeparatorPadding() const {
-  // The location bar will add LOCATION_BAR_HORIZONTAL_PADDING after us.
-  return kSpaceBesideSeparator -
-         GetLayoutConstant(LOCATION_BAR_HORIZONTAL_PADDING);
+  // The location bar will add LocationBarView::kHorizontalPadding after us.
+  return kSpaceBesideSeparator - LocationBarView::kHorizontalPadding;
 }
 
 float IconLabelBubbleView::GetScaleFactor() const {
diff --git a/chrome/browser/ui/views/location_bar/icon_label_bubble_view_unittest.cc b/chrome/browser/ui/views/location_bar/icon_label_bubble_view_unittest.cc
index 74e0664..28f3efe 100644
--- a/chrome/browser/ui/views/location_bar/icon_label_bubble_view_unittest.cc
+++ b/chrome/browser/ui/views/location_bar/icon_label_bubble_view_unittest.cc
@@ -5,7 +5,7 @@
 #include "chrome/browser/ui/views/location_bar/icon_label_bubble_view.h"
 
 #include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/ui/layout_constants.h"
+#include "chrome/browser/ui/views/location_bar/location_bar_view.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/views/controls/image_view.h"
 #include "ui/views/test/views_test_base.h"
@@ -65,7 +65,7 @@
   bool ShouldShowLabel() const override {
     return !IsShrinking() ||
            (width() > (image()->GetPreferredSize().width() +
-                       2 * GetLayoutConstant(LOCATION_BAR_HORIZONTAL_PADDING)));
+                       2 * LocationBarView::kHorizontalPadding));
   }
 
   double WidthMultiplier() const override {
diff --git a/chrome/browser/ui/views/location_bar/keyword_hint_view.cc b/chrome/browser/ui/views/location_bar/keyword_hint_view.cc
index 0256f91..5f7c0bc 100644
--- a/chrome/browser/ui/views/location_bar/keyword_hint_view.cc
+++ b/chrome/browser/ui/views/location_bar/keyword_hint_view.cc
@@ -11,8 +11,8 @@
 #include "base/macros.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/search_engines/template_url_service_factory.h"
-#include "chrome/browser/ui/layout_constants.h"
 #include "chrome/browser/ui/views/location_bar/background_with_1_px_border.h"
+#include "chrome/browser/ui/views/location_bar/location_bar_view.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/search_engines/template_url_service.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -39,7 +39,7 @@
 TabKeyBubbleView::TabKeyBubbleView(const gfx::FontList& font_list)
     : views::Label(l10n_util::GetStringUTF16(IDS_APP_TAB_KEY), font_list) {
   SetBorder(views::CreateEmptyBorder(
-      gfx::Insets(GetLayoutConstant(LOCATION_BAR_BUBBLE_VERTICAL_PADDING), 0)));
+      gfx::Insets(LocationBarView::kBubbleVerticalPadding, 0)));
 }
 
 TabKeyBubbleView::~TabKeyBubbleView() {}
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.cc b/chrome/browser/ui/views/location_bar/location_bar_view.cc
index 76c548b..fcd840cb 100644
--- a/chrome/browser/ui/views/location_bar/location_bar_view.cc
+++ b/chrome/browser/ui/views/location_bar/location_bar_view.cc
@@ -220,10 +220,10 @@
   gfx::FontList font_list = ResourceBundle::GetSharedInstance().GetFontList(
       ResourceBundle::BaseFont);
   const int current_font_size = font_list.GetFontSize();
-  const int desired_font_size = GetLayoutConstant(OMNIBOX_FONT_PIXEL_SIZE);
-  if (current_font_size != desired_font_size) {
+  constexpr int kDesiredFontSize = 14;
+  if (current_font_size != kDesiredFontSize) {
     font_list =
-        font_list.DeriveWithSizeDelta(desired_font_size - current_font_size);
+        font_list.DeriveWithSizeDelta(kDesiredFontSize - current_font_size);
   }
   // Shrink large fonts to make them fit.
   // TODO(pkasting): Stretch the location bar instead in this case.
@@ -234,7 +234,7 @@
 
   // Determine the font for use inside the bubbles.
   const int bubble_padding =
-      GetLayoutConstant(LOCATION_BAR_BUBBLE_VERTICAL_PADDING) +
+      kBubbleVerticalPadding +
       GetLayoutConstant(LOCATION_BAR_BUBBLE_FONT_VERTICAL_PADDING);
   const int bubble_height = location_height - (bubble_padding * 2);
 
@@ -490,8 +490,6 @@
 
   min_size.set_height(min_size.height() * size_animation_.GetCurrentValue());
 
-  const int padding = GetLayoutConstant(LOCATION_BAR_HORIZONTAL_PADDING);
-
   // Compute width of omnibox-leading content.
   const int edge_thickness = GetHorizontalEdgeThickness();
   int leading_width = edge_thickness;
@@ -502,7 +500,8 @@
     leading_width +=
         location_icon_view_->GetMinimumSizeForLabelText(security_text).width();
   } else {
-    leading_width += padding + location_icon_view_->GetMinimumSize().width();
+    leading_width +=
+        kHorizontalPadding + location_icon_view_->GetMinimumSize().width();
   }
 
   // Compute width of omnibox-trailing content.
@@ -521,8 +520,8 @@
   }
 
   min_size.set_width(leading_width + omnibox_view_->GetMinimumSize().width() +
-                     2 * padding - omnibox_view_->GetInsets().width() +
-                     trailing_width);
+                     2 * kHorizontalPadding -
+                     omnibox_view_->GetInsets().width() + trailing_width);
   return min_size;
 }
 
@@ -534,8 +533,7 @@
   location_icon_view_->SetVisible(false);
   keyword_hint_view_->SetVisible(false);
 
-  const int item_padding = GetLayoutConstant(LOCATION_BAR_HORIZONTAL_PADDING);
-  const int edge_thickness = GetHorizontalEdgeThickness();
+  constexpr int item_padding = kHorizontalPadding;
 
   LocationBarLayout leading_decorations(
       LocationBarLayout::LEFT_EDGE, item_padding,
@@ -633,6 +631,8 @@
       keyword_hint_view_->SetKeyword(keyword);
   }
 
+  const int edge_thickness = GetHorizontalEdgeThickness();
+
   // Perform layout.
   int full_width = width() - (2 * edge_thickness);
 
@@ -728,18 +728,20 @@
 // LocationBarView, private:
 
 int LocationBarView::IncrementalMinimumWidth(views::View* view) const {
-  return view->visible() ?
-      (GetLayoutConstant(LOCATION_BAR_HORIZONTAL_PADDING) +
-          view->GetMinimumSize().width()) : 0;
+  return view->visible() ? (kHorizontalPadding + view->GetMinimumSize().width())
+                         : 0;
 }
 
 int LocationBarView::GetHorizontalEdgeThickness() const {
-  return is_popup_mode_ ? 0 : GetLayoutConstant(LOCATION_BAR_BORDER_THICKNESS);
+  return is_popup_mode_
+             ? 0
+             : BackgroundWith1PxBorder::kLocationBarBorderThicknessDip;
 }
 
 int LocationBarView::GetTotalVerticalPadding() const {
-  return GetLayoutConstant(LOCATION_BAR_BORDER_THICKNESS) +
-         GetLayoutConstant(LOCATION_BAR_VERTICAL_PADDING);
+  constexpr int kInteriorPadding = 1;
+  return BackgroundWith1PxBorder::kLocationBarBorderThicknessDip +
+         kInteriorPadding;
 }
 
 void LocationBarView::RefreshLocationIcon() {
@@ -1182,9 +1184,10 @@
   // border images are meant to rest atop the toolbar background and parts atop
   // the omnibox background, so we can't just blindly fill our entire bounds.
   gfx::Rect bounds(GetContentsBounds());
-  bounds.Inset(
-      GetHorizontalEdgeThickness(),
-      is_popup_mode_ ? 0 : GetLayoutConstant(LOCATION_BAR_BORDER_THICKNESS));
+  bounds.Inset(GetHorizontalEdgeThickness(),
+               is_popup_mode_
+                   ? 0
+                   : BackgroundWith1PxBorder::kLocationBarBorderThicknessDip);
   SkColor background_color(GetColor(BACKGROUND));
   canvas->FillRect(bounds, background_color);
   const SkColor border_color = GetBorderColor(profile()->IsOffTheRecord());
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.h b/chrome/browser/ui/views/location_bar/location_bar_view.h
index 6ef1642..82fb098 100644
--- a/chrome/browser/ui/views/location_bar/location_bar_view.h
+++ b/chrome/browser/ui/views/location_bar/location_bar_view.h
@@ -111,6 +111,13 @@
   // Width (and height) of icons in location bar.
   static constexpr int kIconWidth = 16;
 
+  // Space between items in the location bar, as well as between items and the
+  // edges.
+  static constexpr int kHorizontalPadding = 6;
+
+  // The additional vertical padding of a bubble.
+  static constexpr int kBubbleVerticalPadding = 3;
+
   // The location bar view's class name.
   static const char kViewClassName[];
 
diff --git a/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.cc b/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.cc
index d6d3055..8d41cdd 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.cc
@@ -11,7 +11,6 @@
 #include "build/build_config.h"
 #include "chrome/browser/search/search.h"
 #include "chrome/browser/themes/theme_properties.h"
-#include "chrome/browser/ui/layout_constants.h"
 #include "chrome/browser/ui/views/location_bar/location_bar_view.h"
 #include "chrome/browser/ui/views/omnibox/omnibox_result_view.h"
 #include "chrome/browser/ui/views/theme_copying_widget.h"
diff --git a/chrome/browser/ui/views/omnibox/omnibox_result_view.cc b/chrome/browser/ui/views/omnibox/omnibox_result_view.cc
index 2a1fc53..fa8546b2 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_result_view.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_result_view.cc
@@ -20,7 +20,6 @@
 #include "base/i18n/bidi_line_iterator.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
-#include "chrome/browser/ui/layout_constants.h"
 #include "chrome/browser/ui/views/location_bar/background_with_1_px_border.h"
 #include "chrome/browser/ui/views/location_bar/location_bar_view.h"
 #include "chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.h"
@@ -590,20 +589,21 @@
 }
 
 void OmniboxResultView::Layout() {
-  int horizontal_padding =
-      GetLayoutConstant(LOCATION_BAR_HORIZONTAL_PADDING);
+  constexpr int horizontal_padding = LocationBarView::kHorizontalPadding;
   // The horizontal bounds we're given are the outside bounds, so we can match
   // the omnibox border outline shape exactly in OnPaint().  We have to inset
   // here to keep the icons lined up.
-  const int start_x =
-      GetLayoutConstant(LOCATION_BAR_BORDER_THICKNESS) + horizontal_padding;
+  constexpr int start_x =
+      BackgroundWith1PxBorder::kLocationBarBorderThicknessDip +
+      horizontal_padding;
   const int end_x = width() - start_x;
 
   const gfx::ImageSkia icon = GetIcon();
   icon_bounds_.SetRect(start_x, (GetContentLineHeight() - icon.height()) / 2,
                        icon.width(), icon.height());
 
-  const int text_x = start_x + LocationBarView::kIconWidth + horizontal_padding;
+  constexpr int text_x =
+      start_x + LocationBarView::kIconWidth + horizontal_padding;
   int text_width = end_x - text_x;
 
   if (match_.associated_keyword.get()) {
diff --git a/chrome/browser/ui/views/profiles/new_avatar_button.cc b/chrome/browser/ui/views/profiles/new_avatar_button.cc
index 0b7b45a..160c44f 100644
--- a/chrome/browser/ui/views/profiles/new_avatar_button.cc
+++ b/chrome/browser/ui/views/profiles/new_avatar_button.cc
@@ -70,7 +70,8 @@
   // is larger than this, it will be shrunk to match it.
   // TODO(noms): Calculate this constant algorithmically from the button's size.
   const int kDisplayFontHeight = 16;
-  SetFontList(GetFontList().DeriveWithHeightUpperBound(kDisplayFontHeight));
+  SetFontList(
+      label()->font_list().DeriveWithHeightUpperBound(kDisplayFontHeight));
 
   ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance();
   if (button_style == AvatarButtonStyle::THEMED) {
diff --git a/chrome/browser/ui/views/profiles/profile_chooser_view.cc b/chrome/browser/ui/views/profiles/profile_chooser_view.cc
index 638f0497..f2a8cfd 100644
--- a/chrome/browser/ui/views/profiles/profile_chooser_view.cc
+++ b/chrome/browser/ui/views/profiles/profile_chooser_view.cc
@@ -534,7 +534,7 @@
     AddChildView(profile_name_textfield_);
 
     button_ = new RightAlignedIconLabelButton(this, text);
-    button_->SetFontList(medium_font_list);
+    button_->SetFontListDeprecated(medium_font_list);
     // Show an "edit" pencil icon when hovering over. In the default state,
     // we need to create an empty placeholder of the correct size, so that
     // the text doesn't jump around when the hovered icon appears.
diff --git a/chrome/browser/ui/views/tabs/tab.cc b/chrome/browser/ui/views/tabs/tab.cc
index 1f39de8..10ea017 100644
--- a/chrome/browser/ui/views/tabs/tab.cc
+++ b/chrome/browser/ui/views/tabs/tab.cc
@@ -728,8 +728,7 @@
 // static
 gfx::Size Tab::GetStandardSize() {
   const int kNetTabWidth = 193;
-  return gfx::Size(kNetTabWidth + GetLayoutConstant(TABSTRIP_TAB_OVERLAP),
-                   GetMinimumInactiveSize().height());
+  return gfx::Size(kNetTabWidth + kOverlap, GetMinimumInactiveSize().height());
 }
 
 // static
@@ -739,8 +738,8 @@
 
 // static
 int Tab::GetPinnedWidth() {
-  return GetMinimumInactiveSize().width() +
-         GetLayoutConstant(TAB_PINNED_CONTENT_WIDTH);
+  constexpr int kTabPinnedContentWidth = 23;
+  return GetMinimumInactiveSize().width() + kTabPinnedContentWidth;
 }
 
 // static
@@ -919,9 +918,9 @@
   // Size the title to fill the remaining width and use all available height.
   const bool show_title = ShouldRenderAsNormalTab();
   if (show_title) {
-    const int title_spacing = GetLayoutConstant(TAB_FAVICON_TITLE_SPACING);
-    int title_left = showing_icon_ ?
-        (favicon_bounds_.right() + title_spacing) : start;
+    constexpr int kTitleSpacing = 6;
+    int title_left =
+        showing_icon_ ? (favicon_bounds_.right() + kTitleSpacing) : start;
     int title_width = lb.right() - title_left;
     if (showing_alert_indicator_) {
       title_width =
diff --git a/chrome/browser/ui/views/tabs/tab.h b/chrome/browser/ui/views/tabs/tab.h
index 9aefb65..180b1d9 100644
--- a/chrome/browser/ui/views/tabs/tab.h
+++ b/chrome/browser/ui/views/tabs/tab.h
@@ -52,6 +52,9 @@
   // The Tab's class name.
   static const char kViewClassName[];
 
+  // The amount of overlap between two adjacent tabs.
+  static constexpr int kOverlap = 16;
+
   Tab(TabController* controller, gfx::AnimationContainer* container);
   ~Tab() override;
 
diff --git a/chrome/browser/ui/views/tabs/tab_strip.cc b/chrome/browser/ui/views/tabs/tab_strip.cc
index 0fb15a9..c5c58a3 100644
--- a/chrome/browser/ui/views/tabs/tab_strip.cc
+++ b/chrome/browser/ui/views/tabs/tab_strip.cc
@@ -253,7 +253,7 @@
   tab_size_info->min_active_width = Tab::GetMinimumActiveSize().width();
   tab_size_info->min_inactive_width = Tab::GetMinimumInactiveSize().width();
   tab_size_info->max_size = Tab::GetStandardSize();
-  tab_size_info->tab_overlap = GetLayoutConstant(TABSTRIP_TAB_OVERLAP);
+  tab_size_info->tab_overlap = Tab::kOverlap;
   tab_size_info->pinned_to_normal_offset = kPinnedToNonPinnedOffset;
   return *tab_size_info;
 }
@@ -872,7 +872,7 @@
     Tab* last_tab = tab_at(model_count - 1);
     Tab* tab_being_removed = tab_at(model_index);
     available_width_for_tabs_ = last_tab->x() + last_tab->width() -
-        tab_being_removed->width() + GetLayoutConstant(TABSTRIP_TAB_OVERLAP);
+                                tab_being_removed->width() + Tab::kOverlap;
     if (model_index == 0 && tab_being_removed->data().pinned &&
         !tab_at(1)->data().pinned) {
       available_width_for_tabs_ -= kPinnedToNonPinnedOffset;
@@ -1297,8 +1297,7 @@
     if (current_x < previous_x)
       return true;  // Can happen during dragging.
 
-    if (previous_bounds.right() - GetLayoutConstant(TABSTRIP_TAB_OVERLAP) !=
-        current_x) {
+    if (previous_bounds.right() - Tab::kOverlap != current_x) {
       *clip = border_callback.Run(tab_at(index - 1)->size());
       clip->offset(SkIntToScalar(previous_x - current_x), 0);
     }
@@ -1497,14 +1496,13 @@
       needed_tab_width += kPinnedToNonPinnedOffset + min_selected_width +
                           ((remaining_tab_count - 1) * min_unselected_width);
     }
-    const int tab_overlap = GetLayoutConstant(TABSTRIP_TAB_OVERLAP);
     if (tab_count() > 1)
-      needed_tab_width -= (tab_count() - 1) * tab_overlap;
+      needed_tab_width -= (tab_count() - 1) * Tab::kOverlap;
 
     // Don't let the tabstrip shrink smaller than is necessary to show one tab,
     // and don't force it to be larger than is necessary to show 20 tabs.
     const int largest_min_tab_width =
-        min_selected_width + 19 * (min_unselected_width - tab_overlap);
+        min_selected_width + 19 * (min_unselected_width - Tab::kOverlap);
     needed_tab_width = std::min(
         std::max(needed_tab_width, min_selected_width), largest_min_tab_width);
   }
@@ -1659,9 +1657,9 @@
                    ideal_bounds(model_index).height());
   } else {
     Tab* last_tab = tab_at(model_index - 1);
-    tab->SetBounds(
-        last_tab->bounds().right() - GetLayoutConstant(TABSTRIP_TAB_OVERLAP),
-        ideal_bounds(model_index).y(), 0, ideal_bounds(model_index).height());
+    tab->SetBounds(last_tab->bounds().right() - Tab::kOverlap,
+                   ideal_bounds(model_index).y(), 0,
+                   ideal_bounds(model_index).height());
   }
 
   AnimateToIdealBounds();
@@ -1909,7 +1907,7 @@
     gfx::Rect new_bounds = tab->bounds();
     new_bounds.set_origin(gfx::Point(x, 0));
     bounds->push_back(new_bounds);
-    x += tab->width() - GetLayoutConstant(TABSTRIP_TAB_OVERLAP);
+    x += tab->width() - Tab::kOverlap;
   }
 }
 
@@ -1922,7 +1920,7 @@
       width += kPinnedToNonPinnedOffset;
   }
   if (!tabs.empty())
-    width -= GetLayoutConstant(TABSTRIP_TAB_OVERLAP) * (tabs.size() - 1);
+    width -= Tab::kOverlap * (tabs.size() - 1);
   return width;
 }
 
@@ -2256,13 +2254,12 @@
                                   bool* is_beneath) {
   DCHECK_NE(drop_index, -1);
   int center_x;
-  const int tab_overlap = GetLayoutConstant(TABSTRIP_TAB_OVERLAP);
   if (drop_index < tab_count()) {
     Tab* tab = tab_at(drop_index);
-    center_x = tab->x() + ((drop_before ? tab_overlap : tab->width()) / 2);
+    center_x = tab->x() + ((drop_before ? Tab::kOverlap : tab->width()) / 2);
   } else {
     Tab* last_tab = tab_at(drop_index - 1);
-    center_x = last_tab->x() + last_tab->width() - (tab_overlap / 2);
+    center_x = last_tab->x() + last_tab->width() - (Tab::kOverlap / 2);
   }
 
   // Mirror the center point if necessary.
@@ -2450,8 +2447,7 @@
     tabs_.set_ideal_bounds(i, tab_bounds[i]);
   return (num_pinned_tabs < tab_count())
              ? tab_bounds[num_pinned_tabs].x()
-             : tab_bounds[num_pinned_tabs - 1].right() -
-                   GetLayoutConstant(TABSTRIP_TAB_OVERLAP);
+             : tab_bounds[num_pinned_tabs - 1].right() - Tab::kOverlap;
 }
 
 int TabStrip::GetTabAreaWidth() const {
@@ -2478,7 +2474,7 @@
   // The user initiated the close. We want to persist the bounds of all the
   // existing tabs, so we manually shift ideal_bounds then animate.
   Tab* tab_closing = tab_at(model_index);
-  int delta = tab_closing->width() - GetLayoutConstant(TABSTRIP_TAB_OVERLAP);
+  int delta = tab_closing->width() - Tab::kOverlap;
   // If the tab being closed is a pinned tab next to a non-pinned tab, be sure
   // to add the extra padding.
   DCHECK_LT(model_index, tab_count() - 1);
@@ -2531,8 +2527,7 @@
   int pinned_tab_count = GetPinnedTabCount();
   if (pinned_tab_count == 0)
     return 0;
-  const int overlap = GetLayoutConstant(TABSTRIP_TAB_OVERLAP);
-  return pinned_tab_count * (Tab::GetPinnedWidth() - overlap) +
+  return pinned_tab_count * (Tab::GetPinnedWidth() - Tab::kOverlap) +
          kPinnedToNonPinnedOffset;
 }
 
@@ -2601,11 +2596,7 @@
     gfx::Size tab_size(Tab::GetMinimumActiveSize());
     tab_size.set_width(Tab::GetTouchWidth());
     touch_layout_.reset(new StackedTabStripLayout(
-                            tab_size,
-                            GetLayoutConstant(TABSTRIP_TAB_OVERLAP),
-                            kStackedPadding,
-                            kMaxStackedCount,
-                            &tabs_));
+        tab_size, Tab::kOverlap, kStackedPadding, kMaxStackedCount, &tabs_));
     touch_layout_->SetWidth(GetTabAreaWidth());
     // This has to be after SetWidth() as SetWidth() is going to reset the
     // bounds of the pinned tabs (since StackedTabStripLayout doesn't yet know
@@ -2633,9 +2624,9 @@
   int normal_count = tab_count() - pinned_tab_count;
   if (normal_count <= 1 || normal_count == pinned_tab_count)
     return false;
-  const int overlap = GetLayoutConstant(TABSTRIP_TAB_OVERLAP);
-  return (Tab::GetTouchWidth() * normal_count - overlap * (normal_count - 1)) >
-      GetTabAreaWidth() - GetStartXForNormalTabs();
+  return (Tab::GetTouchWidth() * normal_count -
+          Tab::kOverlap * (normal_count - 1)) >
+         GetTabAreaWidth() - GetStartXForNormalTabs();
 }
 
 void TabStrip::SetResetToShrinkOnExit(bool value) {
diff --git a/chrome/browser/ui/views/toolbar/app_menu_button.cc b/chrome/browser/ui/views/toolbar/app_menu_button.cc
index 58937a5..b66144b7 100644
--- a/chrome/browser/ui/views/toolbar/app_menu_button.cc
+++ b/chrome/browser/ui/views/toolbar/app_menu_button.cc
@@ -16,6 +16,7 @@
 #include "chrome/browser/ui/toolbar/app_menu_model.h"
 #include "chrome/browser/ui/views/extensions/browser_action_drag_data.h"
 #include "chrome/browser/ui/views/toolbar/app_menu.h"
+#include "chrome/browser/ui/views/toolbar/toolbar_button.h"
 #include "chrome/browser/ui/views/toolbar/toolbar_view.h"
 #include "chrome/grit/theme_resources.h"
 #include "extensions/common/feature_switch.h"
@@ -108,10 +109,9 @@
 }
 
 gfx::Size AppMenuButton::GetPreferredSize() const {
-  gfx::Size size(image()->GetPreferredSize());
-  const int pad = GetLayoutConstant(TOOLBAR_BUTTON_PADDING);
-  size.Enlarge(pad * 2, pad * 2);
-  return size;
+  gfx::Rect rect(image()->GetPreferredSize());
+  rect.Inset(gfx::Insets(-ToolbarButton::kInteriorPadding));
+  return rect.size();
 }
 
 void AppMenuButton::UpdateIcon() {
diff --git a/chrome/browser/ui/views/toolbar/toolbar_button.cc b/chrome/browser/ui/views/toolbar/toolbar_button.cc
index 00e427c..57fb60de 100644
--- a/chrome/browser/ui/views/toolbar/toolbar_button.cc
+++ b/chrome/browser/ui/views/toolbar/toolbar_button.cc
@@ -12,8 +12,6 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/themes/theme_service.h"
 #include "chrome/browser/themes/theme_service_factory.h"
-#include "chrome/browser/ui/layout_constants.h"
-#include "chrome/browser/ui/views/location_bar/location_bar_view.h"
 #include "ui/accessibility/ax_node_data.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/models/menu_model.h"
@@ -57,16 +55,10 @@
 }
 
 gfx::Size ToolbarButton::GetPreferredSize() const {
-  gfx::Size size(image()->GetPreferredSize());
-  gfx::Size label_size = label()->GetPreferredSize();
-  if (label_size.width() > 0) {
-    size.Enlarge(
-        label_size.width() + GetLayoutConstant(LOCATION_BAR_HORIZONTAL_PADDING),
-        0);
-  }
-  const int pad = GetLayoutConstant(TOOLBAR_BUTTON_PADDING);
-  size.Enlarge(2 * pad, 2 * pad);
-  return size;
+  DCHECK(label()->text().empty());
+  gfx::Rect rect(gfx::Size(image()->GetPreferredSize()));
+  rect.Inset(gfx::Insets(-kInteriorPadding));
+  return rect.size();
 }
 
 bool ToolbarButton::OnMousePressed(const ui::MouseEvent& event) {
@@ -150,7 +142,7 @@
       views::LabelButton::CreateDefaultBorder();
 
   if (ThemeServiceFactory::GetForProfile(profile_)->UsingSystemTheme())
-    border->set_insets(gfx::Insets(GetLayoutConstant(TOOLBAR_BUTTON_PADDING)));
+    border->set_insets(gfx::Insets(kInteriorPadding));
 
   return border;
 }
diff --git a/chrome/browser/ui/views/toolbar/toolbar_button.h b/chrome/browser/ui/views/toolbar/toolbar_button.h
index c3a3207c..04e0dfa 100644
--- a/chrome/browser/ui/views/toolbar/toolbar_button.h
+++ b/chrome/browser/ui/views/toolbar/toolbar_button.h
@@ -33,6 +33,9 @@
 class ToolbarButton : public views::LabelButton,
                       public views::ContextMenuController {
  public:
+  // Padding inside the border (around the image).
+  static constexpr int kInteriorPadding = 6;
+
   // Takes ownership of the |model|, which can be null if no menu
   // is to be shown.
   ToolbarButton(Profile* profile,
diff --git a/chrome/browser/ui/views/toolbar/toolbar_view.cc b/chrome/browser/ui/views/toolbar/toolbar_view.cc
index beae60d..96191078 100644
--- a/chrome/browser/ui/views/toolbar/toolbar_view.cc
+++ b/chrome/browser/ui/views/toolbar/toolbar_view.cc
@@ -570,8 +570,7 @@
       home_->bounds().right() + GetLayoutConstant(TOOLBAR_STANDARD_SPACING);
 
   int app_menu_width = app_menu_button_->GetPreferredSize().width();
-  const int right_padding =
-      GetLayoutConstant(TOOLBAR_LOCATION_BAR_RIGHT_PADDING);
+  const int right_padding = GetLayoutConstant(TOOLBAR_STANDARD_SPACING);
 
   // Note that the browser actions container has its own internal left and right
   // padding to visually separate it from the location bar and app menu button.
@@ -710,8 +709,6 @@
     const int element_padding = GetLayoutConstant(TOOLBAR_ELEMENT_PADDING);
     const int browser_actions_width =
         (browser_actions_->*get_size)().width();
-    const int right_padding =
-        GetLayoutConstant(TOOLBAR_LOCATION_BAR_RIGHT_PADDING);
     const int content_width =
         2 * GetToolbarHorizontalPadding() + (back_->*get_size)().width() +
         element_padding + (forward_->*get_size)().width() + element_padding +
@@ -720,7 +717,9 @@
              ? element_padding + (home_->*get_size)().width()
              : 0) +
         GetLayoutConstant(TOOLBAR_STANDARD_SPACING) +
-        (browser_actions_width > 0 ? browser_actions_width : right_padding) +
+        (browser_actions_width > 0
+             ? browser_actions_width
+             : GetLayoutConstant(TOOLBAR_STANDARD_SPACING)) +
         (app_menu_button_->*get_size)().width();
     size.Enlarge(content_width, 0);
   }
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 2128ca0d..f6f6061 100644
--- a/chrome/browser/ui/webui/chromeos/login/eula_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/eula_screen_handler.cc
@@ -23,6 +23,7 @@
 #include "components/login/localized_values_builder.h"
 #include "components/strings/grit/components_strings.h"
 #include "content/public/browser/web_contents.h"
+#include "rlz/features/features.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/views/widget/widget.h"
 #include "url/gurl.h"
@@ -131,7 +132,7 @@
   builder->Add("eulaTpmBusy", IDS_EULA_TPM_BUSY);
   builder->Add("eulaSystemInstallationSettingsOkButton", IDS_OK);
   builder->Add("termsOfServiceLoading", IDS_TERMS_OF_SERVICE_SCREEN_LOADING);
-#if defined(ENABLE_RLZ)
+#if BUILDFLAG(ENABLE_RLZ)
   builder->AddF("eulaRlzDesc",
                 IDS_EULA_RLZ_DESCRIPTION,
                 IDS_SHORT_PRODUCT_NAME,
@@ -161,7 +162,7 @@
 }
 
 void EulaScreenHandler::GetAdditionalParameters(base::DictionaryValue* dict) {
-#if defined(ENABLE_RLZ)
+#if BUILDFLAG(ENABLE_RLZ)
   dict->SetString("rlzEnabled", "enabled");
 #else
   dict->SetString("rlzEnabled", "disabled");
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 2b9092ec..c3067a60c 100644
--- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
@@ -894,12 +894,22 @@
 }
 
 void SigninScreenHandler::Initialize() {
-  // If delegate_ is nullptr here (e.g. WebUIScreenLocker has been destroyed),
-  // don't do anything, just return.
-  if (!delegate_)
-    return;
+  // Preload PIN keyboard if any of the users can authenticate via PIN.
+  if (user_manager::UserManager::IsInitialized()) {
+    for (user_manager::User* user :
+         user_manager::UserManager::Get()->GetLoggedInUsers()) {
 
-  if (show_on_init_) {
+      chromeos::PinStorage* pin_storage =
+          chromeos::PinStorageFactory::GetForUser(user);
+      if (pin_storage && pin_storage->IsPinAuthenticationAvailable()) {
+        CallJS("cr.ui.Oobe.preloadPinKeyboard");
+        break;
+      }
+    }
+  }
+
+  // |delegate_| is null when we are preloading the lock screen.
+  if (delegate_ && show_on_init_) {
     show_on_init_ = false;
     ShowImpl();
   }
diff --git a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
index df9faab..fac5055 100644
--- a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
+++ b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
@@ -237,6 +237,9 @@
      IDS_SETTINGS_ABOUT_PAGE_UNSTABLE_WARNING_MESSAGE},
     {"aboutUnstableWarningTitle",
      IDS_SETTINGS_ABOUT_PAGE_UNSTABLE_WARNING_TITLE},
+    {"aboutChannelDialogBeta", IDS_SETTINGS_ABOUT_PAGE_DIALOG_CHANNEL_BETA},
+    {"aboutChannelDialogDev", IDS_SETTINGS_ABOUT_PAGE_DIALOG_CHANNEL_DEV},
+    {"aboutChannelDialogStable", IDS_SETTINGS_ABOUT_PAGE_DIALOG_CHANNEL_STABLE},
 #endif
   };
   AddLocalizedStringsBulk(html_source, localized_strings,
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
index 769c213e..e656b88 100644
--- a/chrome/common/chrome_switches.cc
+++ b/chrome/common/chrome_switches.cc
@@ -1018,8 +1018,14 @@
 const char kHelp[]                          = "help";
 const char kHelpShort[]                     = "h";
 
-// Specifies which password store to use
-// (detect, default, gnome-keyring, gnome-libsecret, kwallet).
+// Specifies which encryption storage backend to use. Possible values are
+// kwallet, kwallet5, gnome, gnome-keyring, gnome-libsecret, basic. Any other
+// value will lead to Chrome detecting the best backend automatically.
+// TODO(crbug.com/571003): Once PasswordStore no longer uses the Keyring or
+// KWallet for storing passwords, rename this flag to stop referencing
+// passwords. Do not rename it sooner, though; developers and testers might
+// rely on it keeping large amounts of testing passwords out of their Keyrings
+// or KWallets.
 const char kPasswordStore[]                 = "password-store";
 
 // The same as the --class argument in X applications.  Overrides the WM_CLASS
diff --git a/chrome/common/stack_sampling_configuration.cc b/chrome/common/stack_sampling_configuration.cc
index ca79f3f..c2b0786 100644
--- a/chrome/common/stack_sampling_configuration.cc
+++ b/chrome/common/stack_sampling_configuration.cc
@@ -128,7 +128,8 @@
   DCHECK(IsBrowserProcess());
 
   if (process_type == switches::kGpuProcess &&
-      (configuration_ == PROFILE_GPU_PROCESS ||
+      (configuration_ == PROFILE_CONTROL ||
+       configuration_ == PROFILE_GPU_PROCESS ||
        configuration_ == PROFILE_BROWSER_AND_GPU_PROCESS)) {
     command_line->AppendSwitch(switches::kStartStackProfiler);
   }
@@ -180,18 +181,18 @@
       return ChooseConfiguration({
         { PROFILE_BROWSER_PROCESS, 0},
         { PROFILE_GPU_PROCESS, 0},
-        { PROFILE_BROWSER_AND_GPU_PROCESS, 50},
-        { PROFILE_CONTROL, 50},
-        { PROFILE_DISABLED, 0}
+        { PROFILE_BROWSER_AND_GPU_PROCESS, 80},
+        { PROFILE_CONTROL, 10},
+        { PROFILE_DISABLED, 10}
       });
 
     case version_info::Channel::DEV:
       return ChooseConfiguration({
         { PROFILE_BROWSER_PROCESS, 0},
         { PROFILE_GPU_PROCESS, 0},
-        { PROFILE_BROWSER_AND_GPU_PROCESS, 50},
-        { PROFILE_CONTROL, 50},
-        { PROFILE_DISABLED, 0}
+        { PROFILE_BROWSER_AND_GPU_PROCESS, 80},
+        { PROFILE_CONTROL, 10},
+        { PROFILE_DISABLED, 10}
       });
 
     default:
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index e39ee89..8aa3629 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -16,6 +16,7 @@
 import("//media/media_options.gni")
 import("//ppapi/features/features.gni")
 import("//remoting/remoting_enable.gni")
+import("//rlz/features/features.gni")
 import("//services/service_manager/public/service_manifest.gni")
 import("//testing/test.gni")
 import("//ui/base/ui_features.gni")
@@ -1228,6 +1229,7 @@
     "//media:media_features",
     "//ppapi/features",
     "//printing/features",
+    "//rlz/features",
     "//third_party/WebKit/public:features",
   ]
 
@@ -4757,6 +4759,9 @@
       "../browser/ui/views/apps/app_info_dialog/app_info_permissions_panel_unittest.cc",
       "../browser/ui/views/website_settings/website_settings_popup_view_unittest.cc",
     ]
+    if (is_chromeos) {
+      sources += [ "../browser/ui/views/ime_driver/input_method_bridge_chromeos_unittest.cc" ]
+    }
     if (!is_chromeos && (!is_mac || mac_views_browser)) {
       sources += [
         "../browser/ui/views/frame/opaque_browser_frame_view_layout_unittest.cc",
diff --git a/chrome/test/DEPS b/chrome/test/DEPS
index 254e0473..a975b8f 100644
--- a/chrome/test/DEPS
+++ b/chrome/test/DEPS
@@ -11,6 +11,7 @@
   "+extensions",
   "+mash/package",
   "+mojo",
+  "+rlz/features",
   "+services",
 
   # Tests under chrome/ shouldn't need to access the internals of content/ and
diff --git a/chrome/test/data/extensions/api_test/cast_channel/api/common.js b/chrome/test/data/extensions/api_test/cast_channel/api/common.js
index eabcc5cd..2eda086 100644
--- a/chrome/test/data/extensions/api_test/cast_channel/api/common.js
+++ b/chrome/test/data/extensions/api_test/cast_channel/api/common.js
@@ -8,7 +8,7 @@
   chrome.test.assertTrue(channel.channelId > 0);
   chrome.test.assertTrue(channel.connectInfo.ipAddress == '192.168.1.1');
   chrome.test.assertTrue(channel.connectInfo.port == 8009);
-  chrome.test.assertTrue(channel.connectInfo.auth == 'ssl');
+  chrome.test.assertTrue(channel.connectInfo.auth == 'ssl_verified');
   chrome.test.assertTrue(channel.readyState == 'open');
   chrome.test.assertTrue(channel.errorState == undefined);
 };
@@ -23,7 +23,7 @@
   chrome.test.assertTrue(channel.channelId > 0);
   chrome.test.assertTrue(channel.connectInfo.ipAddress == '192.168.1.1');
   chrome.test.assertTrue(channel.connectInfo.port == 8009);
-  chrome.test.assertTrue(channel.connectInfo.auth == 'ssl');
+  chrome.test.assertTrue(channel.connectInfo.auth == 'ssl_verified');
   chrome.test.assertTrue(channel.readyState == 'closed');
   chrome.test.assertTrue(channel.errorState == error);
 };
diff --git a/chrome/test/data/extensions/api_test/cast_channel/api/test_get_logs.js b/chrome/test/data/extensions/api_test/cast_channel/api/test_get_logs.js
index 99acf9f..315029b 100644
--- a/chrome/test/data/extensions/api_test/cast_channel/api/test_get_logs.js
+++ b/chrome/test/data/extensions/api_test/cast_channel/api/test_get_logs.js
@@ -29,5 +29,8 @@
   chrome.cast.channel.send(channel, message, onSend);
 };
 
-chrome.cast.channel.open({ipAddress: '192.168.1.1', port: 8009, auth: 'ssl'},
-                         onOpen);
+chrome.cast.channel.open({
+  ipAddress: '192.168.1.1',
+  port: 8009,
+  auth: 'ssl_verified'
+}, onOpen);
diff --git a/chrome/test/data/extensions/api_test/cast_channel/api/test_open_error.js b/chrome/test/data/extensions/api_test/cast_channel/api/test_open_error.js
index 3637ab3..2df11f6 100644
--- a/chrome/test/data/extensions/api_test/cast_channel/api/test_open_error.js
+++ b/chrome/test/data/extensions/api_test/cast_channel/api/test_open_error.js
@@ -33,5 +33,7 @@
 };
 
 chrome.cast.channel.onError.addListener(onError);
-chrome.cast.channel.open({ipAddress: '192.168.1.1', port: 8009, auth: 'ssl'},
-                         onOpen);
+chrome.cast.channel.open({
+  ipAddress: '192.168.1.1',
+  port: 8009,
+  auth: 'ssl_verified'}, onOpen);
diff --git a/chrome/test/data/extensions/api_test/cast_channel/api/test_open_receive_close.js b/chrome/test/data/extensions/api_test/cast_channel/api/test_open_receive_close.js
index 6fe6a79..36c255dc 100644
--- a/chrome/test/data/extensions/api_test/cast_channel/api/test_open_receive_close.js
+++ b/chrome/test/data/extensions/api_test/cast_channel/api/test_open_receive_close.js
@@ -30,5 +30,7 @@
   chrome.test.notifyPass();
 };
 
-chrome.cast.channel.open({ipAddress: '192.168.1.1', port: 8009, auth: 'ssl'},
-                         onOpen);
+chrome.cast.channel.open({
+  ipAddress: '192.168.1.1',
+  port: 8009,
+  auth: 'ssl_verified'}, onOpen);
diff --git a/chrome/test/data/extensions/api_test/cast_channel/api/test_open_send_close.js b/chrome/test/data/extensions/api_test/cast_channel/api/test_open_send_close.js
index 4afce56..6ec4ad5 100644
--- a/chrome/test/data/extensions/api_test/cast_channel/api/test_open_send_close.js
+++ b/chrome/test/data/extensions/api_test/cast_channel/api/test_open_send_close.js
@@ -23,6 +23,7 @@
   assertOpenChannel(channel);
   chrome.cast.channel.send(channel, message, onSend);
 };
-
-chrome.cast.channel.open({ipAddress: '192.168.1.1', port: 8009, auth: 'ssl'},
-                         onOpen);
+chrome.cast.channel.open({
+  ipAddress: '192.168.1.1',
+  port: 8009,
+  auth: 'ssl_verified'}, onOpen);
diff --git a/chrome/test/data/extensions/api_test/cast_channel/api/test_open_timeout.js b/chrome/test/data/extensions/api_test/cast_channel/api/test_open_timeout.js
index 348974e..f8949ffd 100644
--- a/chrome/test/data/extensions/api_test/cast_channel/api/test_open_timeout.js
+++ b/chrome/test/data/extensions/api_test/cast_channel/api/test_open_timeout.js
@@ -6,7 +6,7 @@
 chrome.cast.channel.open({
   ipAddress: '192.168.1.1',
   port: 8009,
-  auth: 'ssl',
+  auth: 'ssl_verified',
   livenessTimeout: 5000,
   pingInterval: 1000
 }, function(channel) {
diff --git a/chrome/test/data/extensions/api_test/platform_keys/basic.js b/chrome/test/data/extensions/api_test/platform_keys/basic.js
index 5e1eccba..ee4516d3 100644
--- a/chrome/test/data/extensions/api_test/platform_keys/basic.js
+++ b/chrome/test/data/extensions/api_test/platform_keys/basic.js
@@ -36,39 +36,38 @@
 
   // X.509 client certificate in DER encoding.
   // Algorithm in SPKI: rsaEncryption.
-  // openssl x509 -in net/data/ssl/certificates/client_1.pem -outform DER -out
-  //   client_1.der
+  // Generated by create_net_cert_data.sh .
   client_1: 'client_1.der',
 
   // X.509 client certificate in DER encoding.
   // Algorithm in SPKI: rsaEncryption.
-  // openssl x509 -in net/data/ssl/certificates/client_2.pem -outform DER -out
-  //   client_2.der
+  // Generated by create_net_cert_data.sh .
   client_2: 'client_2.der',
 
   // The public key of client_1 as Subject Public Key Info in DER encoding.
-  // openssl rsa -in net/data/ssl/certificates/client_1.key -inform PEM -out
-  //   pubkey.der -pubout -outform DER
+  // Generated by create_net_cert_data.sh .
   client_1_spki: 'client_1_spki.der',
 
   // The distinguished name of the CA that issued client_1 in DER encoding.
-  // openssl asn1parse -in client_1.der -inform DER -strparse 32 -out
-  //   client_1_issuer_dn.der
+  // Generated by create_net_cert_data.sh .
   client_1_issuer_dn: 'client_1_issuer_dn.der',
 
-  // echo -n "hello world" > data
+  // The string "hello world".
+  // Generated by create_net_cert_data.sh .
   raw_data: 'data',
 
-  // openssl rsautl -inkey net/data/ssl/certificates/client_1.key -sign -in
-  //   data -pkcs -out signature_nohash_pkcs
+  // A signature of raw_data using RSASSA-PKCS1-v1_5 with client_1, but treating
+  // raw_data as a raw digest and without adding the DigestInfo prefix.
+  // Generated by create_net_cert_data.sh .
   signature_nohash_pkcs: 'signature_nohash_pkcs',
 
-  // openssl dgst -sha1 -sign net/data/ssl/certificates/client_1.key
-  //   -out signature_sha1_pkcs data
+  // A signature of raw_data using RSASSA-PKCS1-v1_5 with client_1, using SHA-1
+  // as the hash function.
+  // Generated by create_net_cert_data.sh .
   signature_sha1_pkcs: 'signature_sha1_pkcs',
 };
 
-// Reads the binary file at |path| and passes it as a Uin8Array to |callback|.
+// Reads the binary file at |path| and passes it as a Uint8Array to |callback|.
 function readFile(path, callback) {
   var oReq = new XMLHttpRequest();
   oReq.responseType = "arraybuffer";
diff --git a/chrome/test/data/extensions/api_test/platform_keys/client_1.der b/chrome/test/data/extensions/api_test/platform_keys/client_1.der
index 248df92..a5d1da179a 100644
--- a/chrome/test/data/extensions/api_test/platform_keys/client_1.der
+++ b/chrome/test/data/extensions/api_test/platform_keys/client_1.der
Binary files differ
diff --git a/chrome/test/data/extensions/api_test/platform_keys/client_1_spki.der b/chrome/test/data/extensions/api_test/platform_keys/client_1_spki.der
index 7bd2e3f..55a79d4 100644
--- a/chrome/test/data/extensions/api_test/platform_keys/client_1_spki.der
+++ b/chrome/test/data/extensions/api_test/platform_keys/client_1_spki.der
Binary files differ
diff --git a/chrome/test/data/extensions/api_test/platform_keys/client_2.der b/chrome/test/data/extensions/api_test/platform_keys/client_2.der
index e2de8cb..8f49092 100644
--- a/chrome/test/data/extensions/api_test/platform_keys/client_2.der
+++ b/chrome/test/data/extensions/api_test/platform_keys/client_2.der
Binary files differ
diff --git a/chrome/test/data/extensions/api_test/platform_keys/create_net_cert_data.sh b/chrome/test/data/extensions/api_test/platform_keys/create_net_cert_data.sh
new file mode 100755
index 0000000..45e87b6
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/platform_keys/create_net_cert_data.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+# 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.
+
+# Updates the files which depend on net/data/ssl/certificates.
+
+try() {
+  "$@" || {
+    e=$?
+    echo "*** ERROR $e ***  $@  " > /dev/stderr
+    exit $e
+  }
+}
+
+net_certs_dir=../../../../../../net/data/ssl/certificates
+
+try openssl x509 -in "${net_certs_dir}/client_1.pem" -outform DER -out \
+  client_1.der
+try openssl x509 -in "${net_certs_dir}/client_2.pem" -outform DER -out \
+  client_2.der
+try openssl rsa -in "${net_certs_dir}/client_1.key" -inform PEM -out \
+  client_1_spki.der -pubout -outform DER
+try openssl asn1parse -in client_1.der -inform DER -strparse 32 -out \
+  client_1_issuer_dn.der
+try echo -n "hello world" > data
+try openssl rsautl -inkey "${net_certs_dir}/client_1.key" -sign -in \
+   data -pkcs -out signature_nohash_pkcs
+try openssl dgst -sha1 -sign "${net_certs_dir}/client_1.key" -out \
+   signature_sha1_pkcs data
diff --git a/chrome/test/data/extensions/api_test/platform_keys/signature_nohash_pkcs b/chrome/test/data/extensions/api_test/platform_keys/signature_nohash_pkcs
index 36784aa..bf916de 100644
--- a/chrome/test/data/extensions/api_test/platform_keys/signature_nohash_pkcs
+++ b/chrome/test/data/extensions/api_test/platform_keys/signature_nohash_pkcs
Binary files differ
diff --git a/chrome/test/data/extensions/api_test/platform_keys/signature_sha1_pkcs b/chrome/test/data/extensions/api_test/platform_keys/signature_sha1_pkcs
index c4b768e..e8d5e25 100644
--- a/chrome/test/data/extensions/api_test/platform_keys/signature_sha1_pkcs
+++ b/chrome/test/data/extensions/api_test/platform_keys/signature_sha1_pkcs
Binary files differ
diff --git a/chrome/test/data/webui/bluetooth_internals_browsertest.js b/chrome/test/data/webui/bluetooth_internals_browsertest.js
index 8d15b7d..ae30e2da9 100644
--- a/chrome/test/data/webui/bluetooth_internals_browsertest.js
+++ b/chrome/test/data/webui/bluetooth_internals_browsertest.js
@@ -67,7 +67,8 @@
           ]);
 
           this.adapter = new TestAdapter();
-          this.adapterHandle_ = connection.bindStubDerivedImpl(this.adapter);
+          this.adapterBinding_ = new bindings.Binding(adapter.Adapter,
+                                                      this.adapter);
         };
 
         TestAdapterFactoryProxy.prototype = {
@@ -77,7 +78,7 @@
 
             // Create message pipe bound to TestAdapter.
             return Promise.resolve({
-              adapter: this.adapterHandle_,
+              adapter: this.adapterBinding_.createInterfacePtrAndBind(),
             });
           }
         };
diff --git a/chrome/test/ppapi/ppapi_browsertest.cc b/chrome/test/ppapi/ppapi_browsertest.cc
index a191672..e78ed0a 100644
--- a/chrome/test/ppapi/ppapi_browsertest.cc
+++ b/chrome/test/ppapi/ppapi_browsertest.cc
@@ -31,6 +31,7 @@
 #include "extensions/common/constants.h"
 #include "extensions/test/extension_test_message_listener.h"
 #include "ppapi/shared_impl/test_utils.h"
+#include "rlz/features/features.h"
 
 #if defined(OS_MACOSX)
 #include "base/mac/mac_util.h"
@@ -1233,7 +1234,7 @@
 
 IN_PROC_BROWSER_TEST_F(OutOfProcessPPAPITest, FlashDRM) {
   RunTest(
-#if (defined(OS_WIN) && defined(ENABLE_RLZ)) || defined(OS_CHROMEOS)
+#if (defined(OS_WIN) && BUILDFLAG(ENABLE_RLZ)) || defined(OS_CHROMEOS)
           // Only implemented on Windows and ChromeOS currently.
           LIST_TEST(FlashDRM_GetDeviceID)
 #endif
diff --git a/chrome/tools/build/win/create_installer_archive.py b/chrome/tools/build/win/create_installer_archive.py
index 8c0f814..4a4f0807 100755
--- a/chrome/tools/build/win/create_installer_archive.py
+++ b/chrome/tools/build/win/create_installer_archive.py
@@ -485,30 +485,8 @@
   if not os.path.exists(installer_dir):
     os.mkdir(installer_dir)
 
-  if setup_runtime_deps:
-    setup_component_dlls = ParseDLLsFromDeps(build_dir, setup_runtime_deps)
-  else:
-    # Explicitly list the component DLLs setup.exe depends on (this list may
-    # contain wildcards). These will be copied to |installer_dir| in the
-    # archive.
-    # TODO(jbauman): Remove when GYP is deprecated on Windows.
-    setup_component_dll_globs = [ 'api-ms-win-*.dll',
-                                  'base.dll',
-                                  'boringssl.dll',
-                                  'crcrypto.dll',
-                                  'icui18n.dll',
-                                  'icuuc.dll',
-                                  'msvc*.dll',
-                                  'ucrtbase*.dll',
-                                  'vcruntime*.dll', ]
-    setup_component_dlls = set()
-    for setup_component_dll_glob in setup_component_dll_globs:
-      setup_component_partial_dlls = glob.glob(
-          os.path.join(build_dir, setup_component_dll_glob))
-      if len(setup_component_partial_dlls) == 0:
-        raise Exception('Error: missing expected DLL for component build '
-                        'mini_installer: "%s"' % setup_component_dll_glob)
-      setup_component_dlls.update(setup_component_partial_dlls)
+  setup_component_dlls = ParseDLLsFromDeps(build_dir, setup_runtime_deps)
+
   for setup_component_dll in setup_component_dlls:
     g_archive_inputs.append(setup_component_dll)
     shutil.copy(setup_component_dll, installer_dir)
@@ -517,26 +495,13 @@
   # the version assembly to be able to refer to them below and make sure
   # chrome.exe can find them at runtime), except the ones that are already
   # staged (i.e. non-component DLLs).
-  if chrome_runtime_deps:
-    build_dlls = ParseDLLsFromDeps(build_dir, chrome_runtime_deps)
-  else:
-    # If no chrome_runtime_deps was specified, every DLL in build_dir is
-    # considered to be a component DLL.
-    # TODO(jbauman): Remove when GYP is deprecated on Windows.
-    build_dlls = glob.glob(os.path.join(build_dir, '*.dll'))
+  build_dlls = ParseDLLsFromDeps(build_dir, chrome_runtime_deps)
   staged_dll_basenames = [os.path.basename(staged_dll) for staged_dll in \
                           glob.glob(os.path.join(version_dir, '*.dll'))]
   component_dll_filenames = []
   for component_dll in [dll for dll in build_dlls if \
                         os.path.basename(dll) not in staged_dll_basenames]:
     component_dll_name = os.path.basename(component_dll)
-    # These remoting_*.dll's don't belong in the archive (it doesn't depend
-    # on them in gyp). Trying to copy them causes a build race when creating the
-    # installer archive in component mode. See: crbug.com/180996 and
-    # crbug.com/586967
-    if (component_dll_name.startswith('remoting_')):
-      continue
-
     component_dll_filenames.append(component_dll_name)
     g_archive_inputs.append(component_dll)
     shutil.copy(component_dll, version_dir)
@@ -646,9 +611,6 @@
   parser.add_option('--depfile',
       help='Generate a depfile with the given name listing the implicit inputs '
            'to the archive process that can be used with a build system.')
-
-  # TODO(jbauman): Make --chrome_runtime_deps and --setup_runtime_deps
-  # mandatory when GYP is deprecated on Windows.
   parser.add_option('--chrome_runtime_deps',
       help='A file listing runtime dependencies. This will be used to get a '
            'list of DLLs to archive in a component build.')
@@ -674,6 +636,12 @@
   if not options.input_file:
     parser.error('You must provide an input file')
 
+  is_component_build = options.component_build == '1'
+  if is_component_build and not options.chrome_runtime_deps:
+    parser.error("chrome_runtime_deps must be specified for a component build")
+  if is_component_build and not options.setup_runtime_deps:
+    parser.error("setup_runtime_deps must be specified for a component build")
+
   if not options.output_dir:
     options.output_dir = options.build_dir
 
diff --git a/chrome/utility/chrome_content_utility_client.cc b/chrome/utility/chrome_content_utility_client.cc
index f364d639..f95ceadf 100644
--- a/chrome/utility/chrome_content_utility_client.cc
+++ b/chrome/utility/chrome_content_utility_client.cc
@@ -204,7 +204,7 @@
   registry->AddInterface<net::interfaces::ProxyResolverFactory>(
       base::Bind(CreateProxyResolverFactory));
   registry->AddInterface(base::Bind(CreateResourceUsageReporter));
-  registry->AddInterface(base::Bind(ProfileImportHandler::Create));
+  registry->AddInterface(base::Bind(&ProfileImportHandler::Create));
 #endif
   registry->AddInterface(
       base::Bind(&safe_json::SafeJsonParserMojoImpl::Create));
diff --git a/chromecast/BUILD.gn b/chromecast/BUILD.gn
index c2ab7a3..edf45a1 100644
--- a/chromecast/BUILD.gn
+++ b/chromecast/BUILD.gn
@@ -85,7 +85,6 @@
       args = [
         "--no-sandbox",
         "--enable-local-file-accesses",
-        "--enable-cma-media-pipeline",
         "--ozone-platform=cast",
         "--test-launcher-jobs=1",
       ]
diff --git a/chromecast/base/metrics/BUILD.gn b/chromecast/base/metrics/BUILD.gn
index a9556a5..c547e8fa 100644
--- a/chromecast/base/metrics/BUILD.gn
+++ b/chromecast/base/metrics/BUILD.gn
@@ -22,6 +22,8 @@
   sources = [
     "cast_metrics_test_helper.cc",
     "cast_metrics_test_helper.h",
+    "mock_cast_metrics_helper.cc",
+    "mock_cast_metrics_helper.h",
   ]
 
   public_deps = [
@@ -30,5 +32,6 @@
 
   deps = [
     "//base",
+    "//testing/gmock",
   ]
 }
diff --git a/chromecast/base/metrics/mock_cast_metrics_helper.cc b/chromecast/base/metrics/mock_cast_metrics_helper.cc
new file mode 100644
index 0000000..2af76e04
--- /dev/null
+++ b/chromecast/base/metrics/mock_cast_metrics_helper.cc
@@ -0,0 +1,15 @@
+// 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 "chromecast/base/metrics/mock_cast_metrics_helper.h"
+
+namespace chromecast {
+namespace metrics {
+
+MockCastMetricsHelper::MockCastMetricsHelper() = default;
+
+MockCastMetricsHelper::~MockCastMetricsHelper() = default;
+
+}  // namespace metrics
+}  // namespace chromecast
diff --git a/chromecast/base/metrics/mock_cast_metrics_helper.h b/chromecast/base/metrics/mock_cast_metrics_helper.h
new file mode 100644
index 0000000..7436620
--- /dev/null
+++ b/chromecast/base/metrics/mock_cast_metrics_helper.h
@@ -0,0 +1,49 @@
+// 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 CHROMECAST_BASE_METRICS_MOCK_CAST_METRICS_HELPER_H_
+#define CHROMECAST_BASE_METRICS_MOCK_CAST_METRICS_HELPER_H_
+
+#include "base/macros.h"
+#include "chromecast/base/metrics/cast_metrics_helper.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+namespace chromecast {
+namespace metrics {
+
+class MockCastMetricsHelper : public CastMetricsHelper {
+ public:
+  MockCastMetricsHelper();
+  ~MockCastMetricsHelper() override;
+
+  MOCK_METHOD2(UpdateCurrentAppInfo,
+               void(const std::string& app_id, const std::string& session_id));
+  MOCK_METHOD1(UpdateSDKInfo, void(const std::string& sdk_version));
+  MOCK_METHOD0(LogMediaPlay, void());
+  MOCK_METHOD0(LogMediaPause, void());
+  MOCK_METHOD1(RecordSimpleAction, void(const std::string& action));
+  MOCK_METHOD2(RecordEventWithValue,
+               void(const std::string& action, int value));
+  MOCK_METHOD1(RecordApplicationEvent, void(const std::string& event));
+  MOCK_METHOD2(RecordApplicationEventWithValue,
+               void(const std::string& event, int value));
+  MOCK_METHOD0(LogTimeToFirstPaint, void());
+  MOCK_METHOD0(LogTimeToFirstAudio, void());
+  MOCK_METHOD2(LogTimeToBufferAv,
+               void(BufferingType buffering_type, base::TimeDelta time));
+  MOCK_CONST_METHOD2(GetMetricsNameWithAppName,
+                     std::string(const std::string& prefix,
+                                 const std::string& suffix));
+  MOCK_METHOD1(SetMetricsSink, void(MetricsSink* delegate));
+  MOCK_METHOD1(SetRecordActionCallback,
+               void(const RecordActionCallback& callback));
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(MockCastMetricsHelper);
+};
+
+}  // namespace metrics
+}  // namespace chromecast
+
+#endif  // CHROMECAST_BASE_METRICS_MOCK_CAST_METRICS_HELPER_H_
diff --git a/chromecast/browser/android/apk/AndroidManifest.xml.jinja2 b/chromecast/browser/android/apk/AndroidManifest.xml.jinja2
index 01e6497..b977a9d 100644
--- a/chromecast/browser/android/apk/AndroidManifest.xml.jinja2
+++ b/chromecast/browser/android/apk/AndroidManifest.xml.jinja2
@@ -44,7 +44,7 @@
                  android:exported="false" />
         {% endfor %}
 
-        {% set num_privileged_services = 20 %}
+        {% set num_privileged_services = 3 %}
         <meta-data android:name="org.chromium.content.browser.NUM_PRIVILEGED_SERVICES"
                    android:value="{{ num_privileged_services }}"/>
         {% for i in range(num_privileged_services) %}
diff --git a/chromecast/renderer/cast_content_renderer_client.cc b/chromecast/renderer/cast_content_renderer_client.cc
index c3d1419..125c4bd 100644
--- a/chromecast/renderer/cast_content_renderer_client.cc
+++ b/chromecast/renderer/cast_content_renderer_client.cc
@@ -170,6 +170,7 @@
   static const int mojo_resource_ids[] = {
       IDR_MOJO_UNICODE_JS,
       IDR_MOJO_BUFFER_JS,
+      IDR_MOJO_INTERFACE_TYPES_JS,
       IDR_MOJO_CODEC_JS,
       IDR_MOJO_CONNECTOR_JS,
       IDR_MOJO_VALIDATOR_JS,
diff --git a/components/BUILD.gn b/components/BUILD.gn
index d57d240..bfe31f2 100644
--- a/components/BUILD.gn
+++ b/components/BUILD.gn
@@ -6,6 +6,7 @@
 import("//build/config/features.gni")
 import("//build/config/ui.gni")
 import("//printing/features/features.gni")
+import("//rlz/features/features.gni")
 import("//testing/test.gni")
 import("//tools/grit/repack.gni")
 
diff --git a/components/arc/BUILD.gn b/components/arc/BUILD.gn
index c09d970..155d286 100644
--- a/components/arc/BUILD.gn
+++ b/components/arc/BUILD.gn
@@ -64,8 +64,6 @@
     "power/arc_power_bridge.h",
     "storage_manager/arc_storage_manager.cc",
     "storage_manager/arc_storage_manager.h",
-    "user_data/arc_user_data_service.cc",
-    "user_data/arc_user_data_service.h",
   ]
 
   public_deps = [
diff --git a/components/arc/user_data/arc_user_data_service.cc b/components/arc/user_data/arc_user_data_service.cc
deleted file mode 100644
index b9b3082f..0000000
--- a/components/arc/user_data/arc_user_data_service.cc
+++ /dev/null
@@ -1,86 +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 "components/arc/user_data/arc_user_data_service.h"
-
-#include <utility>
-
-#include "base/command_line.h"
-#include "chromeos/chromeos_switches.h"
-#include "chromeos/cryptohome/cryptohome_parameters.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
-#include "components/prefs/pref_member.h"
-#include "components/signin/core/account_id/account_id.h"
-#include "components/user_manager/user_manager.h"
-
-namespace arc {
-
-ArcUserDataService::ArcUserDataService(
-    ArcBridgeService* bridge_service,
-    std::unique_ptr<BooleanPrefMember> arc_enabled_pref,
-    const AccountId& account_id)
-    : ArcService(bridge_service),
-      arc_enabled_pref_(std::move(arc_enabled_pref)),
-      primary_user_account_id_(account_id),
-      weak_ptr_factory_(this) {
-  arc_bridge_service()->AddObserver(this);
-  pref_change_registrar_.Init(arc_enabled_pref_->prefs());
-  pref_change_registrar_.Add(
-      arc_enabled_pref_->GetPrefName(),
-      base::Bind(&ArcUserDataService::OnOptInPreferenceChanged,
-                 weak_ptr_factory_.GetWeakPtr()));
-  WipeIfRequired();
-}
-
-ArcUserDataService::~ArcUserDataService() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  arc_bridge_service()->RemoveObserver(this);
-}
-
-void ArcUserDataService::OnBridgeStopped(ArcBridgeService::StopReason reason) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  const AccountId& account_id =
-      user_manager::UserManager::Get()->GetPrimaryUser()->GetAccountId();
-  if (account_id != primary_user_account_id_) {
-    LOG(ERROR) << "User preferences not loaded for "
-               << primary_user_account_id_.GetUserEmail()
-               << ", but current primary user is " << account_id.GetUserEmail();
-    primary_user_account_id_ = EmptyAccountId();
-    return;
-  }
-  WipeIfRequired();
-}
-
-void ArcUserDataService::RequireUserDataWiped(const ArcDataCallback& callback) {
-  VLOG(1) << "Require ARC user data to be wiped.";
-  arc_user_data_wipe_required_ = true;
-  callback_ = callback;
-}
-
-void ArcUserDataService::WipeIfRequired() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  if (!arc_bridge_service()->stopped()) {
-    LOG(ERROR) << "ARC instance not stopped, user data can't be wiped";
-    return;
-  }
-  if ((arc_enabled_pref_->GetValue() && !arc_user_data_wipe_required_) ||
-      base::CommandLine::ForCurrentProcess()->HasSwitch(
-          chromeos::switches::kDisableArcDataWipe)) {
-    return;
-  }
-  VLOG(1) << "Wipe ARC user data.";
-  arc_user_data_wipe_required_ = false;
-  const cryptohome::Identification cryptohome_id(primary_user_account_id_);
-  chromeos::SessionManagerClient* session_manager_client =
-      chromeos::DBusThreadManager::Get()->GetSessionManagerClient();
-  session_manager_client->RemoveArcData(cryptohome_id, callback_);
-  callback_.Reset();
-}
-
-void ArcUserDataService::OnOptInPreferenceChanged() {
-  if (!arc_enabled_pref_->GetValue())
-    arc_user_data_wipe_required_ = true;
-}
-
-}  // namespace arc
diff --git a/components/arc/user_data/arc_user_data_service.h b/components/arc/user_data/arc_user_data_service.h
deleted file mode 100644
index 1ac89a2..0000000
--- a/components/arc/user_data/arc_user_data_service.h
+++ /dev/null
@@ -1,84 +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 COMPONENTS_ARC_USER_DATA_ARC_USER_DATA_SERVICE_H_
-#define COMPONENTS_ARC_USER_DATA_ARC_USER_DATA_SERVICE_H_
-
-#include <memory>
-
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "base/threading/thread_checker.h"
-#include "chromeos/dbus/session_manager_client.h"
-#include "components/arc/arc_bridge_service.h"
-#include "components/arc/arc_service.h"
-#include "components/prefs/pref_change_registrar.h"
-#include "components/prefs/pref_member.h"
-#include "components/signin/core/account_id/account_id.h"
-
-namespace arc {
-
-class ArcBridgeService;
-
-// This class controls the lifecycle of ARC user data, removing it when
-// necessary.
-class ArcUserDataService : public ArcService,
-                           public ArcBridgeService::Observer {
- public:
-  explicit ArcUserDataService(
-      ArcBridgeService* arc_bridge_service,
-      std::unique_ptr<BooleanPrefMember> arc_enabled_pref,
-      const AccountId& account_id);
-  ~ArcUserDataService() override;
-
-  using ArcDataCallback = chromeos::SessionManagerClient::ArcCallback;
-
-  // ArcBridgeService::Observer:
-  // Called whenever the arc bridge is stopped to potentially wipe data if
-  // the user has not opted in or it is required.
-  void OnBridgeStopped(ArcBridgeService::StopReason reason) override;
-
-  // Requires to wipe ARC user data after the next ARC bridge shutdown and call
-  // |callback| with an operation result.
-  void RequireUserDataWiped(const ArcDataCallback& callback);
-
- private:
-  base::ThreadChecker thread_checker_;
-
-  // Checks if ARC is both stopped and disabled (not opt-in) or data wipe is
-  // required and triggers removal of user data.
-  void WipeIfRequired();
-
-  // Callback when the kArcEnabled preference changes. It watches for instances
-  // where the preference is disabled and remembers this so that it can wipe
-  // user data once the bridge has stopped.
-  void OnOptInPreferenceChanged();
-
-  const std::unique_ptr<BooleanPrefMember> arc_enabled_pref_;
-
-  // Account ID for the account for which we currently have opt-in information.
-  AccountId primary_user_account_id_;
-
-  // Registrar used to monitor ARC enabled state.
-  PrefChangeRegistrar pref_change_registrar_;
-
-  // Set to true when kArcEnabled goes from true to false or user data wipe is
-  // required and set to false again after user data has been wiped.
-  // This ensures data is wiped even if the user tries to enable ARC before the
-  // bridge has shut down.
-  bool arc_user_data_wipe_required_ = false;
-
-  // Callback object that is passed to RemoveArcData to be invoked with a
-  // result of ARC user data wipe.
-  // Set when ARC user data wipe is required by RequireUserDataWiped.
-  ArcDataCallback callback_;
-
-  base::WeakPtrFactory<ArcUserDataService> weak_ptr_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(ArcUserDataService);
-};
-
-}  // namespace arc
-
-#endif  // COMPONENTS_ARC_USER_DATA_ARC_USER_DATA_SERVICE_H_
diff --git a/components/autofill/DEPS b/components/autofill/DEPS
index 7e8eeb9..6b6ca5cf 100644
--- a/components/autofill/DEPS
+++ b/components/autofill/DEPS
@@ -4,6 +4,7 @@
   "+grit",  # For generated headers
   "+jni",
   "+net",
+  "+third_party/skia",
   "+third_party/zlib/google",
   "+ui",
 
diff --git a/components/autofill/android/java/src/org/chromium/components/autofill/AutofillPopup.java b/components/autofill/android/java/src/org/chromium/components/autofill/AutofillPopup.java
index 55c214f..3a5bd06 100644
--- a/components/autofill/android/java/src/org/chromium/components/autofill/AutofillPopup.java
+++ b/components/autofill/android/java/src/org/chromium/components/autofill/AutofillPopup.java
@@ -6,6 +6,7 @@
 
 import android.annotation.SuppressLint;
 import android.content.Context;
+import android.graphics.Color;
 import android.view.View;
 import android.widget.AdapterView;
 import android.widget.PopupWindow;
@@ -28,7 +29,8 @@
 
     /**
      * The constant used to specify a separator in a list of Autofill suggestions.
-     * Has to be kept in sync with enum in WebAutofillClient.h
+     * Has to be kept in sync with {@code POPUP_ITEM_ID_SEPARATOR} enum in
+     * components/autofill/core/browser/popup_item_ids.h
      */
     private static final int ITEM_ID_SEPARATOR_ENTRY = -3;
 
@@ -57,9 +59,18 @@
     /**
      * Filters the Autofill suggestions to the ones that we support and shows the popup.
      * @param suggestions Autofill suggestion data.
+     * @param isRtl @code true if right-to-left text.
+     * @param backgroundColor popup background color, or {@code Color.TRANSPARENT} if unspecified.
+     * @param dividerColor color for divider between popup items, or {@code Color.TRANSPARENT} if
+     * unspecified.
+     * @param isBoldLabel true if suggestion label's type face is {@code Typeface.BOLD}, false if
+     * suggestion label's type face is {@code Typeface.NORMAL}.
+     * @param dropdownItemHeight height of each dropdown item in dimension independent pixel units,
+     * 0 if unspecified.
      */
     @SuppressLint("InlinedApi")
-    public void filterAndShow(AutofillSuggestion[] suggestions, boolean isRtl) {
+    public void filterAndShow(AutofillSuggestion[] suggestions, boolean isRtl,
+            int backgroundColor, int dividerColor, int dropdownItemHeight) {
         mSuggestions = new ArrayList<AutofillSuggestion>(Arrays.asList(suggestions));
         // Remove the AutofillSuggestions with IDs that are not supported by Android
         ArrayList<DropdownItem> cleanedData = new ArrayList<DropdownItem>();
@@ -73,7 +84,10 @@
             }
         }
 
-        setAdapter(new DropdownAdapter(mContext, cleanedData, separators));
+        setAdapter(new DropdownAdapter(mContext, cleanedData, separators,
+                backgroundColor == Color.TRANSPARENT ? null : backgroundColor,
+                dividerColor == Color.TRANSPARENT ? null : dividerColor,
+                dropdownItemHeight == 0 ? null : dropdownItemHeight));
         setRtl(isRtl);
         show();
         getListView().setOnItemLongClickListener(this);
diff --git a/components/autofill/android/java/src/org/chromium/components/autofill/AutofillSuggestion.java b/components/autofill/android/java/src/org/chromium/components/autofill/AutofillSuggestion.java
index eaf23c363..666dcbf 100644
--- a/components/autofill/android/java/src/org/chromium/components/autofill/AutofillSuggestion.java
+++ b/components/autofill/android/java/src/org/chromium/components/autofill/AutofillSuggestion.java
@@ -12,34 +12,42 @@
 public class AutofillSuggestion extends DropdownItemBase {
     /**
      * The constant used to specify a http warning message in a list of Autofill suggestions.
-     * Has to be kept in sync with enum in popup_item_ids.h
-     * TODO(crbug.com/666529): Generate java constants from C++ enum.
+     * Has to be kept in sync with {@code POPUP_ITEM_ID_SEPARATOR} enum in
+     * components/autofill/core/browser/popup_item_ids.h
      */
     private static final int ITEM_ID_HTTP_NOT_SECURE_WARNING_MESSAGE = -10;
 
     private final String mLabel;
     private final String mSublabel;
     private final int mIconId;
+    private final boolean mIsIconAtStart;
     private final int mSuggestionId;
-    private final boolean mDeletable;
+    private final boolean mIsDeletable;
     private final boolean mIsMultilineLabel;
+    private final boolean mIsBoldLabel;
 
     /**
      * Constructs a Autofill suggestion container.
      * @param label The main label of the Autofill suggestion.
      * @param sublabel The describing sublabel of the Autofill suggestion.
+     * @param iconId The resource ID for the icon associated with the suggestion, or
+     * {@code DropdownItem.NO_ICON} for no icon.
+     * @param isIconAtStart {@code true} if {@param iconId} is displayed before {@param label}.
      * @param suggestionId The type of suggestion.
-     * @param deletable Whether the item can be deleted by the user.
-     * @param multilineLabel Whether the label is displayed over multiple lines.
+     * @param isDeletable Whether the item can be deleted by the user.
+     * @param isMultilineLabel Whether the label is displayed over multiple lines.
+     * @param isBoldLabel Whether the label is displayed in {@code Typeface.BOLD}.
      */
-    public AutofillSuggestion(String label, String sublabel, int iconId, int suggestionId,
-            boolean deletable, boolean multilineLabel) {
+    public AutofillSuggestion(String label, String sublabel, int iconId, boolean isIconAtStart,
+            int suggestionId, boolean isDeletable, boolean isMultilineLabel, boolean isBoldLabel) {
         mLabel = label;
         mSublabel = sublabel;
         mIconId = iconId;
+        mIsIconAtStart = isIconAtStart;
         mSuggestionId = suggestionId;
-        mDeletable = deletable;
-        mIsMultilineLabel = multilineLabel;
+        mIsDeletable = isDeletable;
+        mIsMultilineLabel = isMultilineLabel;
+        mIsBoldLabel = isBoldLabel;
     }
 
     @Override
@@ -63,6 +71,11 @@
     }
 
     @Override
+    public boolean isBoldLabel() {
+        return mIsBoldLabel;
+    }
+
+    @Override
     public int getLabelFontColorResId() {
         if (mSuggestionId == ITEM_ID_HTTP_NOT_SECURE_WARNING_MESSAGE) {
             return R.color.http_bad_warning_message_text;
@@ -88,7 +101,7 @@
 
     @Override
     public boolean isIconAtStart() {
-        if (mSuggestionId == ITEM_ID_HTTP_NOT_SECURE_WARNING_MESSAGE) {
+        if (mIsIconAtStart) {
             return true;
         }
         return super.isIconAtStart();
@@ -99,7 +112,7 @@
     }
 
     public boolean isDeletable() {
-        return mDeletable;
+        return mIsDeletable;
     }
 
     public boolean isFillable() {
diff --git a/components/autofill/core/browser/autofill_download_manager.cc b/components/autofill/core/browser/autofill_download_manager.cc
index 021a850..331de99 100644
--- a/components/autofill/core/browser/autofill_download_manager.cc
+++ b/components/autofill/core/browser/autofill_download_manager.cc
@@ -247,8 +247,12 @@
                         net::LOAD_DO_NOT_SEND_COOKIES);
   // Add Chrome experiment state to the request headers.
   net::HttpRequestHeaders headers;
-  variations::AppendVariationHeaders(
-      fetcher->GetOriginalURL(), driver_->IsOffTheRecord(), false, &headers);
+  // Note: It's fine to pass in |is_signed_in| false, which does not affect
+  // transmission of experiment ids coming from the variations server.
+  bool is_signed_in = false;
+  variations::AppendVariationHeaders(fetcher->GetOriginalURL(),
+                                     driver_->IsOffTheRecord(), false,
+                                     is_signed_in, &headers);
   fetcher->SetExtraRequestHeaders(headers.ToString());
   fetcher->Start();
 
diff --git a/components/autofill/core/browser/autofill_experiments.cc b/components/autofill/core/browser/autofill_experiments.cc
index 6ecc864b..28fdc27b 100644
--- a/components/autofill/core/browser/autofill_experiments.cc
+++ b/components/autofill/core/browser/autofill_experiments.cc
@@ -7,9 +7,12 @@
 #include "base/command_line.h"
 #include "base/feature_list.h"
 #include "base/metrics/field_trial.h"
+#include "base/strings/string16.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
+#include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
+#include "components/autofill/core/browser/suggestion.h"
 #include "components/autofill/core/common/autofill_pref_names.h"
 #include "components/autofill/core/common/autofill_switches.h"
 #include "components/prefs/pref_service.h"
@@ -17,6 +20,8 @@
 #include "components/sync/driver/sync_service.h"
 #include "components/variations/variations_associated_data.h"
 #include "google_apis/gaia/gaia_auth_util.h"
+#include "grit/components_strings.h"
+#include "ui/base/l10n/l10n_util.h"
 
 namespace autofill {
 
@@ -28,7 +33,34 @@
                                             base::FEATURE_DISABLED_BY_DEFAULT};
 const base::Feature kAutofillScanCardholderName{
     "AutofillScanCardholderName", base::FEATURE_DISABLED_BY_DEFAULT};
+const base::Feature kAutofillCreditCardPopupLayout{
+    "AutofillCreditCardPopupLayout", base::FEATURE_DISABLED_BY_DEFAULT};
 const char kCreditCardSigninPromoImpressionLimitParamKey[] = "impression_limit";
+const char kAutofillCreditCardPopupBackgroundColorKey[] = "background_color";
+const char kAutofillCreditCardPopupDividerColorKey[] = "dropdown_divider_color";
+const char kAutofillCreditCardPopupValueBoldKey[] = "is_value_bold";
+const char kAutofillCreditCardPopupIsValueAndLabelInSingleLineKey[] =
+    "is_value_and_label_in_single_line";
+const char kAutofillPopupDropdownItemHeightKey[] =
+    "dropdown_item_height";
+const char kAutofillCreditCardPopupIsIconAtStartKey[] =
+    "is_credit_card_icon_at_start";
+
+namespace {
+
+// Returns parameter value in |kAutofillCreditCardPopupLayout| feature, or 0 if
+// parameter is not specified.
+unsigned int GetCreditCardPopupParameterUintValue(
+    const std::string& param_name) {
+  unsigned int value;
+  const std::string param_value = variations::GetVariationParamValueByFeature(
+      kAutofillCreditCardPopupLayout, param_name);
+  if (!param_value.empty() && base::StringToUint(param_value, &value))
+    return value;
+  return 0;
+}
+
+}  // namespace
 
 bool IsAutofillEnabled(const PrefService* pref_service) {
   return pref_service->GetBoolean(prefs::kAutofillEnabled);
@@ -67,6 +99,60 @@
   return 0;
 }
 
+bool IsAutofillCreditCardPopupLayoutExperimentEnabled() {
+  return base::FeatureList::IsEnabled(kAutofillCreditCardPopupLayout);
+}
+
+// |GetCreditCardPopupParameterUintValue| returns 0 if experiment parameter is
+// not specified. 0 == |SK_ColorTRANSPARENT|.
+SkColor GetCreditCardPopupBackgroundColor() {
+  return GetCreditCardPopupParameterUintValue(
+      kAutofillCreditCardPopupBackgroundColorKey);
+}
+
+SkColor GetCreditCardPopupDividerColor() {
+  return GetCreditCardPopupParameterUintValue(
+      kAutofillCreditCardPopupDividerColorKey);
+}
+
+bool IsCreditCardPopupValueBold() {
+  const std::string param_value = variations::GetVariationParamValueByFeature(
+      kAutofillCreditCardPopupLayout, kAutofillCreditCardPopupValueBoldKey);
+  return param_value == "true";
+}
+
+unsigned int GetPopupDropdownItemHeight() {
+  return GetCreditCardPopupParameterUintValue(
+      kAutofillPopupDropdownItemHeightKey);
+}
+
+bool IsIconInCreditCardPopupAtStart() {
+  const std::string param_value = variations::GetVariationParamValueByFeature(
+      kAutofillCreditCardPopupLayout, kAutofillCreditCardPopupIsIconAtStartKey);
+  return param_value == "true";
+}
+
+// Modifies |suggestion| as follows if experiment to display value and label in
+// a single line is enabled.
+// Say, |value| is 'Visa ....1111' and |label| is '01/18' (expiration date).
+// Modifies |value| to 'Visa ....1111, exp 01/18' and clears |label|.
+void ModifyAutofillCreditCardSuggestion(Suggestion* suggestion) {
+  DCHECK(IsAutofillCreditCardPopupLayoutExperimentEnabled());
+  const std::string param_value = variations::GetVariationParamValueByFeature(
+      kAutofillCreditCardPopupLayout,
+      kAutofillCreditCardPopupIsValueAndLabelInSingleLineKey);
+  if (param_value == "true") {
+    const base::string16 format_string = l10n_util::GetStringUTF16(
+        IDS_AUTOFILL_CREDIT_CARD_EXPIRATION_DATE_LABEL_AND_ABBR);
+    if (!format_string.empty()) {
+      suggestion->value.append(l10n_util::GetStringFUTF16(
+          IDS_AUTOFILL_CREDIT_CARD_EXPIRATION_DATE_LABEL_AND_ABBR,
+          suggestion->label));
+    }
+    suggestion->label.clear();
+  }
+}
+
 bool OfferStoreUnmaskedCards() {
 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
   // The checkbox can be forced on with a flag, but by default we don't store
diff --git a/components/autofill/core/browser/autofill_experiments.h b/components/autofill/core/browser/autofill_experiments.h
index 9fe4fc0b..fc02866 100644
--- a/components/autofill/core/browser/autofill_experiments.h
+++ b/components/autofill/core/browser/autofill_experiments.h
@@ -7,6 +7,9 @@
 
 #include <string>
 
+#include "base/strings/string16.h"
+#include "third_party/skia/include/core/SkColor.h"
+
 class PrefService;
 
 namespace base {
@@ -19,11 +22,15 @@
 
 namespace autofill {
 
+struct Suggestion;
+
 extern const base::Feature kAutofillCreditCardAssist;
 extern const base::Feature kAutofillCreditCardSigninPromo;
 extern const base::Feature kAutofillProfileCleanup;
 extern const base::Feature kAutofillScanCardholderName;
+extern const base::Feature kAutofillCreditCardPopupLayout;
 extern const char kCreditCardSigninPromoImpressionLimitParamKey[];
+extern const char kAutofillCreditCardPopupSettingsSuggestionValueKey[];
 
 // Returns true if autofill should be enabled. See also
 // IsInAutofillSuggestionsDisabledExperiment below.
@@ -64,6 +71,37 @@
 // in the autofill dropdown when credit card fields are on an HTTP page.
 bool IsCreditCardAutofillHttpWarningEnabled();
 
+// Returns whether the new Autofill credit card popup layout experiment is
+// enabled.
+bool IsAutofillCreditCardPopupLayoutExperimentEnabled();
+
+// Returns the background color for credit card autofill popup, or
+// |SK_ColorTRANSPARENT| if the new credit card autofill popup layout experiment
+// is not enabled.
+SkColor GetCreditCardPopupBackgroundColor();
+
+// Returns the divider color for credit card autofill popup, or
+// |SK_ColorTRANSPARENT| if the new credit card autofill popup layout experiment
+// is not enabled.
+SkColor GetCreditCardPopupDividerColor();
+
+// Returns true if the credit card autofill popup suggestion value is displayed
+// in bold type face.
+bool IsCreditCardPopupValueBold();
+
+// Returns the dropdown item height for autofill popup, returning 0 if the
+// dropdown item height isn't configured in an experiment to tweak autofill
+// popup layout.
+unsigned int GetPopupDropdownItemHeight();
+
+// Returns true if the icon in the credit card autofill popup must be displayed
+// before the credit card value or any other suggestion text.
+bool IsIconInCreditCardPopupAtStart();
+
+// Modifies the suggestion value and label if the new credit card autofill popup
+// experiment is enabled to tweak the display of the value and label.
+void ModifyAutofillCreditCardSuggestion(struct Suggestion* suggestion);
+
 }  // namespace autofill
 
 #endif  // COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_EXPERIMENTS_H_
diff --git a/components/autofill/core/browser/autofill_external_delegate.cc b/components/autofill/core/browser/autofill_external_delegate.cc
index 9c8c7c13..bfab143d 100644
--- a/components/autofill/core/browser/autofill_external_delegate.cc
+++ b/components/autofill/core/browser/autofill_external_delegate.cc
@@ -19,6 +19,7 @@
 #include "build/build_config.h"
 #include "components/autofill/core/browser/autocomplete_history_manager.h"
 #include "components/autofill/core/browser/autofill_driver.h"
+#include "components/autofill/core/browser/autofill_experiments.h"
 #include "components/autofill/core/browser/autofill_manager.h"
 #include "components/autofill/core/browser/autofill_metrics.h"
 #include "components/autofill/core/browser/popup_item_ids.h"
@@ -48,6 +49,7 @@
       has_autofill_suggestions_(false),
       has_shown_popup_for_current_edit_(false),
       should_show_scan_credit_card_(false),
+      is_credit_card_popup_(false),
       should_show_cc_signin_promo_(false),
       has_shown_address_book_prompt(false),
       weak_ptr_factory_(this) {
@@ -69,6 +71,8 @@
   element_bounds_ = element_bounds;
   should_show_scan_credit_card_ =
       manager_->ShouldShowScanCreditCard(query_form_, query_field_);
+  is_credit_card_popup_ =
+      manager_->IsCreditCardPopup(query_form_, query_field_);
   should_show_cc_signin_promo_ =
       manager_->ShouldShowCreditCardSigninPromo(query_form_, query_field_);
 }
@@ -275,6 +279,10 @@
   driver_->RendererShouldClearPreviewedForm();
 }
 
+bool AutofillExternalDelegate::IsCreditCardPopup() {
+  return is_credit_card_popup_;
+}
+
 void AutofillExternalDelegate::Reset() {
   manager_->client()->HideAutofillPopup();
 }
@@ -325,8 +333,6 @@
   if (query_field_.is_autofilled) {
     base::string16 value =
         l10n_util::GetStringUTF16(IDS_AUTOFILL_CLEAR_FORM_MENU_ITEM);
-    // TODO(rouslan): Remove manual upper-casing when keyboard accessory becomes
-    // default on Android.
     if (IsKeyboardAccessoryEnabled())
       value = base::i18n::ToUpper(value);
 
@@ -334,12 +340,9 @@
     suggestions->back().frontend_id = POPUP_ITEM_ID_CLEAR_FORM;
   }
 
-  // Append the 'Chrome Autofill options' menu item;
-  // TODO(rouslan): Switch on the platform in the GRD file when keyboard
-  // accessory becomes default on Android.
-  suggestions->push_back(Suggestion(l10n_util::GetStringUTF16(
-      IsKeyboardAccessoryEnabled() ? IDS_AUTOFILL_OPTIONS_CONTENT_DESCRIPTION
-                                   : IDS_AUTOFILL_OPTIONS_POPUP)));
+  // Append the 'Chrome Autofill options' menu item, or the menu item specified
+  // in the popup layout experiment.
+  suggestions->push_back(Suggestion(GetSettingsSuggestionValue()));
   suggestions->back().frontend_id = POPUP_ITEM_ID_AUTOFILL_OPTIONS;
   if (IsKeyboardAccessoryEnabled())
     suggestions->back().icon = base::ASCIIToUTF16("settings");
@@ -382,4 +385,14 @@
   }
 }
 
+base::string16 AutofillExternalDelegate::GetSettingsSuggestionValue()
+    const {
+  if (IsKeyboardAccessoryEnabled()) {
+    return l10n_util::GetStringUTF16(IDS_AUTOFILL_OPTIONS_CONTENT_DESCRIPTION);
+  }
+  return l10n_util::GetStringUTF16(is_credit_card_popup_ ?
+                                   IDS_AUTOFILL_CREDIT_CARD_OPTIONS_POPUP :
+                                   IDS_AUTOFILL_OPTIONS_POPUP);
+}
+
 }  // namespace autofill
diff --git a/components/autofill/core/browser/autofill_external_delegate.h b/components/autofill/core/browser/autofill_external_delegate.h
index 4afbb92..6a9807a0 100644
--- a/components/autofill/core/browser/autofill_external_delegate.h
+++ b/components/autofill/core/browser/autofill_external_delegate.h
@@ -51,6 +51,9 @@
                                    base::string16* body) override;
   bool RemoveSuggestion(const base::string16& value, int identifier) override;
   void ClearPreviewedForm() override;
+  // Returns false for all popups prior to |onQuery|, true for credit card
+  // popups after call to |onQuery|.
+  bool IsCreditCardPopup() override;
 
   // Records and associates a query_id with web form data.  Called
   // when the renderer posts an Autofill query to the browser. |bounds|
@@ -115,6 +118,9 @@
   // version.
   void InsertDataListValues(std::vector<Suggestion>* suggestions);
 
+  // Returns the text (i.e. |Suggestion| value) for Chrome autofill options.
+  base::string16 GetSettingsSuggestionValue() const;
+
   AutofillManager* manager_;  // weak.
 
   // Provides driver-level context to the shared code of the component. Must
@@ -139,8 +145,8 @@
   // currently editing?  Used to keep track of state for metrics logging.
   bool has_shown_popup_for_current_edit_;
 
-  // FIXME
   bool should_show_scan_credit_card_;
+  bool is_credit_card_popup_;
 
   // Whether the credit card signin promo should be shown to the user.
   bool should_show_cc_signin_promo_;
diff --git a/components/autofill/core/browser/autofill_manager.cc b/components/autofill/core/browser/autofill_manager.cc
index fe2557c..6d12bb9 100644
--- a/components/autofill/core/browser/autofill_manager.cc
+++ b/components/autofill/core/browser/autofill_manager.cc
@@ -308,6 +308,12 @@
   return field.value.size() <= kShowScanCreditCardMaxValueLength;
 }
 
+bool AutofillManager::IsCreditCardPopup(const FormData& form,
+                                        const FormFieldData& field) {
+  AutofillField* autofill_field = GetAutofillField(form, field);
+  return autofill_field && autofill_field->Type().group() == CREDIT_CARD;
+}
+
 bool AutofillManager::ShouldShowCreditCardSigninPromo(
     const FormData& form,
     const FormFieldData& field) {
@@ -528,8 +534,6 @@
   if (!IsValidFormData(form) || !IsValidFormFieldData(field))
     return;
 
-  std::vector<Suggestion> suggestions;
-
   gfx::RectF transformed_box =
       driver_->TransformBoundingBoxToViewportCoordinates(bounding_box);
   external_delegate_->OnQuery(query_id, form, field, transformed_box);
@@ -554,6 +558,8 @@
     }
   }
 
+  std::vector<Suggestion> suggestions;
+
   if (is_autofill_possible &&
       driver_->RendererIsAvailable() &&
       got_autofillable_form) {
@@ -1790,6 +1796,7 @@
   for (size_t i = 0; i < suggestions.size(); i++) {
     suggestions[i].frontend_id =
         MakeFrontendID(suggestions[i].backend_id, std::string());
+    suggestions[i].is_value_bold = IsCreditCardPopupValueBold();
   }
   return suggestions;
 }
diff --git a/components/autofill/core/browser/autofill_manager.h b/components/autofill/core/browser/autofill_manager.h
index 16efc7f..ce8608f 100644
--- a/components/autofill/core/browser/autofill_manager.h
+++ b/components/autofill/core/browser/autofill_manager.h
@@ -96,6 +96,10 @@
   virtual bool ShouldShowScanCreditCard(const FormData& form,
                                         const FormFieldData& field);
 
+  // Whether the |field| belongs to CREDIT_CARD |FieldTypeGroup|.
+  virtual bool IsCreditCardPopup(const FormData& form,
+                                 const FormFieldData& field);
+
   // Whether we should show the signin promo, based on the triggered |field|
   // inside the |form|.
   virtual bool ShouldShowCreditCardSigninPromo(const FormData& form,
diff --git a/components/autofill/core/browser/autofill_popup_delegate.h b/components/autofill/core/browser/autofill_popup_delegate.h
index 99a6675..5a86424 100644
--- a/components/autofill/core/browser/autofill_popup_delegate.h
+++ b/components/autofill/core/browser/autofill_popup_delegate.h
@@ -43,6 +43,9 @@
 
   // Informs the delegate that the Autofill previewed form should be cleared.
   virtual void ClearPreviewedForm() = 0;
+
+  // Returns true if popup is for credit card.
+  virtual bool IsCreditCardPopup() = 0;
 };
 
 }  // namespace autofill
diff --git a/components/autofill/core/browser/personal_data_manager.cc b/components/autofill/core/browser/personal_data_manager.cc
index 37418c7..b58bc6c 100644
--- a/components/autofill/core/browser/personal_data_manager.cc
+++ b/components/autofill/core/browser/personal_data_manager.cc
@@ -1626,6 +1626,8 @@
         suggestion->value = credit_card->TypeAndLastFourDigits();
         suggestion->label = credit_card->GetInfo(
             AutofillType(CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR), app_locale_);
+        if (IsAutofillCreditCardPopupLayoutExperimentEnabled())
+          ModifyAutofillCreditCardSuggestion(suggestion);
       } else if (credit_card->number().empty()) {
         if (type.GetStorableType() != CREDIT_CARD_NAME_FULL) {
           suggestion->label = credit_card->GetInfo(
diff --git a/components/autofill/core/browser/suggestion.cc b/components/autofill/core/browser/suggestion.cc
index 22d4ac7..754ede93 100644
--- a/components/autofill/core/browser/suggestion.cc
+++ b/components/autofill/core/browser/suggestion.cc
@@ -10,7 +10,8 @@
 
 Suggestion::Suggestion()
     : frontend_id(0),
-      match(PREFIX_MATCH) {
+      match(PREFIX_MATCH),
+      is_value_bold(false) {
 }
 
 Suggestion::Suggestion(const Suggestion& other)
@@ -19,13 +20,15 @@
       value(other.value),
       label(other.label),
       icon(other.icon),
-      match(other.match) {
+      match(other.match),
+      is_value_bold(other.is_value_bold) {
 }
 
 Suggestion::Suggestion(const base::string16& v)
     : frontend_id(0),
       value(v),
-      match(PREFIX_MATCH) {
+      match(PREFIX_MATCH),
+      is_value_bold(false) {
 }
 
 Suggestion::Suggestion(const std::string& v,
@@ -36,7 +39,8 @@
       value(base::UTF8ToUTF16(v)),
       label(base::UTF8ToUTF16(l)),
       icon(base::UTF8ToUTF16(i)),
-      match(PREFIX_MATCH) {
+      match(PREFIX_MATCH),
+      is_value_bold(false) {
 }
 
 Suggestion::~Suggestion() {
diff --git a/components/autofill/core/browser/suggestion.h b/components/autofill/core/browser/suggestion.h
index 930ab23..63522de 100644
--- a/components/autofill/core/browser/suggestion.h
+++ b/components/autofill/core/browser/suggestion.h
@@ -47,6 +47,7 @@
   base::string16 label;
   base::string16 icon;
   MatchMode match;
+  bool is_value_bold;  // true if |value| should be displayed in bold type face.
 };
 
 }  // namespace autofill
diff --git a/components/autofill_strings.grdp b/components/autofill_strings.grdp
index e6bafa54..92713992 100644
--- a/components/autofill_strings.grdp
+++ b/components/autofill_strings.grdp
@@ -157,6 +157,17 @@
     </message>
   </if>
 
+  <if expr="_google_chrome">
+    <message name="IDS_AUTOFILL_CREDIT_CARD_OPTIONS_POPUP" desc="The label of the text displayed in the Autofill Credit Card popup to direct the user to the Autofill settings UI.">
+     Chrome Autofill settings...    
+    </message>
+  </if>
+  <if expr="not _google_chrome">
+    <message name="IDS_AUTOFILL_CREDIT_CARD_OPTIONS_POPUP" desc="The label of the text displayed in the Autofill Credit Card popup to direct the user to the Autofill settings UI.">    
+      Chromium Autofill settings...
+    </message>
+  </if>    
+
   <message name="IDS_AUTOFILL_OPTIONS_CONTENT_DESCRIPTION" desc="The text verbalised by a screen reader for the button that directs the user to the Autofill settings UI. This string is not displayed.">
     settings
   </message>
@@ -229,6 +240,10 @@
     Exp: <ph name="EXPIRATION_MONTH">$1<ex>06</ex></ph>/<ph name="EXPIRATION_YEAR">$2<ex>17</ex></ph>
   </message>
 
+  <message name="IDS_AUTOFILL_CREDIT_CARD_EXPIRATION_DATE_LABEL_AND_ABBR" desc="text displayed in the Autofill Credit Card popup before the credit card expiration date and the abbreviated expiration date.">
+    , exp <ph name="EXPIRATION_DATE_ABBR">$1<ex>06/17</ex></ph>
+  </message>
+
   <!-- Autofill credit card unmask prompt -->
   <message name="IDS_AUTOFILL_CARD_UNMASK_PROMPT_ERROR_TRY_AGAIN_CVC" desc="Error message that encourages the user to try to re-enter their credit card CVC after a previous failed attempt." formatter_data="android_java">
     Check your CVC and try again
diff --git a/components/browsing_data/core/counters/autofill_counter.cc b/components/browsing_data/core/counters/autofill_counter.cc
index a852db4..b0e55d0f 100644
--- a/components/browsing_data/core/counters/autofill_counter.cc
+++ b/components/browsing_data/core/counters/autofill_counter.cc
@@ -81,7 +81,20 @@
     WebDataServiceBase::Handle handle,
     std::unique_ptr<WDTypedResult> result) {
   DCHECK(thread_checker_.CalledOnValidThread());
+
   if (!result) {
+    // CancelAllRequests will cancel all queries that are active; the query that
+    // just failed is complete and cannot be canceled so zero it out.
+    if (handle == suggestions_query_) {
+      suggestions_query_ = 0;
+    } else if (handle == credit_cards_query_) {
+      credit_cards_query_ = 0;
+    } else if (handle == addresses_query_) {
+      addresses_query_ = 0;
+    } else {
+      NOTREACHED();
+    }
+
     CancelAllRequests();
     return;
   }
diff --git a/components/cronet/android/api/src/org/chromium/net/ExperimentalCronetEngine.java b/components/cronet/android/api/src/org/chromium/net/ExperimentalCronetEngine.java
index 6fc67f4e..4535fe15 100644
--- a/components/cronet/android/api/src/org/chromium/net/ExperimentalCronetEngine.java
+++ b/components/cronet/android/api/src/org/chromium/net/ExperimentalCronetEngine.java
@@ -181,8 +181,12 @@
             return this;
         }
 
+        /**
+         * Returns delegate, only for testing.
+         * @hide
+         */
         @VisibleForTesting
-        ICronetEngineBuilder getBuilderDelegate() {
+        public ICronetEngineBuilder getBuilderDelegate() {
             return mBuilderDelegate;
         }
 
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/CronetTestBase.java b/components/cronet/android/test/javatests/src/org/chromium/net/CronetTestBase.java
index addc524f..c0b8d3c 100644
--- a/components/cronet/android/test/javatests/src/org/chromium/net/CronetTestBase.java
+++ b/components/cronet/android/test/javatests/src/org/chromium/net/CronetTestBase.java
@@ -152,7 +152,7 @@
         }
     }
 
-    void assertResponseEquals(UrlResponseInfo expected, UrlResponseInfo actual) {
+    public void assertResponseEquals(UrlResponseInfo expected, UrlResponseInfo actual) {
         assertEquals(expected.getAllHeaders(), actual.getAllHeaders());
         assertEquals(expected.getAllHeadersAsList(), actual.getAllHeadersAsList());
         assertEquals(expected.getHttpStatusCode(), actual.getHttpStatusCode());
@@ -168,7 +168,7 @@
         }
     }
 
-    static void assertContains(String expectedSubstring, String actualString) {
+    public static void assertContains(String expectedSubstring, String actualString) {
         assertNotNull(actualString);
         if (!actualString.contains(expectedSubstring)) {
             fail("String [" + actualString + "] doesn't contain substring [" + expectedSubstring
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/TestUrlRequestCallback.java b/components/cronet/android/test/javatests/src/org/chromium/net/TestUrlRequestCallback.java
index b088cfb..42f98a5 100644
--- a/components/cronet/android/test/javatests/src/org/chromium/net/TestUrlRequestCallback.java
+++ b/components/cronet/android/test/javatests/src/org/chromium/net/TestUrlRequestCallback.java
@@ -27,7 +27,7 @@
  * method to block thread until the request completes on another thread.
  * Allows to cancel, block request or throw an exception from an arbitrary step.
  */
-class TestUrlRequestCallback extends UrlRequest.Callback {
+public class TestUrlRequestCallback extends UrlRequest.Callback {
     public ArrayList<UrlResponseInfo> mRedirectResponseInfoList = new ArrayList<UrlResponseInfo>();
     public ArrayList<String> mRedirectUrlList = new ArrayList<String>();
     public UrlResponseInfo mResponseInfo;
diff --git a/components/cronet/android/test/src/org/chromium/net/QuicTestServer.java b/components/cronet/android/test/src/org/chromium/net/QuicTestServer.java
index 0e9c5878..4745e7f 100644
--- a/components/cronet/android/test/src/org/chromium/net/QuicTestServer.java
+++ b/components/cronet/android/test/src/org/chromium/net/QuicTestServer.java
@@ -7,6 +7,7 @@
 import android.content.Context;
 import android.os.ConditionVariable;
 
+import org.chromium.base.ContextUtils;
 import org.chromium.base.Log;
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.annotations.JNINamespace;
@@ -73,6 +74,7 @@
     }
 
     public static long createMockCertVerifier() {
+        TestFilesInstaller.installIfNeeded(ContextUtils.getApplicationContext());
         return MockCertVerifier.createMockCertVerifier(CERTS_USED, true);
     }
 
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 40fbb78..f3374d5 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
@@ -201,6 +201,13 @@
       percent_savings_via_data_reduction_proxy);
 }
 
+void RecordSavingsClearedNegativeClockMetric(int days_since_last_update) {
+  // Data savings are cleared if the system clock moved back by more than
+  // one day.
+  UMA_HISTOGRAM_BOOLEAN("DataReductionProxy.SavingsCleared.NegativeSystemClock",
+                        days_since_last_update < -1);
+}
+
 }  // namespace
 
 class DataReductionProxyCompressionStats::DailyContentLengthUpdate {
@@ -923,6 +930,8 @@
           "Net.DailyContentLength_ViaDataReductionProxy_UnknownMime");
     }
 
+    RecordSavingsClearedNegativeClockMetric(days_since_last_update);
+
     // The system may go backwards in time by up to a day for legitimate
     // reasons, such as with changes to the time zone. In such cases, we
     // keep adding to the current day which is why we check for
@@ -930,6 +939,11 @@
     // Note: we accept the fact that some reported data is shifted to
     // the adjacent day if users travel back and forth across time zones.
     if (days_since_last_update && (days_since_last_update != -1)) {
+      if (days_since_last_update < -1) {
+        pref_service_->SetInt64(
+            prefs::kDataReductionProxySavingsClearedNegativeSystemClock,
+            now.ToInternalValue());
+      }
       SetInt64(data_reduction_proxy::prefs::
                    kDailyHttpOriginalContentLengthApplication,
                0);
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 31a62cc..35ec52f 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
@@ -904,11 +904,14 @@
 }
 
 TEST_F(DataReductionProxyCompressionStatsTest, ForwardMultipleDays) {
+  base::HistogramTester histogram_tester;
   const int64_t kOriginalLength = 200;
   const int64_t kReceivedLength = 100;
   RecordContentLengthPrefs(
       kReceivedLength, kOriginalLength, true, VIA_DATA_REDUCTION_PROXY,
       FakeNow());
+  histogram_tester.ExpectUniqueSample(
+      "DataReductionProxy.SavingsCleared.NegativeSystemClock", false, 1);
 
   // Forward three days.
   SetFakeTimeDeltaInHours(3 * 24);
@@ -916,6 +919,8 @@
   RecordContentLengthPrefs(
       kReceivedLength, kOriginalLength, true, VIA_DATA_REDUCTION_PROXY,
       FakeNow());
+  histogram_tester.ExpectUniqueSample(
+      "DataReductionProxy.SavingsCleared.NegativeSystemClock", false, 2);
 
   int64_t original[] = {kOriginalLength, 0, 0, kOriginalLength};
   int64_t received[] = {kReceivedLength, 0, 0, kReceivedLength};
@@ -939,6 +944,8 @@
       original2, 8, received2, 8,
       original2, 8, received2, 8,
       original2, 8, received2, 8);
+  histogram_tester.ExpectUniqueSample(
+      "DataReductionProxy.SavingsCleared.NegativeSystemClock", false, 3);
 
   // Forward |kNumDaysInHistory| more days.
   AddFakeTimeDeltaInHours(kNumDaysInHistory * 24);
@@ -951,6 +958,8 @@
       original3, 1, received3, 1,
       original3, 1, received3, 1,
       original3, 1, received3, 1);
+  histogram_tester.ExpectUniqueSample(
+      "DataReductionProxy.SavingsCleared.NegativeSystemClock", false, 4);
 
   // Forward |kNumDaysInHistory| + 1 more days.
   AddFakeTimeDeltaInHours((kNumDaysInHistory + 1)* 24);
@@ -961,9 +970,12 @@
       original3, 1, received3, 1,
       original3, 1, received3, 1,
       original3, 1, received3, 1);
+  histogram_tester.ExpectUniqueSample(
+      "DataReductionProxy.SavingsCleared.NegativeSystemClock", false, 5);
 }
 
 TEST_F(DataReductionProxyCompressionStatsTest, BackwardAndForwardOneDay) {
+  base::HistogramTester histogram_tester;
   const int64_t kOriginalLength = 200;
   const int64_t kReceivedLength = 100;
   int64_t original[] = {kOriginalLength};
@@ -972,6 +984,8 @@
   RecordContentLengthPrefs(
       kReceivedLength, kOriginalLength, true, VIA_DATA_REDUCTION_PROXY,
       FakeNow());
+  histogram_tester.ExpectUniqueSample(
+      "DataReductionProxy.SavingsCleared.NegativeSystemClock", false, 1);
 
   // Backward one day.
   SetFakeTimeDeltaInHours(-24);
@@ -984,6 +998,8 @@
       original, 1, received, 1,
       original, 1, received, 1,
       original, 1, received, 1);
+  histogram_tester.ExpectUniqueSample(
+      "DataReductionProxy.SavingsCleared.NegativeSystemClock", false, 2);
 
   // Then, Forward one day
   AddFakeTimeDeltaInHours(24);
@@ -996,9 +1012,12 @@
       original2, 2, received2, 2,
       original2, 2, received2, 2,
       original2, 2, received2, 2);
+  histogram_tester.ExpectUniqueSample(
+      "DataReductionProxy.SavingsCleared.NegativeSystemClock", false, 3);
 }
 
 TEST_F(DataReductionProxyCompressionStatsTest, BackwardTwoDays) {
+  base::HistogramTester histogram_tester;
   const int64_t kOriginalLength = 200;
   const int64_t kReceivedLength = 100;
   int64_t original[] = {kOriginalLength};
@@ -1007,6 +1026,9 @@
   RecordContentLengthPrefs(
       kReceivedLength, kOriginalLength, true, VIA_DATA_REDUCTION_PROXY,
       FakeNow());
+  histogram_tester.ExpectUniqueSample(
+      "DataReductionProxy.SavingsCleared.NegativeSystemClock", false, 1);
+
   // Backward two days.
   SetFakeTimeDeltaInHours(-2 * 24);
   RecordContentLengthPrefs(
@@ -1016,6 +1038,30 @@
       original, 1, received, 1,
       original, 1, received, 1,
       original, 1, received, 1);
+  histogram_tester.ExpectTotalCount(
+      "DataReductionProxy.SavingsCleared.NegativeSystemClock", 2);
+  histogram_tester.ExpectBucketCount(
+      "DataReductionProxy.SavingsCleared.NegativeSystemClock", true, 1);
+  VerifyPrefInt64(prefs::kDataReductionProxySavingsClearedNegativeSystemClock,
+                  FakeNow().ToInternalValue());
+
+  // Backward two days.
+  SetFakeTimeDeltaInHours(-4 * 24);
+  RecordContentLengthPrefs(kReceivedLength, kOriginalLength, true,
+                           VIA_DATA_REDUCTION_PROXY, FakeNow());
+  histogram_tester.ExpectTotalCount(
+      "DataReductionProxy.SavingsCleared.NegativeSystemClock", 3);
+  histogram_tester.ExpectBucketCount(
+      "DataReductionProxy.SavingsCleared.NegativeSystemClock", true, 2);
+
+  // Forward 10 days.
+  AddFakeTimeDeltaInHours(10 * 24);
+  RecordContentLengthPrefs(kReceivedLength, kOriginalLength, true,
+                           VIA_DATA_REDUCTION_PROXY, FakeNow());
+  histogram_tester.ExpectTotalCount(
+      "DataReductionProxy.SavingsCleared.NegativeSystemClock", 4);
+  histogram_tester.ExpectBucketCount(
+      "DataReductionProxy.SavingsCleared.NegativeSystemClock", false, 2);
 }
 
 TEST_F(DataReductionProxyCompressionStatsTest, NormalizeHostname) {
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc
index 4a2b45e2..5a96288 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc
@@ -282,6 +282,62 @@
   DISALLOW_COPY_AND_ASSIGN(SecureProxyChecker);
 };
 
+// URLFetcherDelegate for fetching the warmup URL.
+class WarmupURLFetcher : public net::URLFetcherDelegate {
+ public:
+  explicit WarmupURLFetcher(const scoped_refptr<net::URLRequestContextGetter>&
+                                url_request_context_getter)
+      : url_request_context_getter_(url_request_context_getter) {
+    DCHECK(url_request_context_getter_);
+  }
+
+  ~WarmupURLFetcher() override {}
+
+  // Creates and starts a URLFetcher that fetches the warmup URL.
+  void FetchWarmupURL() {
+    UMA_HISTOGRAM_EXACT_LINEAR("DataReductionProxy.WarmupURL.FetchInitiated", 1,
+                               2);
+
+    fetcher_ = net::URLFetcher::Create(params::GetWarmupURL(),
+                                       net::URLFetcher::GET, this);
+    data_use_measurement::DataUseUserData::AttachToFetcher(
+        fetcher_.get(),
+        data_use_measurement::DataUseUserData::DATA_REDUCTION_PROXY);
+    fetcher_->SetLoadFlags(net::LOAD_BYPASS_CACHE);
+    fetcher_->SetRequestContext(url_request_context_getter_.get());
+    // |fetcher| should not retry on 5xx errors.
+    fetcher_->SetAutomaticallyRetryOn5xx(false);
+    fetcher_->SetAutomaticallyRetryOnNetworkChanges(0);
+    fetcher_->Start();
+  }
+
+  void SetWarmupURLFetcherCallbackForTesting(
+      base::Callback<void()> warmup_url_fetched_callback) {
+    fetch_completion_callback_ = warmup_url_fetched_callback;
+  }
+
+ private:
+  void OnURLFetchComplete(const net::URLFetcher* source) override {
+    DCHECK_EQ(source, fetcher_.get());
+    UMA_HISTOGRAM_BOOLEAN(
+        "DataReductionProxy.WarmupURL.FetchSuccessful",
+        source->GetStatus().status() == net::URLRequestStatus::SUCCESS);
+
+    if (fetch_completion_callback_)
+      fetch_completion_callback_.Run();
+  }
+
+  scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
+
+  // The URLFetcher being used for fetching the warmup URL.
+  std::unique_ptr<net::URLFetcher> fetcher_;
+
+  // Called upon the completion of fetching of the warmup URL. May be null.
+  base::Callback<void()> fetch_completion_callback_;
+
+  DISALLOW_COPY_AND_ASSIGN(WarmupURLFetcher);
+};
+
 DataReductionProxyConfig::DataReductionProxyConfig(
     scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
     net::NetLog* net_log,
@@ -320,10 +376,16 @@
   net::NetworkChangeNotifier::RemoveIPAddressObserver(this);
 }
 
-void DataReductionProxyConfig::InitializeOnIOThread(const scoped_refptr<
-    net::URLRequestContextGetter>& url_request_context_getter) {
+void DataReductionProxyConfig::InitializeOnIOThread(
+    const scoped_refptr<net::URLRequestContextGetter>&
+        basic_url_request_context_getter,
+    const scoped_refptr<net::URLRequestContextGetter>&
+        url_request_context_getter) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+
   secure_proxy_checker_.reset(
-      new SecureProxyChecker(url_request_context_getter));
+      new SecureProxyChecker(basic_url_request_context_getter));
+  warmup_url_fetcher_.reset(new WarmupURLFetcher(url_request_context_getter));
 
   if (!config_values_->allowed())
     return;
@@ -647,6 +709,7 @@
 
   if (enabled) {
     HandleCaptivePortal();
+    FetchWarmupURL();
 
     // Check if the proxy has been restricted explicitly by the carrier.
     // It is safe to use base::Unretained here, since it gets executed
@@ -732,6 +795,8 @@
 }
 
 void DataReductionProxyConfig::OnIPAddressChanged() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+
   if (enabled_by_user_) {
     DCHECK(config_values_->allowed());
     RecordNetworkChangeEvent(IP_CHANGED);
@@ -741,6 +806,7 @@
     network_quality_at_last_query_ = NETWORK_QUALITY_AT_LAST_QUERY_UNKNOWN;
 
     HandleCaptivePortal();
+    FetchWarmupURL();
     // It is safe to use base::Unretained here, since it gets executed
     // synchronously on the IO thread, and |this| outlives
     // |secure_proxy_checker_|.
@@ -791,6 +857,23 @@
                                                      fetcher_callback);
 }
 
+void DataReductionProxyConfig::FetchWarmupURL() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+
+  if (!enabled_by_user_ || !params::FetchWarmupURLEnabled())
+    return;
+
+  warmup_url_fetcher_->FetchWarmupURL();
+}
+
+void DataReductionProxyConfig::SetWarmupURLFetcherCallbackForTesting(
+    base::Callback<void()> warmup_url_fetched_callback) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+
+  warmup_url_fetcher_->SetWarmupURLFetcherCallbackForTesting(
+      warmup_url_fetched_callback);
+}
+
 void DataReductionProxyConfig::SetLoFiModeOff() {
   DCHECK(thread_checker_.CalledOnValidThread());
   lofi_off_ = true;
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h
index 385bf60..3fe9f61 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h
@@ -51,6 +51,7 @@
 class DataReductionProxyConfigurator;
 class DataReductionProxyEventCreator;
 class SecureProxyChecker;
+class WarmupURLFetcher;
 struct DataReductionProxyTypeInfo;
 
 // Values of the UMA DataReductionProxy.ProbeURL histogram.
@@ -103,7 +104,13 @@
   ~DataReductionProxyConfig() override;
 
   // Performs initialization on the IO thread.
+  // |basic_url_request_context_getter| is the net::URLRequestContextGetter that
+  // disables the use of alternative protocols and proxies.
+  // |url_request_context_getter| is the default net::URLRequestContextGetter
+  // used for making URL requests.
   void InitializeOnIOThread(const scoped_refptr<net::URLRequestContextGetter>&
+                                basic_url_request_context_getter,
+                            const scoped_refptr<net::URLRequestContextGetter>&
                                 url_request_context_getter);
 
   // Sets the proxy configs, enabling or disabling the proxy according to
@@ -214,6 +221,10 @@
   // Updates the Data Reduction Proxy configurator with the current config.
   void UpdateConfigForTesting(bool enabled, bool restricted);
 
+  // Updates the callback that is called when the warmup URL has been fetched.
+  void SetWarmupURLFetcherCallbackForTesting(
+      base::Callback<void()> warmup_url_fetched_callback);
+
  private:
   friend class MockDataReductionProxyConfig;
   friend class TestDataReductionProxyConfig;
@@ -230,6 +241,7 @@
   FRIEND_TEST_ALL_PREFIXES(DataReductionProxyConfigTest, LoFiAccuracy);
   FRIEND_TEST_ALL_PREFIXES(DataReductionProxyConfigTest,
                            LoFiAccuracyNonZeroDelay);
+  FRIEND_TEST_ALL_PREFIXES(DataReductionProxyConfigTest, WarmupURL);
 
   // Values of the estimated network quality at the beginning of the most
   // recent query of the Network Quality Estimator.
@@ -308,8 +320,15 @@
   // for testing.
   virtual bool GetIsCaptivePortal() const;
 
+  // Fetches the warmup URL.
+  void FetchWarmupURL();
+
+  // URL fetcher used for performing the secure proxy check.
   std::unique_ptr<SecureProxyChecker> secure_proxy_checker_;
 
+  // URL fetcher used for fetching the warmup URL.
+  std::unique_ptr<WarmupURLFetcher> warmup_url_fetcher_;
+
   // Indicates if the secure Data Reduction Proxy can be used or not.
   bool secure_proxy_allowed_;
 
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.h
index 05b59b3..4198e68 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.h
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.h
@@ -118,6 +118,7 @@
   void SetIsCaptivePortal(bool is_captive_portal);
 
   using DataReductionProxyConfig::UpdateConfigForTesting;
+  using DataReductionProxyConfig::SetWarmupURLFetcherCallbackForTesting;
 
  private:
   bool GetIsCaptivePortal() const override;
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc
index 0535786..c2984bc 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc
@@ -14,10 +14,13 @@
 #include <vector>
 
 #include "base/command_line.h"
+#include "base/files/file_path.h"
+#include "base/files/file_util.h"
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/ref_counted.h"
 #include "base/metrics/field_trial.h"
+#include "base/run_loop.h"
 #include "base/strings/safe_sprintf.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
@@ -44,8 +47,10 @@
 #include "net/nqe/network_quality_estimator.h"
 #include "net/nqe/network_quality_estimator_test_util.h"
 #include "net/proxy/proxy_server.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
 #include "net/url_request/test_url_fetcher_factory.h"
 #include "net/url_request/url_fetcher.h"
+#include "net/url_request/url_request.h"
 #include "net/url_request/url_request_test_util.h"
 
 using testing::_;
@@ -167,6 +172,17 @@
         1);
   }
 
+  void WarmupURLFetchedCallBack() const {
+    warmup_url_fetched_run_loop_->Quit();
+  }
+
+  void WarmUpURLFetchedRunLoop() {
+    warmup_url_fetched_run_loop_.reset(new base::RunLoop());
+    // |warmup_url_fetched_run_loop_| will run until WarmupURLFetchedCallBack()
+    // is called.
+    warmup_url_fetched_run_loop_->Run();
+  }
+
   void RunUntilIdle() {
     test_context_->RunUntilIdle();
   }
@@ -204,6 +220,7 @@
   std::unique_ptr<net::NetworkChangeNotifier> network_change_notifier_;
 
   base::MessageLoopForIO message_loop_;
+  std::unique_ptr<base::RunLoop> warmup_url_fetched_run_loop_;
   std::unique_ptr<DataReductionProxyTestContext> test_context_;
   std::unique_ptr<TestDataReductionProxyParams> expected_params_;
 };
@@ -304,6 +321,103 @@
       FAILED_PROXY_DISABLED, std::vector<net::ProxyServer>(1, kHttpProxy));
 }
 
+// Verifies that the warm up URL is fetched correctly.
+TEST_F(DataReductionProxyConfigTest, WarmupURL) {
+  const net::URLRequestStatus kSuccess(net::URLRequestStatus::SUCCESS, net::OK);
+  const net::ProxyServer kHttpsProxy = net::ProxyServer::FromURI(
+      "https://secure_origin.net:443", net::ProxyServer::SCHEME_HTTP);
+  const net::ProxyServer kHttpProxy = net::ProxyServer::FromURI(
+      "insecure_origin.net:80", net::ProxyServer::SCHEME_HTTP);
+
+  // Set up the embedded test server from where the warm up URL will be fetched.
+  net::EmbeddedTestServer embedded_test_server;
+  embedded_test_server.AddDefaultHandlers(
+      base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest")));
+  EXPECT_TRUE(embedded_test_server.Start());
+
+  GURL warmup_url = embedded_test_server.GetURL("/simple.html");
+
+  const struct {
+    bool data_reduction_proxy_enabled;
+    bool enabled_via_field_trial;
+  } tests[] = {
+      {
+          false, false,
+      },
+      {
+          false, true,
+      },
+      {
+          true, false,
+      },
+      {
+          true, true,
+      },
+  };
+  for (const auto& test : tests) {
+    base::HistogramTester histogram_tester;
+    SetProxiesForHttpOnCommandLine({kHttpsProxy, kHttpProxy});
+
+    ResetSettings(true, true, true, false);
+
+    variations::testing::ClearAllVariationParams();
+    std::map<std::string, std::string> variation_params;
+    variation_params["enable_warmup"] =
+        test.enabled_via_field_trial ? "true" : "false";
+    variation_params["warmup_url"] = warmup_url.spec();
+
+    ASSERT_TRUE(variations::AssociateVariationParams(
+        params::GetQuicFieldTrialName(), "Enabled", variation_params));
+
+    base::FieldTrialList field_trial_list(nullptr);
+    base::FieldTrialList::CreateFieldTrial(params::GetQuicFieldTrialName(),
+                                           "Enabled");
+
+    base::CommandLine::ForCurrentProcess()->InitFromArgv(0, NULL);
+    TestDataReductionProxyConfig config(
+        DataReductionProxyParams::kAllowed |
+            DataReductionProxyParams::kFallbackAllowed,
+        TestDataReductionProxyParams::HAS_EVERYTHING, task_runner(), nullptr,
+        configurator(), event_creator());
+
+    scoped_refptr<net::URLRequestContextGetter> request_context_getter_ =
+        new net::TestURLRequestContextGetter(task_runner());
+    config.InitializeOnIOThread(request_context_getter_.get(),
+                                request_context_getter_.get());
+    config.SetWarmupURLFetcherCallbackForTesting(
+        base::Bind(&DataReductionProxyConfigTest::WarmupURLFetchedCallBack,
+                   base::Unretained(this)));
+    config.SetProxyConfig(test.data_reduction_proxy_enabled, true);
+    bool warmup_url_enabled =
+        test.data_reduction_proxy_enabled && test.enabled_via_field_trial;
+
+    if (warmup_url_enabled) {
+      // Block until warm up URL is fetched successfully.
+      WarmUpURLFetchedRunLoop();
+      histogram_tester.ExpectUniqueSample(
+          "DataReductionProxy.WarmupURL.FetchInitiated", 1, 1);
+      histogram_tester.ExpectUniqueSample(
+          "DataReductionProxy.WarmupURL.FetchSuccessful", 1, 1);
+    }
+
+    config.OnIPAddressChanged();
+
+    if (warmup_url_enabled) {
+      // Block until warm up URL is fetched successfully.
+      WarmUpURLFetchedRunLoop();
+      histogram_tester.ExpectUniqueSample(
+          "DataReductionProxy.WarmupURL.FetchInitiated", 1, 2);
+      histogram_tester.ExpectUniqueSample(
+          "DataReductionProxy.WarmupURL.FetchSuccessful", 1, 2);
+    } else {
+      histogram_tester.ExpectTotalCount(
+          "DataReductionProxy.WarmupURL.FetchInitiated", 0);
+      histogram_tester.ExpectTotalCount(
+          "DataReductionProxy.WarmupURL.FetchSuccessful", 0);
+    }
+  }
+}
+
 TEST_F(DataReductionProxyConfigTest, AreProxiesBypassed) {
   const struct {
     // proxy flags
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc
index 4a1326e..91c05f7d 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc
@@ -196,7 +196,8 @@
 
 void DataReductionProxyIOData::InitializeOnIOThread() {
   DCHECK(io_task_runner_->BelongsToCurrentThread());
-  config_->InitializeOnIOThread(basic_url_request_context_getter_.get());
+  config_->InitializeOnIOThread(basic_url_request_context_getter_.get(),
+                                url_request_context_getter_);
   bypass_stats_->InitializeOnIOThread();
   proxy_delegate_->InitializeOnIOThread();
   if (config_client_.get())
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_prefs.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_prefs.cc
index c2b2b44..b3d912c 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_prefs.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_prefs.cc
@@ -21,6 +21,8 @@
                                 false);
 
   registry->RegisterInt64Pref(prefs::kDataReductionProxyLastEnabledTime, 0L);
+  registry->RegisterInt64Pref(
+      prefs::kDataReductionProxySavingsClearedNegativeSystemClock, 0);
 
   registry->RegisterBooleanPref(prefs::kDataUsageReportingEnabled, false);
 
@@ -108,7 +110,8 @@
   registry->RegisterStringPref(prefs::kDataReductionProxy, std::string());
   registry->RegisterInt64Pref(prefs::kDataReductionProxyLastEnabledTime, 0L);
   registry->RegisterInt64Pref(
-      prefs::kHttpReceivedContentLength, 0);
+      prefs::kDataReductionProxySavingsClearedNegativeSystemClock, 0);
+  registry->RegisterInt64Pref(prefs::kHttpReceivedContentLength, 0);
   registry->RegisterInt64Pref(
       prefs::kHttpOriginalContentLength, 0);
   registry->RegisterListPref(
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.cc
index ee018ff..4e6cb86 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.cc
@@ -277,6 +277,22 @@
           (clock_->Now() - base::Time::FromInternalValue(last_enabled_time))
               .InDays());
     }
+
+    int64_t last_savings_cleared_time = prefs->GetInt64(
+        prefs::kDataReductionProxySavingsClearedNegativeSystemClock);
+    if (last_savings_cleared_time != 0) {
+      int32_t days_since_savings_cleared =
+          (clock_->Now() -
+           base::Time::FromInternalValue(last_savings_cleared_time))
+              .InDays();
+
+      // Sample in the UMA histograms must be at least 1.
+      if (days_since_savings_cleared == 0)
+        days_since_savings_cleared = 1;
+      UMA_HISTOGRAM_CUSTOM_COUNTS(
+          "DataReductionProxy.DaysSinceSavingsCleared.NegativeSystemClock",
+          days_since_savings_cleared, 1, 365, 50);
+    }
   }
 
   if (spdy_proxy_auth_enabled_.GetValue() &&
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h
index 513a797..f522542 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h
@@ -270,6 +270,8 @@
                            TestDaysSinceEnabledWithTestClock);
   FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
                            TestDaysSinceEnabledExistingUser);
+  FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
+                           TestDaysSinceSavingsCleared);
 
   // Override of DataReductionProxyService::Observer.
   void OnServiceInitialized() override;
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_unittest.cc
index 52566c0d..dd162d19 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_settings_unittest.cc
@@ -731,6 +731,32 @@
                    prefs::kDataReductionProxyLastEnabledTime));
 }
 
+TEST_F(DataReductionProxySettingsTest, TestDaysSinceSavingsCleared) {
+  std::unique_ptr<base::SimpleTestClock> clock(new base::SimpleTestClock());
+  base::SimpleTestClock* clock_ptr = clock.get();
+  clock_ptr->Advance(base::TimeDelta::FromDays(1));
+  ResetSettings(std::move(clock), true, true, false, false);
+
+  InitPrefMembers();
+  base::HistogramTester histogram_tester;
+  test_context_->pref_service()->SetInt64(
+      prefs::kDataReductionProxySavingsClearedNegativeSystemClock,
+      clock_ptr->Now().ToInternalValue());
+
+  settings_->data_reduction_proxy_service_->SetIOData(
+      test_context_->io_data()->GetWeakPtr());
+  test_context_->RunUntilIdle();
+
+  clock_ptr->Advance(base::TimeDelta::FromDays(100));
+
+  // Simulate Chromium startup with data reduction proxy already enabled.
+  settings_->spdy_proxy_auth_enabled_.SetValue(true);
+  settings_->MaybeActivateDataReductionProxy(true /* at_startup */);
+  test_context_->RunUntilIdle();
+  histogram_tester.ExpectUniqueSample(
+      "DataReductionProxy.DaysSinceSavingsCleared.NegativeSystemClock", 100, 1);
+}
+
 TEST_F(DataReductionProxySettingsTest, TestGetDailyContentLengths) {
   ContentLengthList result =
       settings_->GetDailyContentLengths(prefs::kDailyHttpOriginalContentLength);
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 f4c28f4..84f14ec 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
@@ -33,7 +33,7 @@
     "http://o-o.preferred.nttdocomodcp-hnd1.proxy-dev.googlezip.net:80";
 const char kDefaultFallbackOrigin[] = "compress.googlezip.net:80";
 const char kDefaultSecureProxyCheckUrl[] = "http://check.googlezip.net/connect";
-const char kDefaultWarmupUrl[] = "http://www.gstatic.com/generate_204";
+const char kDefaultWarmupUrl[] = "http://check.googlezip.net/generate_204";
 
 const char kAndroidOneIdentifier[] = "sprout";
 
@@ -138,6 +138,29 @@
              "TamperDetection_Enabled", base::CompareCase::SENSITIVE);
 }
 
+bool FetchWarmupURLEnabled() {
+  // Fetching of the warmup URL can be enabled only for Enabled* and Control*
+  // groups.
+  if (!base::StartsWith(FieldTrialList::FindFullName(kQuicFieldTrial), kEnabled,
+                        base::CompareCase::SENSITIVE) &&
+      !base::StartsWith(FieldTrialList::FindFullName(kQuicFieldTrial), kControl,
+                        base::CompareCase::SENSITIVE)) {
+    return false;
+  }
+
+  std::map<std::string, std::string> params;
+  variations::GetVariationParams(GetQuicFieldTrialName(), &params);
+  return GetStringValueForVariationParamWithDefaultValue(
+             params, "enable_warmup", "false") == "true";
+}
+
+GURL GetWarmupURL() {
+  std::map<std::string, std::string> params;
+  variations::GetVariationParams(GetQuicFieldTrialName(), &params);
+  return GURL(GetStringValueForVariationParamWithDefaultValue(
+      params, "warmup_url", kDefaultWarmupUrl));
+}
+
 bool IsLoFiOnViaFlags() {
   return IsLoFiAlwaysOnViaFlags() || IsLoFiCellularOnlyViaFlags() ||
          IsLoFiSlowConnectionsOnlyViaFlags();
@@ -427,8 +450,6 @@
     fallback_origin = GetDefaultFallbackOrigin();
   if (secure_proxy_check_url.empty())
     secure_proxy_check_url = GetDefaultSecureProxyCheckURL();
-  if (warmup_url.empty())
-    warmup_url = GetDefaultWarmupURL();
 
   origin_ = net::ProxyServer::FromURI(origin, net::ProxyServer::SCHEME_HTTP);
   fallback_origin_ =
@@ -439,7 +460,6 @@
     proxies_for_http_.push_back(fallback_origin_);
 
   secure_proxy_check_url_ = GURL(secure_proxy_check_url);
-  warmup_url_ = GURL(warmup_url);
 }
 
 const std::vector<net::ProxyServer>&
@@ -495,8 +515,5 @@
   return kDefaultSecureProxyCheckUrl;
 }
 
-std::string DataReductionProxyParams::GetDefaultWarmupURL() const {
-  return kDefaultWarmupUrl;
-}
 
 }  // namespace data_reduction_proxy
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 4aea4d5c..bfdf16e 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
@@ -148,6 +148,12 @@
 // Returns the name of the server side experiment field trial.
 const char* GetServerExperimentsFieldTrialName();
 
+// Returns true if fetching of the warmup URL is enabled.
+bool FetchWarmupURLEnabled();
+
+// Returns the warmup URL.
+GURL GetWarmupURL();
+
 }  // namespace params
 
 // Contains information about a given proxy server. |proxies_for_http| contains
@@ -222,7 +228,6 @@
   virtual std::string GetDefaultOrigin() const;
   virtual std::string GetDefaultFallbackOrigin() const;
   virtual std::string GetDefaultSecureProxyCheckURL() const;
-  virtual std::string GetDefaultWarmupURL() const;
 
   std::vector<net::ProxyServer> proxies_for_http_;
 
@@ -231,7 +236,6 @@
   net::ProxyServer fallback_origin_;
 
   GURL secure_proxy_check_url_;
-  GURL warmup_url_;
 
   bool allowed_;
   bool fallback_allowed_;
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_params_unittest.cc b/components/data_reduction_proxy/core/common/data_reduction_proxy_params_unittest.cc
index 716e02a1..e849b0d 100644
--- a/components/data_reduction_proxy/core/common/data_reduction_proxy_params_unittest.cc
+++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_params_unittest.cc
@@ -377,20 +377,31 @@
     bool expected_enabled;
     std::string zero_rtt_param;
     bool expected_zero_rtt;
+    bool enable_warmup_url;
+    bool expect_warmup_url_enabled;
+    std::string warmup_url;
   } tests[] = {
-      {"Enabled", true, "true", true},
-      {"Enabled_Control", true, "true", true},
-      {"Enabled_Control", true, "false", false},
-      {"Enabled_Control", true, std::string(), false},
-      {"Control", false, "true", false},
-      {"Disabled", false, "false", false},
-      {"enabled", false, "false", false},
+      {"Enabled", true, "true", true, true, true, std::string()},
+      {"Enabled", true, "true", true, false, false, std::string()},
+      {"Enabled_Control", true, "true", true, true, true, std::string()},
+      {"Enabled_Control", true, "false", false, true, true, std::string()},
+      {"Enabled_Control", true, std::string(), false, true, true,
+       std::string()},
+      {"Control", false, "true", false, true, true, std::string()},
+      {"Disabled", false, "false", false, true, false, std::string()},
+      {"enabled", false, "false", false, true, false, std::string()},
+      {"Enabled", true, "true", true, true, true, "example.com/test.html"},
   };
 
   for (const auto& test : tests) {
     variations::testing::ClearAllVariationParams();
     std::map<std::string, std::string> variation_params;
     variation_params["enable_zero_rtt"] = test.zero_rtt_param;
+    if (test.enable_warmup_url)
+      variation_params["enable_warmup"] = "true";
+
+    if (!test.warmup_url.empty())
+      variation_params["warmup_url"] = test.warmup_url;
     ASSERT_TRUE(variations::AssociateVariationParams(
         params::GetQuicFieldTrialName(), test.trial_group_name,
         variation_params));
@@ -401,6 +412,13 @@
 
     EXPECT_EQ(test.expected_enabled, params::IsIncludedInQuicFieldTrial());
     EXPECT_EQ(test.expected_zero_rtt, params::IsZeroRttQuicEnabled());
+    if (!test.warmup_url.empty()) {
+      EXPECT_EQ(GURL(test.warmup_url), params::GetWarmupURL());
+    } else {
+      EXPECT_EQ(GURL("http://check.googlezip.net/generate_204"),
+                params::GetWarmupURL());
+    }
+    EXPECT_EQ(test.expect_warmup_url_enabled, params::FetchWarmupURLEnabled());
   }
 }
 
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.cc b/components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.cc
index cd72646..0ac6d04 100644
--- a/components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.cc
+++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.cc
@@ -191,6 +191,11 @@
 const char kDataReductionProxyLastEnabledTime[] =
     "data_reduction.last_enabled_time";
 
+// An integer pref that contains the time when the data reduction proxy savings
+// were last cleared because the system clock was moved back by more than 1 day.
+const char kDataReductionProxySavingsClearedNegativeSystemClock[] =
+    "data_reduction.savings_cleared_negative_system_clock";
+
 // An int64_t pref that contains the total size of all HTTP content received
 // from the network.
 const char kHttpReceivedContentLength[] = "http_received_content_length";
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.h b/components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.h
index 65c93b2b..e67a082 100644
--- a/components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.h
+++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.h
@@ -48,6 +48,7 @@
 extern const char kDataUsageReportingEnabled[];
 extern const char kDataReductionProxyWasEnabledBefore[];
 extern const char kDataReductionProxyLastEnabledTime[];
+extern const char kDataReductionProxySavingsClearedNegativeSystemClock[];
 extern const char kHttpOriginalContentLength[];
 extern const char kHttpReceivedContentLength[];
 extern const char kLoFiImplicitOptOutEpoch[];
diff --git a/components/data_use_measurement/core/data_use_measurement_unittest.cc b/components/data_use_measurement/core/data_use_measurement_unittest.cc
index 707577b..31a2784 100644
--- a/components/data_use_measurement/core/data_use_measurement_unittest.cc
+++ b/components/data_use_measurement/core/data_use_measurement_unittest.cc
@@ -41,9 +41,21 @@
   }
 };
 
+// The more usual initialization of kUserDataKey would be along the lines of
+//     const void* const UserRequestUserDataForTesting::kUserDataKey =
+//         &UserRequestUserDataForTesting::kUserDataKey;
+// but lld's identical constant folding then folds that with
+// DataUseUserData::kUserDataKey which is initialized like that as well, and
+// then UserRequestUserDataForTesting::IsUserRequest() starts classifying
+// service requests as user requests.  To work around this, make
+// UserRequestUserDataForTesting::kUserDataKey point to an arbitrary integer
+// instead.
+// TODO(thakis): If we changed lld to only ICF over code and not over data,
+// we could undo this again.
+const int kICFBuster = 12345634;
+
 // static
-const void* const UserRequestUserDataForTesting::kUserDataKey =
-    &UserRequestUserDataForTesting::kUserDataKey;
+const void* const UserRequestUserDataForTesting::kUserDataKey = &kICFBuster;
 
 class DataUseMeasurementTest : public testing::Test {
  public:
diff --git a/components/display_compositor/compositor_overlay_candidate_validator_android.cc b/components/display_compositor/compositor_overlay_candidate_validator_android.cc
index b5b1c130..a42d035 100644
--- a/components/display_compositor/compositor_overlay_candidate_validator_android.cc
+++ b/components/display_compositor/compositor_overlay_candidate_validator_android.cc
@@ -37,7 +37,7 @@
 
     // This quad either will be promoted, or would be if it were backed by a
     // SurfaceView.  Record that it should get a promotion hint.
-    candidates->promotable_resource_hints_.insert(candidate.resource_id);
+    candidates->AddPromotionHint(candidate);
 
     if (candidate.is_backed_by_surface_texture) {
       // This quad would be promoted if it were backed by a SurfaceView.  Since
diff --git a/components/feedback/feedback_uploader_chrome.cc b/components/feedback/feedback_uploader_chrome.cc
index 0de322a..9b3cb82e 100644
--- a/components/feedback/feedback_uploader_chrome.cc
+++ b/components/feedback/feedback_uploader_chrome.cc
@@ -60,8 +60,12 @@
       fetcher, data_use_measurement::DataUseUserData::FEEDBACK_UPLOADER);
   // Tell feedback server about the variation state of this install.
   net::HttpRequestHeaders headers;
-  variations::AppendVariationHeaders(
-      fetcher->GetOriginalURL(), context_->IsOffTheRecord(), false, &headers);
+  // Note: It's fine to pass in |is_signed_in| false, which does not affect
+  // transmission of experiment ids coming from the variations server.
+  bool is_signed_in = false;
+  variations::AppendVariationHeaders(fetcher->GetOriginalURL(),
+                                     context_->IsOffTheRecord(), false,
+                                     is_signed_in, &headers);
   fetcher->SetExtraRequestHeaders(headers.ToString());
 
   fetcher->SetUploadData(kProtoBufMimeType, data);
diff --git a/components/ntp_snippets/remote/ntp_snippets_fetcher.cc b/components/ntp_snippets/remote/ntp_snippets_fetcher.cc
index 360d476..50dcf780 100644
--- a/components/ntp_snippets/remote/ntp_snippets_fetcher.cc
+++ b/components/ntp_snippets/remote/ntp_snippets_fetcher.cc
@@ -691,10 +691,13 @@
     headers.SetHeader("Authorization", auth_header_);
   }
   // Add X-Client-Data header with experiment IDs from field trials.
+  // Note: It's fine to pass in |is_signed_in| false, which does not affect
+  // transmission of experiment ids coming from the variations server.
+  bool is_signed_in = false;
   variations::AppendVariationHeaders(url_,
                                      false,  // incognito
                                      false,  // uma_enabled
-                                     &headers);
+                                     is_signed_in, &headers);
   return headers.ToString();
 }
 
diff --git a/components/omnibox/browser/omnibox_field_trial.cc b/components/omnibox/browser/omnibox_field_trial.cc
index cbcf6f6..371c7626 100644
--- a/components/omnibox/browser/omnibox_field_trial.cc
+++ b/components/omnibox/browser/omnibox_field_trial.cc
@@ -371,33 +371,21 @@
   }
 }
 
-bool OmniboxFieldTrial::HQPExperimentalScoringEnabled() {
-  return variations::GetVariationParamValue(
-      kBundledExperimentFieldTrialName,
-      kHQPExperimentalScoringEnabledParam) == "true";
-}
-
 std::string OmniboxFieldTrial::HQPExperimentalScoringBuckets() {
-  if (!HQPExperimentalScoringEnabled())
-    return "";
-
   return variations::GetVariationParamValue(
       kBundledExperimentFieldTrialName,
       kHQPExperimentalScoringBucketsParam);
 }
 
 float OmniboxFieldTrial::HQPExperimentalTopicalityThreshold() {
-  if (!HQPExperimentalScoringEnabled())
-    return -1;
-
-  std::string topicality_threhold_str =
-    variations::GetVariationParamValue(
-        kBundledExperimentFieldTrialName,
-        kHQPExperimentalScoringTopicalityThresholdParam);
+  std::string topicality_threshold_str = variations::GetVariationParamValue(
+      kBundledExperimentFieldTrialName,
+      kHQPExperimentalScoringTopicalityThresholdParam);
 
   double topicality_threshold;
-  if (!base::StringToDouble(topicality_threhold_str, &topicality_threshold))
-    return -1;
+  if (topicality_threshold_str.empty() ||
+      !base::StringToDouble(topicality_threshold_str, &topicality_threshold))
+    return 0.8f;
 
   return static_cast<float>(topicality_threshold);
 }
@@ -580,8 +568,6 @@
 const char OmniboxFieldTrial::kHUPNewScoringVisitedCountUseDecayFactorParam[] =
     "VisitedCountUseDecayFactor";
 
-const char OmniboxFieldTrial::kHQPExperimentalScoringEnabledParam[] =
-    "HQPExperimentalScoringEnabled";
 const char OmniboxFieldTrial::kHQPExperimentalScoringBucketsParam[] =
     "HQPExperimentalScoringBuckets";
 const char
diff --git a/components/omnibox/browser/omnibox_field_trial.h b/components/omnibox/browser/omnibox_field_trial.h
index c4c6afe7..ff72ad1f 100644
--- a/components/omnibox/browser/omnibox_field_trial.h
+++ b/components/omnibox/browser/omnibox_field_trial.h
@@ -270,22 +270,15 @@
   // For HQP scoring related experiments to control the topicality and scoring
   // ranges of relevancy scores.
 
-  // Returns true if HQP experimental scoring is enabled. Returns false if
-  // |kHQPExperimentalScoringEnabledParam| is not specified in the field trial.
-  static bool HQPExperimentalScoringEnabled();
-
-  // Returns the scoring buckets for HQP experiments. Returns empty string
-  // in case |kHQPExperimentalScoringBucketsParam| or
-  // |kHQPExperimentalScoringEnabledParam| is not specified in the
-  // field trial. Scoring buckets are stored in string form giving mapping from
-  // (topicality_score, frequency_score) to final relevance score.
-  // Please see GetRelevancyScore() under
-  // chrome/browser/history::ScoredHistoryMatch for details.
+  // Returns the scoring buckets for HQP experiments. Returns an empty string
+  // if scoring buckets are not specified in the field trial. Scoring buckets
+  // are stored in string form giving mapping from (topicality_score,
+  // frequency_score) to final relevance score. Please see GetRelevancyScore()
+  // under chrome/browser/history::ScoredHistoryMatch for details.
   static std::string HQPExperimentalScoringBuckets();
 
-  // Returns the topicality threshold for HQP experiments. Returns -1 if
-  // |kHQPExperimentalScoringTopicalityThresholdParam| or
-  // |kHQPExperimentalScoringEnabledParam| is not specified in the field trial.
+  // Returns the topicality threshold for HQP experiments. Returns a default
+  // value of 0.8 if no threshold is specified in the field trial.
   static float HQPExperimentalTopicalityThreshold();
 
   // ---------------------------------------------------------
@@ -411,7 +404,6 @@
   static const char kHUPNewScoringVisitedCountUseDecayFactorParam[];
 
   // Parameter names used by the HQP experimental scoring experiments.
-  static const char kHQPExperimentalScoringEnabledParam[];
   static const char kHQPExperimentalScoringBucketsParam[];
   static const char kHQPExperimentalScoringTopicalityThresholdParam[];
 
diff --git a/components/omnibox/browser/scored_history_match.cc b/components/omnibox/browser/scored_history_match.cc
index bdde8e5..8e88bfa 100644
--- a/components/omnibox/browser/scored_history_match.cc
+++ b/components/omnibox/browser/scored_history_match.cc
@@ -10,6 +10,7 @@
 #include <vector>
 
 #include "base/logging.h"
+#include "base/macros.h"
 #include "base/numerics/safe_conversions.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_split.h"
@@ -113,17 +114,9 @@
 bool ScoredHistoryMatch::allow_tld_matches_;
 bool ScoredHistoryMatch::allow_scheme_matches_;
 size_t ScoredHistoryMatch::num_title_words_to_allow_;
-bool ScoredHistoryMatch::hqp_experimental_scoring_enabled_;
-
-// Default topicality threshold.  See GetTopicalityScore() for details.
-float ScoredHistoryMatch::topicality_threshold_ = 0.8f;
-
-// Default HQP relevance buckets. See GetFinalRelevancyScore() for more details
-// on these numbers.
-char ScoredHistoryMatch::hqp_relevance_buckets_str_[] =
-    "0.0:400,1.5:600,5.0:900,10.5:1203,15.0:1300,20.0:1399";
-std::vector<ScoredHistoryMatch::ScoreMaxRelevance>*
-    ScoredHistoryMatch::hqp_relevance_buckets_ = nullptr;
+float ScoredHistoryMatch::topicality_threshold_;
+ScoredHistoryMatch::ScoreMaxRelevances*
+    ScoredHistoryMatch::relevance_buckets_override_ = nullptr;
 
 ScoredHistoryMatch::ScoredHistoryMatch()
     : ScoredHistoryMatch(history::URLRow(),
@@ -261,8 +254,8 @@
   const float topicality_score = GetTopicalityScore(
       terms_vector.size(), url, terms_to_word_starts_offsets, word_starts);
   const float frequency_score = GetFrequency(now, is_url_bookmarked, visits);
-  raw_score = base::saturated_cast<int>(GetFinalRelevancyScore(
-      topicality_score, frequency_score, *hqp_relevance_buckets_));
+  raw_score = base::saturated_cast<int>(
+      GetFinalRelevancyScore(topicality_score, frequency_score));
 
   if (also_do_hup_like_scoring_ && likely_can_inline) {
     // HistoryURL-provider-like scoring gives any match that is
@@ -415,10 +408,11 @@
   allow_tld_matches_ = OmniboxFieldTrial::HQPAllowMatchInTLDValue();
   allow_scheme_matches_ = OmniboxFieldTrial::HQPAllowMatchInSchemeValue();
   num_title_words_to_allow_ = OmniboxFieldTrial::HQPNumTitleWordsToAllow();
+  topicality_threshold_ =
+      OmniboxFieldTrial::HQPExperimentalTopicalityThreshold();
 
   InitRawTermScoreToTopicalityScoreArray();
   InitDaysAgoToRecencyScoreArray();
-  InitHQPExperimentalParams();
 }
 
 float ScoredHistoryMatch::GetTopicalityScore(
@@ -617,12 +611,17 @@
 }
 
 // static
-float ScoredHistoryMatch::GetFinalRelevancyScore(
-    float topicality_score,
-    float frequency_score,
-    const std::vector<ScoreMaxRelevance>& hqp_relevance_buckets) {
-  DCHECK(hqp_relevance_buckets.size() > 0);
-  DCHECK_EQ(hqp_relevance_buckets[0].first, 0.0);
+float ScoredHistoryMatch::GetFinalRelevancyScore(float topicality_score,
+                                                 float frequency_score) {
+  // |relevance_buckets| gives a mapping from intemerdiate score to the final
+  // relevance score.
+  CR_DEFINE_STATIC_LOCAL(ScoreMaxRelevances, default_relevance_buckets,
+                         (GetHQPBuckets()));
+  ScoreMaxRelevances* relevance_buckets = relevance_buckets_override_
+                                              ? relevance_buckets_override_
+                                              : &default_relevance_buckets;
+  DCHECK(!relevance_buckets->empty());
+  DCHECK_EQ(0.0, (*relevance_buckets)[0].first);
 
   if (topicality_score == 0)
     return 0;
@@ -642,7 +641,7 @@
   //
   // The below code maps intermediate_score to the range [0, 1399].
   // For example:
-  // HQP default scoring buckets: "0.0:400,1.5:600,12.0:1300,20.0:1399"
+  // The default scoring buckets: "0.0:400,1.5:600,12.0:1300,20.0:1399"
   // We will linearly interpolate the scores between:
   //      0 to 1.5    --> 400 to 600
   //    1.5 to 12.0   --> 600 to 1300
@@ -655,76 +654,52 @@
 
   // Find the threshold where intermediate score is greater than bucket.
   size_t i = 1;
-  for (; i < hqp_relevance_buckets.size(); ++i) {
-    const ScoreMaxRelevance& hqp_bucket = hqp_relevance_buckets[i];
-    if (intermediate_score >= hqp_bucket.first) {
+  for (; i < relevance_buckets->size(); ++i) {
+    const ScoreMaxRelevance& bucket = (*relevance_buckets)[i];
+    if (intermediate_score >= bucket.first) {
       continue;
     }
-    const ScoreMaxRelevance& previous_bucket = hqp_relevance_buckets[i - 1];
-    const float slope = ((hqp_bucket.second - previous_bucket.second) /
-                         (hqp_bucket.first - previous_bucket.first));
+    const ScoreMaxRelevance& previous_bucket = (*relevance_buckets)[i - 1];
+    const float slope = ((bucket.second - previous_bucket.second) /
+                         (bucket.first - previous_bucket.first));
     return (previous_bucket.second +
             (slope * (intermediate_score - previous_bucket.first)));
   }
   // It will reach this stage when the score is > highest bucket score.
   // Return the highest bucket score.
-  return hqp_relevance_buckets[i - 1].second;
+  return (*relevance_buckets)[i - 1].second;
 }
 
 // static
-void ScoredHistoryMatch::InitHQPExperimentalParams() {
-  // These are default HQP relevance scoring buckets.
-  // See GetFinalRelevancyScore() for details.
-  std::string hqp_relevance_buckets_str = std::string(
-      hqp_relevance_buckets_str_);
-
-  // Fetch the experiment params if they are any.
-  hqp_experimental_scoring_enabled_ =
-      OmniboxFieldTrial::HQPExperimentalScoringEnabled();
-
-  if (hqp_experimental_scoring_enabled_) {
-    // Add the topicality threshold from experiment params.
-    float hqp_experimental_topicality_threhold =
-        OmniboxFieldTrial::HQPExperimentalTopicalityThreshold();
-    topicality_threshold_ = hqp_experimental_topicality_threhold;
-
-    // Add the HQP experimental scoring buckets.
-    std::string hqp_experimental_scoring_buckets =
-        OmniboxFieldTrial::HQPExperimentalScoringBuckets();
-    if (!hqp_experimental_scoring_buckets.empty())
-      hqp_relevance_buckets_str = hqp_experimental_scoring_buckets;
-  }
-
-  // Parse the hqp_relevance_buckets_str string once and store them in vector
-  // which is easy to access.
-  hqp_relevance_buckets_ =
-      new std::vector<ScoredHistoryMatch::ScoreMaxRelevance>();
-
-  bool is_valid_bucket_str = GetHQPBucketsFromString(hqp_relevance_buckets_str,
-                                                     hqp_relevance_buckets_);
-  DCHECK(is_valid_bucket_str);
+std::vector<ScoredHistoryMatch::ScoreMaxRelevance>
+ScoredHistoryMatch::GetHQPBuckets() {
+  // Start with the default buckets and override them if appropriate.
+  std::string relevance_buckets_str =
+      "0.0:400,1.5:600,5.0:900,10.5:1203,15.0:1300,20.0:1399";
+  std::string experimental_scoring_buckets =
+      OmniboxFieldTrial::HQPExperimentalScoringBuckets();
+  if (!experimental_scoring_buckets.empty())
+    relevance_buckets_str = experimental_scoring_buckets;
+  return GetHQPBucketsFromString(relevance_buckets_str);
 }
 
 // static
-bool ScoredHistoryMatch::GetHQPBucketsFromString(
-    const std::string& buckets_str,
-    std::vector<ScoreMaxRelevance>* hqp_buckets) {
-  DCHECK(hqp_buckets != NULL);
+ScoredHistoryMatch::ScoreMaxRelevances
+ScoredHistoryMatch::GetHQPBucketsFromString(const std::string& buckets_str) {
   DCHECK(!buckets_str.empty());
-
   base::StringPairs kv_pairs;
-  if (base::SplitStringIntoKeyValuePairs(buckets_str, ':', ',', &kv_pairs)) {
-    for (base::StringPairs::const_iterator it = kv_pairs.begin();
-         it != kv_pairs.end(); ++it) {
-      ScoreMaxRelevance bucket;
-      bool is_valid_intermediate_score =
-          base::StringToDouble(it->first, &bucket.first);
-      DCHECK(is_valid_intermediate_score);
-      bool is_valid_hqp_score = base::StringToInt(it->second, &bucket.second);
-      DCHECK(is_valid_hqp_score);
-      hqp_buckets->push_back(bucket);
-    }
-    return true;
+  if (!base::SplitStringIntoKeyValuePairs(buckets_str, ':', ',', &kv_pairs))
+    return ScoreMaxRelevances();
+  ScoreMaxRelevances hqp_buckets;
+  for (base::StringPairs::const_iterator it = kv_pairs.begin();
+       it != kv_pairs.end(); ++it) {
+    ScoreMaxRelevance bucket;
+    bool is_valid_intermediate_score =
+        base::StringToDouble(it->first, &bucket.first);
+    DCHECK(is_valid_intermediate_score);
+    bool is_valid_hqp_score = base::StringToInt(it->second, &bucket.second);
+    DCHECK(is_valid_hqp_score);
+    hqp_buckets.push_back(bucket);
   }
-  return false;
+  return hqp_buckets;
 }
diff --git a/components/omnibox/browser/scored_history_match.h b/components/omnibox/browser/scored_history_match.h
index dacd31ce..a58c62a 100644
--- a/components/omnibox/browser/scored_history_match.h
+++ b/components/omnibox/browser/scored_history_match.h
@@ -24,9 +24,14 @@
 struct ScoredHistoryMatch : public history::HistoryMatch {
   // ScoreMaxRelevance maps from an intermediate-score to the maximum
   // final-relevance score given to a URL for this intermediate score.
-  // This is used to store the score ranges of HQP relevance buckets.
+  // This is used to store the score ranges of relevance buckets.
   // Please see GetFinalRelevancyScore() for details.
-  typedef std::pair<double, int> ScoreMaxRelevance;
+  using ScoreMaxRelevance = std::pair<double, int>;
+
+  // A sorted vector of ScoreMaxRelevance entries, used by taking a score and
+  // interpolating between consecutive buckets.  See GetFinalRelevancyScore()
+  // for details.
+  using ScoreMaxRelevances = std::vector<ScoreMaxRelevance>;
 
   // Required for STL, we don't use this directly.
   ScoredHistoryMatch();
@@ -128,29 +133,22 @@
                      const bool bookmarked,
                      const VisitInfoVector& visits) const;
 
-  // Combines the two component scores into a final score that's
-  // an appropriate value to use as a relevancy score. Scoring buckets are
-  // specified through |hqp_relevance_buckets|. Please see the function
-  // implementation for more details.
-  static float GetFinalRelevancyScore(
-      float topicality_score,
-      float frequency_score,
-      const std::vector<ScoreMaxRelevance>& hqp_relevance_buckets);
+  // Combines the two component scores into a final score that's an appropriate
+  // value to use as a relevancy score.
+  static float GetFinalRelevancyScore(float topicality_score,
+                                      float frequency_score);
 
-  // Initializes the HQP experimental params: |hqp_relevance_buckets_|
-  // to default buckets. If hqp experimental scoring is enabled, it
-  // fetches the |hqp_experimental_scoring_enabled_|, |topicality_threshold_|
-  // and |hqp_relevance_buckets_| from omnibox field trials.
-  static void InitHQPExperimentalParams();
+  // Helper function that returns the string containing the scoring buckets
+  // (either the default ones or ones specified in an experiment).
+  static ScoreMaxRelevances GetHQPBuckets();
 
-  // Helper function to parse the string containing the scoring buckets.
-  // For example,
-  // String: "0.0:400,1.5:600,12.0:1300,20.0:1399"
-  // Buckets: vector[(0.0, 400),(1.5,600),(12.0,1300),(20.0,1399)]
-  // Returns false, in case if it fail to parse the string.
-  static bool GetHQPBucketsFromString(
-      const std::string& buckets_str,
-      std::vector<ScoreMaxRelevance>* hqp_buckets);
+  // Helper function to parse the string containing the scoring buckets and
+  // return the results.  For example, with |buckets_str| as
+  // "0.0:400,1.5:600,12.0:1300,20.0:1399", it returns [(0.0, 400), (1.5, 600),
+  // (12.0, 1300), (20.0, 1399)]. It returns an empty vector in the case of a
+  // malformed |buckets_str|.
+  static ScoreMaxRelevances GetHQPBucketsFromString(
+      const std::string& buckets_str);
 
   // If true, assign raw scores to be max(whatever it normally would be, a
   // score that's similar to the score HistoryURL provider would assign).
@@ -184,22 +182,15 @@
   // Words beyond this number are ignored.
   static size_t num_title_words_to_allow_;
 
-  // True, if hqp experimental scoring is enabled.
-  static bool hqp_experimental_scoring_enabled_;
-
   // |topicality_threshold_| is used to control the topicality scoring.
-  // If |topicality_threshold_| > 0, then URLs with topicality-score < threshold
-  // are given topicality score of 0. By default it is initalized to -1.
+  // If |topicality_threshold_| > 0, then URLs with topicality-score less than
+  // the threshold are given topicality score of 0.
   static float topicality_threshold_;
 
-  // |hqp_relevance_buckets_str_| is used to control the hqp score ranges.
-  // It is the string representation of |hqp_relevance_buckets_|.
-  static char hqp_relevance_buckets_str_[];
-
-  // |hqp_relevance_buckets_| gives mapping from (topicality*frequency)
-  // to the final relevance scoring. Please see GetFinalRelevancyScore()
-  // for more details and scoring method.
-  static std::vector<ScoreMaxRelevance>* hqp_relevance_buckets_;
+  // Used for testing.  A possibly null pointer to a vector.  If set,
+  // overrides the static local variable |relevance_buckets| declared in
+  // GetFinalRelevancyScore().
+  static ScoreMaxRelevances* relevance_buckets_override_;
 };
 typedef std::vector<ScoredHistoryMatch> ScoredHistoryMatches;
 
diff --git a/components/omnibox/browser/scored_history_match_unittest.cc b/components/omnibox/browser/scored_history_match_unittest.cc
index 1f416e4..06400b2 100644
--- a/components/omnibox/browser/scored_history_match_unittest.cc
+++ b/components/omnibox/browser/scored_history_match_unittest.cc
@@ -647,54 +647,51 @@
 
 // Test the function GetFinalRelevancyScore().
 TEST_F(ScoredHistoryMatchTest, GetFinalRelevancyScore) {
-  // hqp_relevance_buckets = "0.0:100,1.0:200,4.0:500,8.0:900,10.0:1000";
-  std::vector<ScoredHistoryMatch::ScoreMaxRelevance> hqp_buckets;
-  hqp_buckets.push_back(std::make_pair(0.0, 100));
-  hqp_buckets.push_back(std::make_pair(1.0, 200));
-  hqp_buckets.push_back(std::make_pair(4.0, 500));
-  hqp_buckets.push_back(std::make_pair(8.0, 900));
-  hqp_buckets.push_back(std::make_pair(10.0, 1000));
+  // relevance_buckets = "0.0:100,1.0:200,4.0:500,8.0:900,10.0:1000";
+  ScoredHistoryMatch::ScoreMaxRelevances relevance_buckets = {
+      {0.0, 100}, {1.0, 200}, {4.0, 500}, {8.0, 900}, {10.0, 1000}};
+  base::AutoReset<ScoredHistoryMatch::ScoreMaxRelevances*> tmp(
+      &ScoredHistoryMatch::relevance_buckets_override_, &relevance_buckets);
+
   // Check when topicality score is zero.
   float topicality_score = 0.0;
   float frequency_score = 10.0;
   // intermediate_score = 0.0 * 10.0 = 0.0.
-  EXPECT_EQ(0, ScoredHistoryMatch::GetFinalRelevancyScore(
-                   topicality_score, frequency_score, hqp_buckets));
+  EXPECT_EQ(0, ScoredHistoryMatch::GetFinalRelevancyScore(topicality_score,
+                                                          frequency_score));
 
   // Check when intermediate score falls at the border range.
   topicality_score = 0.4f;
   frequency_score = 10.0f;
   // intermediate_score = 0.5 * 10.0 = 4.0.
-  EXPECT_EQ(500, ScoredHistoryMatch::GetFinalRelevancyScore(
-                     topicality_score, frequency_score, hqp_buckets));
+  EXPECT_EQ(500, ScoredHistoryMatch::GetFinalRelevancyScore(topicality_score,
+                                                            frequency_score));
 
   // Checking the score that falls into one of the buckets.
   topicality_score = 0.5f;
   frequency_score = 10.0f;
   // intermediate_score = 0.5 * 10.0 = 5.0.
   EXPECT_EQ(600,  // 500 + (((900 - 500)/(8 -4)) * 1) = 600.
-            ScoredHistoryMatch::GetFinalRelevancyScore(
-                topicality_score, frequency_score, hqp_buckets));
+            ScoredHistoryMatch::GetFinalRelevancyScore(topicality_score,
+                                                       frequency_score));
 
   // Never give the score greater than maximum specified.
   topicality_score = 0.5f;
   frequency_score = 22.0f;
   // intermediate_score = 0.5 * 22.0 = 11.0
-  EXPECT_EQ(1000, ScoredHistoryMatch::GetFinalRelevancyScore(
-                      topicality_score, frequency_score, hqp_buckets));
+  EXPECT_EQ(1000, ScoredHistoryMatch::GetFinalRelevancyScore(topicality_score,
+                                                             frequency_score));
 }
 
 // Test the function GetHQPBucketsFromString().
 TEST_F(ScoredHistoryMatchTest, GetHQPBucketsFromString) {
   std::string buckets_str = "0.0:400,1.5:600,12.0:1300,20.0:1399";
-  std::vector<ScoredHistoryMatch::ScoreMaxRelevance> hqp_buckets;
-
-  EXPECT_TRUE(
-      ScoredHistoryMatch::GetHQPBucketsFromString(buckets_str, &hqp_buckets));
+  std::vector<ScoredHistoryMatch::ScoreMaxRelevance> hqp_buckets =
+      ScoredHistoryMatch::GetHQPBucketsFromString(buckets_str);
   EXPECT_THAT(hqp_buckets, ElementsAre(Pair(0.0, 400), Pair(1.5, 600),
                                        Pair(12.0, 1300), Pair(20.0, 1399)));
-  // invalid string.
+  // Test using an invalid string.
   buckets_str = "0.0,400,1.5,600";
-  EXPECT_FALSE(
-      ScoredHistoryMatch::GetHQPBucketsFromString(buckets_str, &hqp_buckets));
+  hqp_buckets = ScoredHistoryMatch::GetHQPBucketsFromString(buckets_str);
+  EXPECT_TRUE(hqp_buckets.empty());
 }
diff --git a/components/omnibox/browser/search_provider.cc b/components/omnibox/browser/search_provider.cc
index 666e966..55e363f 100644
--- a/components/omnibox/browser/search_provider.cc
+++ b/components/omnibox/browser/search_provider.cc
@@ -890,8 +890,12 @@
   fetcher->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES);
   // Add Chrome experiment state to the request headers.
   net::HttpRequestHeaders headers;
-  variations::AppendVariationHeaders(
-      fetcher->GetOriginalURL(), client()->IsOffTheRecord(), false, &headers);
+  // Note: It's fine to pass in |is_signed_in| false, which does not affect
+  // transmission of experiment ids coming from the variations server.
+  bool is_signed_in = false;
+  variations::AppendVariationHeaders(fetcher->GetOriginalURL(),
+                                     client()->IsOffTheRecord(), false,
+                                     is_signed_in, &headers);
   fetcher->SetExtraRequestHeaders(headers.ToString());
   fetcher->Start();
   return fetcher;
diff --git a/components/omnibox/browser/zero_suggest_provider.cc b/components/omnibox/browser/zero_suggest_provider.cc
index f848a3c8..652034f 100644
--- a/components/omnibox/browser/zero_suggest_provider.cc
+++ b/components/omnibox/browser/zero_suggest_provider.cc
@@ -333,9 +333,12 @@
     fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES);
     // Add Chrome experiment state to the request headers.
     net::HttpRequestHeaders headers;
+    // Note: It's fine to pass in |is_signed_in| false, which does not affect
+    // transmission of experiment ids coming from the variations server.
+    bool is_signed_in = false;
     variations::AppendVariationHeaders(fetcher_->GetOriginalURL(),
                                        client()->IsOffTheRecord(), false,
-                                       &headers);
+                                       is_signed_in, &headers);
     fetcher_->SetExtraRequestHeaders(headers.ToString());
     fetcher_->Start();
     LogOmniboxZeroSuggestRequest(ZERO_SUGGEST_REQUEST_SENT);
diff --git a/components/password_manager/core/browser/password_autofill_manager.cc b/components/password_manager/core/browser/password_autofill_manager.cc
index 1c0b1bf..56f3efc 100644
--- a/components/password_manager/core/browser/password_autofill_manager.cc
+++ b/components/password_manager/core/browser/password_autofill_manager.cc
@@ -310,6 +310,10 @@
   password_manager_driver_->ClearPreviewedForm();
 }
 
+bool PasswordAutofillManager::IsCreditCardPopup() {
+  return false;
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // PasswordAutofillManager, private:
 
diff --git a/components/password_manager/core/browser/password_autofill_manager.h b/components/password_manager/core/browser/password_autofill_manager.h
index c1075c32..ce34770 100644
--- a/components/password_manager/core/browser/password_autofill_manager.h
+++ b/components/password_manager/core/browser/password_autofill_manager.h
@@ -42,6 +42,7 @@
                                    base::string16* body) override;
   bool RemoveSuggestion(const base::string16& value, int identifier) override;
   void ClearPreviewedForm() override;
+  bool IsCreditCardPopup() override;
 
   // Invoked when a password mapping is added.
   void OnAddPasswordFormMapping(
diff --git a/components/precache/content/BUILD.gn b/components/precache/content/BUILD.gn
index 54eed60..bca9748e5 100644
--- a/components/precache/content/BUILD.gn
+++ b/components/precache/content/BUILD.gn
@@ -39,6 +39,7 @@
     "//components/history/core/browser",
     "//components/precache/core",
     "//components/precache/core:proto",
+    "//components/variations:test_support",
     "//content/public/browser",
     "//content/test:test_support",
     "//net:test_support",
diff --git a/components/precache/content/DEPS b/components/precache/content/DEPS
index 6206a88..5a18477 100644
--- a/components/precache/content/DEPS
+++ b/components/precache/content/DEPS
@@ -5,12 +5,14 @@
   "+components/variations",
   "+content/public/browser",
   "+net/base",
+  "+net/disk_cache",
+  "+net/http",
+  "+net/url_request",
 ]
 
 specific_include_rules = {
   '.*_[a-z]*test\.cc': [
     "+content/public/test",
-    "+net/http",
-    "+net/url_request",
+    "+net/test",
   ],
 }
diff --git a/components/precache/content/precache_manager.cc b/components/precache/content/precache_manager.cc
index a884ff7..204ab49 100644
--- a/components/precache/content/precache_manager.cc
+++ b/components/precache/content/precache_manager.cc
@@ -11,7 +11,10 @@
 #include "base/bind.h"
 #include "base/command_line.h"
 #include "base/logging.h"
+#include "base/memory/ref_counted.h"
 #include "base/metrics/field_trial.h"
+#include "base/metrics/histogram_macros.h"
+#include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "base/time/time.h"
 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h"
@@ -27,12 +30,19 @@
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/storage_partition.h"
 #include "net/base/network_change_notifier.h"
+#include "net/http/http_cache.h"
+#include "net/url_request/url_request_context.h"
+#include "net/url_request/url_request_context_getter.h"
 
 using content::BrowserThread;
 
-namespace {
+namespace precache {
 
 const char kPrecacheFieldTrialName[] = "Precache";
+const char kMinCacheSizeParam[] = "min_cache_size";
+
+namespace {
+
 const char kPrecacheFieldTrialEnabledGroup[] = "Enabled";
 const char kPrecacheFieldTrialControlGroup[] = "Control";
 const char kConfigURLParam[] = "config_url";
@@ -42,8 +52,6 @@
 
 }  // namespace
 
-namespace precache {
-
 size_t NumTopHosts() {
   return kNumTopHosts;
 }
@@ -123,6 +131,94 @@
   return AllowedType::DISALLOWED;
 }
 
+void PrecacheManager::OnCacheBackendReceived(int net_error_code) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  if (net_error_code != net::OK) {
+    // Assume there is no cache.
+    cache_backend_ = nullptr;
+    OnCacheSizeReceived(0);
+    return;
+  }
+  DCHECK(cache_backend_);
+  int result = cache_backend_->CalculateSizeOfAllEntries(base::Bind(
+      &PrecacheManager::OnCacheSizeReceived, base::Unretained(this)));
+  if (result == net::ERR_IO_PENDING) {
+    // Wait for the callback.
+  } else if (result >= 0) {
+    // The result is the expected bytes already.
+    OnCacheSizeReceived(result);
+  } else {
+    // Error occurred. Couldn't get the size. Assume there is no cache.
+    OnCacheSizeReceived(0);
+  }
+  cache_backend_ = nullptr;
+}
+
+void PrecacheManager::OnCacheSizeReceived(int cache_size_bytes) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+  BrowserThread::PostTask(
+      BrowserThread::UI, FROM_HERE,
+      base::Bind(&PrecacheManager::OnCacheSizeReceivedInUIThread,
+                 base::Unretained(this), cache_size_bytes));
+}
+
+void PrecacheManager::OnCacheSizeReceivedInUIThread(int cache_size_bytes) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+  UMA_HISTOGRAM_MEMORY_KB("Precache.CacheSize.AllEntries",
+                          cache_size_bytes / 1024);
+
+  if (cache_size_bytes < min_cache_size_bytes_) {
+    OnDone();  // Do not continue.
+  } else {
+    BrowserThread::PostTaskAndReplyWithResult(
+        BrowserThread::DB, FROM_HERE,
+        base::Bind(&PrecacheDatabase::GetUnfinishedWork,
+                   base::Unretained(precache_database_.get())),
+        base::Bind(&PrecacheManager::OnGetUnfinishedWorkDone, AsWeakPtr()));
+  }
+}
+
+void PrecacheManager::PrecacheIfCacheIsBigEnough(
+    scoped_refptr<net::URLRequestContextGetter> url_request_context_getter) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  CHECK(url_request_context_getter);
+
+  // Continue with OnGetUnfinishedWorkDone only if the size of the cache is
+  // at least min_cache_size_bytes_.
+  // Class disk_cache::Backend does not expose its maximum size. However, caches
+  // are usually full, so we can use the size of all the entries stored in the
+  // cache (via CalculateSizeOfAllEntries) as a proxy of its maximum size.
+  net::URLRequestContext* context =
+      url_request_context_getter->GetURLRequestContext();
+  if (!context) {
+    OnCacheSizeReceived(0);
+    return;
+  }
+  net::HttpTransactionFactory* factory = context->http_transaction_factory();
+  if (!factory) {
+    OnCacheSizeReceived(0);
+    return;
+  }
+  net::HttpCache* cache = factory->GetCache();
+  if (!cache) {
+    // There is no known cache. Assume that there is no cache.
+    // TODO(jamartin): I'm not sure this can be an actual posibility. Consider
+    // making this a CHECK(cache).
+    OnCacheSizeReceived(0);
+    return;
+  }
+  const int net_error_code = cache->GetBackend(
+      &cache_backend_, base::Bind(&PrecacheManager::OnCacheBackendReceived,
+                                  base::Unretained(this)));
+  if (net_error_code != net::ERR_IO_PENDING) {
+    // No need to wait for the callback. The callback hasn't been called with
+    // the appropriate code, so we call it directly.
+    OnCacheBackendReceived(net_error_code);
+  }
+}
+
 void PrecacheManager::StartPrecaching(
     const PrecacheCompletionCallback& precache_completion_callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
@@ -140,12 +236,30 @@
       base::Bind(&PrecacheDatabase::SetLastPrecacheTimestamp,
                  base::Unretained(precache_database_.get()),
                  base::Time::Now()));
-  BrowserThread::PostTaskAndReplyWithResult(
-      BrowserThread::DB,
-      FROM_HERE,
-      base::Bind(&PrecacheDatabase::GetUnfinishedWork,
-                 base::Unretained(precache_database_.get())),
-      base::Bind(&PrecacheManager::OnGetUnfinishedWorkDone, AsWeakPtr()));
+
+  // Ignore boolean return value. In all documented failure cases, it sets the
+  // int to a reasonable value.
+  base::StringToInt(variations::GetVariationParamValue(kPrecacheFieldTrialName,
+                                                       kMinCacheSizeParam),
+                    &min_cache_size_bytes_);
+  if (min_cache_size_bytes_ <= 0) {
+    // Skip looking up the cache size, because it doesn't matter.
+    OnCacheSizeReceivedInUIThread(0);
+    return;
+  }
+
+  scoped_refptr<net::URLRequestContextGetter> url_request_context_getter(
+      content::BrowserContext::GetDefaultStoragePartition(browser_context_)
+          ->GetURLRequestContext());
+  if (!url_request_context_getter) {
+    OnCacheSizeReceivedInUIThread(0);
+    return;
+  }
+
+  BrowserThread::PostTask(
+      BrowserThread::IO, FROM_HERE,
+      base::Bind(&PrecacheManager::PrecacheIfCacheIsBigEnough, AsWeakPtr(),
+                 std::move(url_request_context_getter)));
 }
 
 void PrecacheManager::OnGetUnfinishedWorkDone(
diff --git a/components/precache/content/precache_manager.h b/components/precache/content/precache_manager.h
index 507aeba2..ec093b0 100644
--- a/components/precache/content/precache_manager.h
+++ b/components/precache/content/precache_manager.h
@@ -17,10 +17,13 @@
 #include "base/callback.h"
 #include "base/compiler_specific.h"
 #include "base/macros.h"
+#include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
 #include "components/history/core/browser/history_types.h"
 #include "components/keyed_service/core/keyed_service.h"
 #include "components/precache/core/precache_fetcher.h"
+#include "net/disk_cache/disk_cache.h"
+#include "net/http/http_cache.h"
 #include "url/gurl.h"
 
 namespace base {
@@ -55,6 +58,8 @@
 class PrecacheUnfinishedWork;
 
 // Visible for test.
+extern const char kPrecacheFieldTrialName[];
+extern const char kMinCacheSizeParam[];
 size_t NumTopHosts();
 
 // Class that manages all precaching-related activities. Owned by the
@@ -162,6 +167,14 @@
   // gets the list of TopHosts for metrics purposes, but otherwise does nothing.
   void OnHostsReceivedThenDone(const history::TopHostsList& host_counts);
 
+  // Chain of callbacks for StartPrecaching that make sure that we only precache
+  // if there is a cache big enough.
+  void PrecacheIfCacheIsBigEnough(
+      scoped_refptr<net::URLRequestContextGetter> url_request_context_getter);
+  void OnCacheBackendReceived(int net_error_code);
+  void OnCacheSizeReceived(int cache_size_bytes);
+  void OnCacheSizeReceivedInUIThread(int cache_size_bytes);
+
   // Returns true if precaching is allowed for the browser context.
   AllowedType PrecachingAllowed() const;
 
@@ -214,6 +227,15 @@
   // Flag indicating whether or not precaching is currently in progress.
   bool is_precaching_;
 
+  // Pointer to the backend of the cache. Required to get the size of the cache.
+  // It is not owned and it is reset on demand via callbacks.
+  // It should only be accessed from the IO thread.
+  disk_cache::Backend* cache_backend_;
+
+  // The minimum cache size allowed for precaching. Initialized by
+  // StartPrecaching and read by OnCacheSizeReceivedInUIThread.
+  int min_cache_size_bytes_;
+
   // Work that hasn't yet finished.
   std::unique_ptr<PrecacheUnfinishedWork> unfinished_work_;
 
diff --git a/components/precache/content/precache_manager_unittest.cc b/components/precache/content/precache_manager_unittest.cc
index c8d0d0c..a93a2ca 100644
--- a/components/precache/content/precache_manager_unittest.cc
+++ b/components/precache/content/precache_manager_unittest.cc
@@ -28,12 +28,17 @@
 #include "components/precache/core/precache_database.h"
 #include "components/precache/core/precache_switches.h"
 #include "components/precache/core/proto/unfinished_work.pb.h"
+#include "components/variations/variations_params_manager.h"
 #include "content/public/browser/browser_thread.h"
+#include "content/public/browser/storage_partition.h"
 #include "content/public/test/test_browser_context.h"
 #include "content/public/test/test_browser_thread_bundle.h"
+#include "net/base/test_completion_callback.h"
+#include "net/disk_cache/simple/simple_backend_impl.h"
 #include "net/http/http_response_headers.h"
 #include "net/http/http_response_info.h"
 #include "net/http/http_status_code.h"
+#include "net/test/gtest_util.h"
 #include "net/url_request/test_url_fetcher_factory.h"
 #include "net/url_request/url_request_status.h"
 #include "net/url_request/url_request_test_util.h"
@@ -223,6 +228,7 @@
   testing::NiceMock<MockHistoryService> history_service_;
   base::HistogramTester histograms_;
   net::HttpResponseInfo info_;
+  variations::testing::VariationParamsManager variation_params_;
 };
 
 TEST_F(PrecacheManagerTest, StartAndFinishPrecaching) {
@@ -253,6 +259,75 @@
   EXPECT_EQ(expected_requested_urls, url_callback_.requested_urls());
 }
 
+TEST_F(PrecacheManagerTest, StartPrecachingWithGoodSizedCache) {
+  variation_params_.SetVariationParams(kPrecacheFieldTrialName,
+                                       {{kMinCacheSizeParam, "1"}});
+
+  // Let's store something in the cache so we pass the min_cache_size threshold.
+  disk_cache::Backend* cache_backend;
+  {
+    // Get the CacheBackend.
+    net::TestCompletionCallback cb;
+    net::HttpCache* cache =
+        content::BrowserContext::GetDefaultStoragePartition(&browser_context_)
+            ->GetURLRequestContext()
+            ->GetURLRequestContext()
+            ->http_transaction_factory()
+            ->GetCache();
+    CHECK_NE(nullptr, cache);
+    int rv = cache->GetBackend(&cache_backend, cb.callback());
+    CHECK_EQ(net::OK, cb.GetResult(rv));
+    CHECK_NE(nullptr, cache_backend);
+    CHECK_EQ(cache_backend, cache->GetCurrentBackend());
+  }
+  disk_cache::Entry* entry = nullptr;
+  {
+    // Create a cache Entry.
+    net::TestCompletionCallback cb;
+    int rv = cache_backend->CreateEntry("key", &entry, cb.callback());
+    CHECK_EQ(net::OK, cb.GetResult(rv));
+    CHECK_NE(nullptr, entry);
+  }
+  {
+    // Store some data in the cache Entry.
+    const std::string data(1, 'a');
+    scoped_refptr<net::StringIOBuffer> buffer(new net::StringIOBuffer(data));
+    net::TestCompletionCallback cb;
+    int rv = entry->WriteData(0, 0, buffer.get(), buffer->size(), cb.callback(),
+                              false);
+    entry->Close();
+    CHECK_EQ(buffer->size(), cb.GetResult(rv));
+  }
+  {
+    // Make sure everything went according to plan.
+    net::TestCompletionCallback cb;
+    int rv = cache_backend->CalculateSizeOfAllEntries(cb.callback());
+    CHECK_LE(1, cb.GetResult(rv));
+  }
+  EXPECT_FALSE(precache_manager_->IsPrecaching());
+
+  precache_manager_->StartPrecaching(precache_callback_.GetCallback());
+  base::RunLoop().RunUntilIdle();
+
+  EXPECT_TRUE(precache_manager_->IsPrecaching());
+  // Now it should be waiting for the top hosts.
+}
+
+TEST_F(PrecacheManagerTest, StartPrecachingStopsOnSmallCaches) {
+  // We don't have any entry in the cache, so the reported cache_size = 0 and
+  // thus it will fall below the threshold of 1.
+  variation_params_.SetVariationParams(kPrecacheFieldTrialName,
+                                       {{kMinCacheSizeParam, "1"}});
+  EXPECT_FALSE(precache_manager_->IsPrecaching());
+
+  precache_manager_->StartPrecaching(precache_callback_.GetCallback());
+  base::RunLoop().RunUntilIdle();
+
+  EXPECT_FALSE(precache_manager_->IsPrecaching());
+  EXPECT_TRUE(precache_callback_.was_on_done_called());
+  EXPECT_TRUE(url_callback_.requested_urls().empty());
+}
+
 TEST_F(PrecacheManagerTest, StartAndFinishPrecachingWithUnfinishedHosts) {
   std::unique_ptr<PrecacheUnfinishedWork> unfinished_work(
       new PrecacheUnfinishedWork());
@@ -355,7 +430,9 @@
 
   EXPECT_TRUE(precache_manager_->IsPrecaching());
   // Run a task to get unfinished work, and to get hosts.
-  for (int i = 0; i < 2; ++i) {
+  // We need to call run_loop.Run as many times as needed to go through the
+  // chain of callbacks :-(.
+  for (int i = 0; i < 4; ++i) {
     base::RunLoop run_loop;
     base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
                                                   run_loop.QuitClosure());
@@ -418,7 +495,8 @@
   base::RunLoop().RunUntilIdle();
   EXPECT_THAT(
       histograms_.GetTotalCountsForPrefix("Precache."),
-      UnorderedElementsAre(Pair("Precache.DownloadedPrecacheMotivated", 1),
+      UnorderedElementsAre(Pair("Precache.CacheSize.AllEntries", 1),
+                           Pair("Precache.DownloadedPrecacheMotivated", 1),
                            Pair("Precache.Fetch.PercentCompleted", 1),
                            Pair("Precache.Fetch.ResponseBytes.Network", 1),
                            Pair("Precache.Fetch.ResponseBytes.Total", 1),
@@ -498,6 +576,7 @@
   RecordStatsForPrecacheFetch(
       GURL("http://yesterday-fetch.com"), std::string(), base::TimeDelta(),
       kCurrentTime - base::TimeDelta::FromDays(1), info_, 1000);
+  expected_histogram_count_map["Precache.CacheSize.AllEntries"]++;
   expected_histogram_count_map["Precache.DownloadedPrecacheMotivated"] += 3;
   expected_histogram_count_map["Precache.Fetch.PercentCompleted"]++;
   expected_histogram_count_map["Precache.Fetch.ResponseBytes.Network"]++;
@@ -527,6 +606,7 @@
   // The precache fetcher runs until done, which records these histograms,
   // and then cancels precaching, which records these histograms again.
   // In practice
+  expected_histogram_count_map["Precache.CacheSize.AllEntries"]++;
   expected_histogram_count_map["Precache.Fetch.PercentCompleted"]++;
   expected_histogram_count_map["Precache.Fetch.ResponseBytes.Network"]++;
   expected_histogram_count_map["Precache.Fetch.ResponseBytes.Total"]++;
diff --git a/components/proximity_auth/screenlock_bridge.cc b/components/proximity_auth/screenlock_bridge.cc
index d3996b1..0663dda 100644
--- a/components/proximity_auth/screenlock_bridge.cc
+++ b/components/proximity_auth/screenlock_bridge.cc
@@ -117,13 +117,13 @@
 }
 
 void ScreenlockBridge::SetLockHandler(LockHandler* lock_handler) {
-  DCHECK(lock_handler_ == nullptr || lock_handler == nullptr);
-
   // Don't notify observers if there is no change -- i.e. if the screen was
   // already unlocked, and is remaining unlocked.
   if (lock_handler == lock_handler_)
     return;
 
+  DCHECK(lock_handler_ == nullptr || lock_handler == nullptr);
+
   // TODO(isherman): If |lock_handler| is null, then |lock_handler_| might have
   // been freed. Cache the screen type rather than querying it below.
   LockHandler::ScreenType screen_type;
diff --git a/components/safe_browsing/OWNERS b/components/safe_browsing/OWNERS
index b7fd72e..41a80e21 100644
--- a/components/safe_browsing/OWNERS
+++ b/components/safe_browsing/OWNERS
@@ -1,3 +1,4 @@
+jialiul@chromium.org
 mattm@chromium.org
 nparker@chromium.org
 shess@chromium.org
diff --git a/components/suggestions/suggestions_service.cc b/components/suggestions/suggestions_service.cc
index 47072e8..ec69cfe 100644
--- a/components/suggestions/suggestions_service.cc
+++ b/components/suggestions/suggestions_service.cc
@@ -420,8 +420,11 @@
   request->SetRequestContext(url_request_context_);
   // Add Chrome experiment state to the request headers.
   net::HttpRequestHeaders headers;
+  // Note: It's fine to pass in |is_signed_in| false, which does not affect
+  // transmission of experiment ids coming from the variations server.
+  bool is_signed_in = false;
   variations::AppendVariationHeaders(request->GetOriginalURL(), false, false,
-                                     &headers);
+                                     is_signed_in, &headers);
   request->SetExtraRequestHeaders(headers.ToString());
   if (!access_token.empty()) {
     request->AddExtraRequestHeader(
diff --git a/components/sync/device_info/device_info_sync_bridge.cc b/components/sync/device_info/device_info_sync_bridge.cc
index c762c90..e1387abe 100644
--- a/components/sync/device_info/device_info_sync_bridge.cc
+++ b/components/sync/device_info/device_info_sync_bridge.cc
@@ -118,6 +118,13 @@
     EntityDataMap entity_data_map) {
   DCHECK(has_provider_initialized_);
   DCHECK(change_processor()->IsTrackingMetadata());
+  const DeviceInfo* local_info =
+      local_device_info_provider_->GetLocalDeviceInfo();
+  // If our dependency was yanked out from beneath us, we cannot correctly
+  // handle this request, and all our data will be deleted soon.
+  if (local_info == nullptr) {
+    return SyncError();
+  }
 
   // Local data should typically be near empty, with the only possible value
   // corresponding to this device. This is because on signout all device info
@@ -130,8 +137,6 @@
   }
 
   bool has_changes = false;
-  const DeviceInfo* local_info =
-      local_device_info_provider_->GetLocalDeviceInfo();
   std::string local_guid = local_info->guid();
   std::unique_ptr<WriteBatch> batch = store_->CreateWriteBatch();
   for (const auto& kv : entity_data_map) {
@@ -166,6 +171,13 @@
     std::unique_ptr<MetadataChangeList> metadata_change_list,
     EntityChangeList entity_changes) {
   DCHECK(has_provider_initialized_);
+  const DeviceInfo* local_info =
+      local_device_info_provider_->GetLocalDeviceInfo();
+  // If our dependency was yanked out from beneath us, we cannot correctly
+  // handle this request, and all our data will be deleted soon.
+  if (local_info == nullptr) {
+    return SyncError();
+  }
 
   std::unique_ptr<WriteBatch> batch = store_->CreateWriteBatch();
   bool has_changes = false;
@@ -173,7 +185,7 @@
     const std::string guid = change.storage_key();
     // Each device is the authoritative source for itself, ignore any remote
     // changes that have our local cache guid.
-    if (guid == local_device_info_provider_->GetLocalDeviceInfo()->guid()) {
+    if (guid == local_info->guid()) {
       continue;
     }
 
@@ -315,6 +327,8 @@
   // should only need to give the processor metadata upon initialization. If
   // sync is disabled and enabled, our provider will try to retrigger this
   // event, but we do not want to send any more metadata to the processor.
+  // TODO(skym, crbug.com/672600): Handle re-initialization and start the pulse
+  // timer.
   subscription_.reset();
 
   has_provider_initialized_ = true;
@@ -387,6 +401,15 @@
 
   const DeviceInfo* current_info =
       local_device_info_provider_->GetLocalDeviceInfo();
+  // Must ensure |pulse_timer_| is started even if sync is in the process of
+  // being disabled. TODO(skym, crbug.com/672600): Remove this timer Start(), as
+  // it should be started when the provider re-initializes instead.
+  if (current_info == nullptr) {
+    pulse_timer_.Start(FROM_HERE, DeviceInfoUtil::kPulseInterval,
+                       base::Bind(&DeviceInfoSyncBridge::SendLocalData,
+                                  base::Unretained(this)));
+    return;
+  }
   auto iter = all_data_.find(current_info->guid());
 
   // Convert to DeviceInfo for Equals function.
diff --git a/components/sync/device_info/device_info_sync_bridge_unittest.cc b/components/sync/device_info/device_info_sync_bridge_unittest.cc
index ace2211..3ed624e 100644
--- a/components/sync/device_info/device_info_sync_bridge_unittest.cc
+++ b/components/sync/device_info/device_info_sync_bridge_unittest.cc
@@ -26,6 +26,7 @@
 
 namespace syncer {
 
+using base::OneShotTimer;
 using base::Time;
 using base::TimeDelta;
 using sync_pb::DeviceInfoSpecifics;
@@ -287,6 +288,8 @@
     return processor_;
   }
 
+  const OneShotTimer& pulse_timer() { return bridge()->pulse_timer_; }
+
   // Should only be called after the bridge has been initialized. Will first
   // recover the bridge's store, so another can be initialized later, and then
   // deletes the bridge.
@@ -398,6 +401,16 @@
   EXPECT_TRUE(processor()->metadata());
 }
 
+// Simulate shutting down sync during the ModelTypeStore callbacks. The pulse
+// timer should still be initialized, even though reconcile never occurs.
+TEST_F(DeviceInfoSyncBridgeTest, ClearProviderDuringInit) {
+  InitializeBridge();
+  local_device()->Clear();
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(0u, bridge()->GetAllDeviceInfo().size());
+  EXPECT_TRUE(pulse_timer().IsRunning());
+}
+
 TEST_F(DeviceInfoSyncBridgeTest, GetClientTagNormal) {
   InitializeBridge();
   const std::string guid = "abc";
@@ -587,6 +600,25 @@
   EXPECT_EQ(1, change_count());
 }
 
+TEST_F(DeviceInfoSyncBridgeTest, ClearProviderAndApply) {
+  // This will initialize the provider a first time.
+  InitializeAndPump();
+  EXPECT_EQ(1u, bridge()->GetAllDeviceInfo().size());
+
+  const DeviceInfoSpecifics specifics = CreateSpecifics(1, Time::Now());
+
+  local_device()->Clear();
+  SyncError error = bridge()->ApplySyncChanges(
+      bridge()->CreateMetadataChangeList(), EntityAddList({specifics}));
+  EXPECT_FALSE(error.IsSet());
+  EXPECT_EQ(1u, bridge()->GetAllDeviceInfo().size());
+
+  local_device()->Initialize(CreateModel(kDefaultLocalSuffix));
+  error = bridge()->ApplySyncChanges(bridge()->CreateMetadataChangeList(),
+                                     EntityAddList({specifics}));
+  EXPECT_EQ(2u, bridge()->GetAllDeviceInfo().size());
+}
+
 TEST_F(DeviceInfoSyncBridgeTest, MergeEmpty) {
   InitializeAndPump();
   EXPECT_EQ(1, change_count());
@@ -680,6 +712,24 @@
   EXPECT_EQ(0u, bridge()->GetAllDeviceInfo().size());
 }
 
+TEST_F(DeviceInfoSyncBridgeTest, ClearProviderAndMerge) {
+  // This will initialize the provider a first time.
+  InitializeAndPump();
+  EXPECT_EQ(1u, bridge()->GetAllDeviceInfo().size());
+
+  const DeviceInfoSpecifics specifics = CreateSpecifics(1, Time::Now());
+
+  local_device()->Clear();
+  SyncError error = bridge()->MergeSyncData(
+      bridge()->CreateMetadataChangeList(), InlineEntityDataMap({specifics}));
+  EXPECT_FALSE(error.IsSet());
+  EXPECT_EQ(1u, bridge()->GetAllDeviceInfo().size());
+  local_device()->Initialize(CreateModel(kDefaultLocalSuffix));
+  error = bridge()->MergeSyncData(bridge()->CreateMetadataChangeList(),
+                                  InlineEntityDataMap({specifics}));
+  EXPECT_EQ(2u, bridge()->GetAllDeviceInfo().size());
+}
+
 TEST_F(DeviceInfoSyncBridgeTest, CountActiveDevices) {
   InitializeAndPump();
   EXPECT_EQ(1, bridge()->CountActiveDevices());
diff --git a/components/test/android/browsertests_apk/AndroidManifest.xml.jinja2 b/components/test/android/browsertests_apk/AndroidManifest.xml.jinja2
index 29baf6f..42b9282 100644
--- a/components/test/android/browsertests_apk/AndroidManifest.xml.jinja2
+++ b/components/test/android/browsertests_apk/AndroidManifest.xml.jinja2
@@ -48,7 +48,7 @@
                  android:exported="false" />
         {% endfor %}
 
-        {% set num_privileged_services = 20 %}
+        {% set num_privileged_services = 3 %}
         <meta-data android:name="org.chromium.content.browser.NUM_PRIVILEGED_SERVICES"
                    android:value="{{ num_privileged_services }}"/>
         {% for i in range(num_privileged_services) %}
diff --git a/components/ui_devtools/devtools_server.h b/components/ui_devtools/devtools_server.h
index 4060184..7dfc02c 100644
--- a/components/ui_devtools/devtools_server.h
+++ b/components/ui_devtools/devtools_server.h
@@ -13,7 +13,6 @@
 #include "components/ui_devtools/Forward.h"
 #include "components/ui_devtools/Protocol.h"
 #include "components/ui_devtools/devtools_client.h"
-#include "components/ui_devtools/devtools_export.h"
 #include "components/ui_devtools/string_util.h"
 #include "net/server/http_server.h"
 
@@ -26,12 +25,12 @@
 
   // Returns an empty unique_ptr if ui devtools flag isn't enabled or if a
   // server instance has already been created.
-  static UI_DEVTOOLS_EXPORT std::unique_ptr<UiDevToolsServer> Create(
+  static std::unique_ptr<UiDevToolsServer> Create(
       scoped_refptr<base::SingleThreadTaskRunner> io_thread_task_runner);
 
   // Returns a list of attached UiDevToolsClient name + URL
   using NameUrlPair = std::pair<std::string, std::string>;
-  static UI_DEVTOOLS_EXPORT std::vector<NameUrlPair> GetClientNamesAndUrls();
+  static std::vector<NameUrlPair> GetClientNamesAndUrls();
 
   void AttachClient(std::unique_ptr<UiDevToolsClient> client);
   void SendOverWebSocket(int connection_id, const String& message);
diff --git a/components/variations/net/variations_http_headers.cc b/components/variations/net/variations_http_headers.cc
index 48e84eb1..3217974 100644
--- a/components/variations/net/variations_http_headers.cc
+++ b/components/variations/net/variations_http_headers.cc
@@ -44,6 +44,7 @@
 void AppendVariationHeaders(const GURL& url,
                             bool incognito,
                             bool uma_enabled,
+                            bool is_signed_in,
                             net::HttpRequestHeaders* headers) {
   // Note the criteria for attaching client experiment headers:
   // 1. We only transmit to Google owned domains which can evaluate experiments.
@@ -62,7 +63,8 @@
     headers->SetHeaderIfMissing(kChromeUMAEnabled, "1");
 
   const std::string variation_ids_header =
-      VariationsHttpHeaderProvider::GetInstance()->GetClientDataHeader();
+      VariationsHttpHeaderProvider::GetInstance()->GetClientDataHeader(
+          is_signed_in);
   if (!variation_ids_header.empty()) {
     // Note that prior to M33 this header was named X-Chrome-Variations.
     headers->SetHeaderIfMissing(kClientData, variation_ids_header);
diff --git a/components/variations/net/variations_http_headers.h b/components/variations/net/variations_http_headers.h
index d6280e5..fe4d597 100644
--- a/components/variations/net/variations_http_headers.h
+++ b/components/variations/net/variations_http_headers.h
@@ -17,12 +17,16 @@
 namespace variations {
 
 // Adds Chrome experiment and metrics state as custom headers to |headers|.
-// Some headers may not be set given the |incognito| mode or whether
-// the user has |uma_enabled|.  Also, we never transmit headers to non-Google
-// sites, which is checked based on the destination |url|.
+// The content of the headers will depend on |incognito|, |uma_enabled| and
+// |is_signed_in| parameters. It is fine to pass false for |is_signed_in| if the
+// state is not known to the caller. This will prevent addition of ids of type
+// GOOGLE_WEB_PROPERTIES_SIGNED_IN, which is not the case for any ids that come
+// from the variations server. These headers are never transmitted to non-Google
+// web sites, which is checked based on the destination |url|.
 void AppendVariationHeaders(const GURL& url,
                             bool incognito,
                             bool uma_enabled,
+                            bool is_signed_in,
                             net::HttpRequestHeaders* headers);
 
 // Returns the HTTP header names which are added by AppendVariationHeaders().
diff --git a/components/variations/variations_associated_data.cc b/components/variations/variations_associated_data.cc
index 6701105..ec696a3 100644
--- a/components/variations/variations_associated_data.cc
+++ b/components/variations/variations_associated_data.cc
@@ -39,13 +39,21 @@
                    const VariationID id,
                    const bool force) {
 #if !defined(NDEBUG)
-    DCHECK_EQ(3, ID_COLLECTION_COUNT);
-    // Ensure that at most one of the trigger/non-trigger web property IDs are
-    // set.
-    if (key == GOOGLE_WEB_PROPERTIES || key == GOOGLE_WEB_PROPERTIES_TRIGGER) {
-      IDCollectionKey other_key = key == GOOGLE_WEB_PROPERTIES ?
-          GOOGLE_WEB_PROPERTIES_TRIGGER : GOOGLE_WEB_PROPERTIES;
-      DCHECK_EQ(EMPTY_ID, GetID(other_key, group_identifier));
+    DCHECK_EQ(4, ID_COLLECTION_COUNT);
+    // Ensure that at most one of the trigger/non-trigger/signed-in web property
+    // IDs are set.
+    if (key == GOOGLE_WEB_PROPERTIES || key == GOOGLE_WEB_PROPERTIES_TRIGGER ||
+        key == GOOGLE_WEB_PROPERTIES_SIGNED_IN) {
+      if (key != GOOGLE_WEB_PROPERTIES)
+        DCHECK_EQ(EMPTY_ID, GetID(GOOGLE_WEB_PROPERTIES, group_identifier));
+      if (key != GOOGLE_WEB_PROPERTIES_TRIGGER) {
+        DCHECK_EQ(EMPTY_ID,
+                  GetID(GOOGLE_WEB_PROPERTIES_TRIGGER, group_identifier));
+      }
+      if (key != GOOGLE_WEB_PROPERTIES_SIGNED_IN) {
+        DCHECK_EQ(EMPTY_ID,
+                  GetID(GOOGLE_WEB_PROPERTIES_SIGNED_IN, group_identifier));
+      }
     }
 
     // Validate that all collections with this |group_identifier| have the same
diff --git a/components/variations/variations_associated_data.h b/components/variations/variations_associated_data.h
index ad359a4..8b1b25f 100644
--- a/components/variations/variations_associated_data.h
+++ b/components/variations/variations_associated_data.h
@@ -58,6 +58,9 @@
   // This collection is used by Google web properties, transmitted through the
   // X-Client-Data header.
   GOOGLE_WEB_PROPERTIES,
+  // This collection is used by Google web properties for signed in users only,
+  // transmitted through the X-Client-Data header.
+  GOOGLE_WEB_PROPERTIES_SIGNED_IN,
   // This collection is used by Google web properties for IDs that trigger
   // server side experimental behavior, transmitted through the
   // X-Client-Data header.
diff --git a/components/variations/variations_http_header_provider.cc b/components/variations/variations_http_header_provider.cc
index 5af7151..885c8908 100644
--- a/components/variations/variations_http_header_provider.cc
+++ b/components/variations/variations_http_header_provider.cc
@@ -26,7 +26,8 @@
   return base::Singleton<VariationsHttpHeaderProvider>::get();
 }
 
-std::string VariationsHttpHeaderProvider::GetClientDataHeader() {
+std::string VariationsHttpHeaderProvider::GetClientDataHeader(
+    bool is_signed_in) {
   // Lazily initialize the header, if not already done, before attempting to
   // transmit it.
   InitVariationIDsCacheIfNeeded();
@@ -34,7 +35,9 @@
   std::string variation_ids_header_copy;
   {
     base::AutoLock scoped_lock(lock_);
-    variation_ids_header_copy = variation_ids_header_;
+    variation_ids_header_copy = is_signed_in
+                                    ? cached_variation_ids_header_signed_in_
+                                    : cached_variation_ids_header_;
   }
   return variation_ids_header_copy;
 }
@@ -48,9 +51,11 @@
   std::string ids_string = " ";
   {
     base::AutoLock scoped_lock(lock_);
-    for (VariationID id : GetAllVariationIds()) {
-      ids_string.append(base::IntToString(id));
-      ids_string.push_back(' ');
+    for (const VariationIDEntry& entry : GetAllVariationIds()) {
+      if (entry.second == GOOGLE_WEB_PROPERTIES) {
+        ids_string.append(base::IntToString(entry.first));
+        ids_string.push_back(' ');
+      }
     }
   }
   return ids_string;
@@ -76,15 +81,12 @@
   return true;
 }
 
-
 bool VariationsHttpHeaderProvider::SetDefaultVariationIds(
     const std::vector<std::string>& variation_ids) {
   default_variation_ids_set_.clear();
-  default_trigger_id_set_.clear();
   for (const std::string& entry : variation_ids) {
     if (entry.empty()) {
       default_variation_ids_set_.clear();
-      default_trigger_id_set_.clear();
       return false;
     }
     bool trigger_id =
@@ -95,13 +97,11 @@
     int variation_id = 0;
     if (!base::StringToInt(trimmed_entry, &variation_id)) {
       default_variation_ids_set_.clear();
-      default_trigger_id_set_.clear();
       return false;
     }
-    if (trigger_id)
-      default_trigger_id_set_.insert(variation_id);
-    else
-      default_variation_ids_set_.insert(variation_id);
+    default_variation_ids_set_.insert(VariationIDEntry(
+        variation_id,
+        trigger_id ? GOOGLE_WEB_PROPERTIES_TRIGGER : GOOGLE_WEB_PROPERTIES));
   }
   return true;
 }
@@ -123,20 +123,13 @@
 void VariationsHttpHeaderProvider::OnFieldTrialGroupFinalized(
     const std::string& trial_name,
     const std::string& group_name) {
-  VariationID new_id =
-      GetGoogleVariationID(GOOGLE_WEB_PROPERTIES, trial_name, group_name);
-  VariationID new_trigger_id = GetGoogleVariationID(
-      GOOGLE_WEB_PROPERTIES_TRIGGER, trial_name, group_name);
-  if (new_id == EMPTY_ID && new_trigger_id == EMPTY_ID)
-    return;
-
   base::AutoLock scoped_lock(lock_);
-  if (new_id != EMPTY_ID)
-    variation_ids_set_.insert(new_id);
-  if (new_trigger_id != EMPTY_ID)
-    variation_trigger_ids_set_.insert(new_trigger_id);
-
-  UpdateVariationIDsHeaderValue();
+  const size_t old_size = variation_ids_set_.size();
+  CacheVariationsId(trial_name, group_name, GOOGLE_WEB_PROPERTIES);
+  CacheVariationsId(trial_name, group_name, GOOGLE_WEB_PROPERTIES_SIGNED_IN);
+  CacheVariationsId(trial_name, group_name, GOOGLE_WEB_PROPERTIES_TRIGGER);
+  if (variation_ids_set_.size() != old_size)
+    UpdateVariationIDsHeaderValue();
 }
 
 void VariationsHttpHeaderProvider::OnSyntheticTrialsChanged(
@@ -145,10 +138,18 @@
 
   synthetic_variation_ids_set_.clear();
   for (const SyntheticTrialGroup& group : groups) {
-    const VariationID id =
+    VariationID id =
         GetGoogleVariationIDFromHashes(GOOGLE_WEB_PROPERTIES, group.id);
-    if (id != EMPTY_ID)
-      synthetic_variation_ids_set_.insert(id);
+    if (id != EMPTY_ID) {
+      synthetic_variation_ids_set_.insert(
+          VariationIDEntry(id, GOOGLE_WEB_PROPERTIES));
+    }
+    id = GetGoogleVariationIDFromHashes(GOOGLE_WEB_PROPERTIES_SIGNED_IN,
+                                        group.id);
+    if (id != EMPTY_ID) {
+      synthetic_variation_ids_set_.insert(
+          VariationIDEntry(id, GOOGLE_WEB_PROPERTIES_SIGNED_IN));
+    }
   }
   UpdateVariationIDsHeaderValue();
 }
@@ -169,18 +170,12 @@
   base::FieldTrialList::GetActiveFieldTrialGroups(&initial_groups);
 
   for (const auto& entry : initial_groups) {
-    const VariationID id =
-        GetGoogleVariationID(GOOGLE_WEB_PROPERTIES, entry.trial_name,
-                             entry.group_name);
-    if (id != EMPTY_ID)
-      variation_ids_set_.insert(id);
-
-    const VariationID trigger_id =
-        GetGoogleVariationID(GOOGLE_WEB_PROPERTIES_TRIGGER, entry.trial_name,
-                             entry.group_name);
-
-    if (trigger_id != EMPTY_ID)
-      variation_trigger_ids_set_.insert(trigger_id);
+    CacheVariationsId(entry.trial_name, entry.group_name,
+                      GOOGLE_WEB_PROPERTIES);
+    CacheVariationsId(entry.trial_name, entry.group_name,
+                      GOOGLE_WEB_PROPERTIES_SIGNED_IN);
+    CacheVariationsId(entry.trial_name, entry.group_name,
+                      GOOGLE_WEB_PROPERTIES_TRIGGER);
   }
   UpdateVariationIDsHeaderValue();
 
@@ -192,61 +187,90 @@
   variation_ids_cache_initialized_ = true;
 }
 
+void VariationsHttpHeaderProvider::CacheVariationsId(
+    const std::string& trial_name,
+    const std::string& group_name,
+    IDCollectionKey key) {
+  const VariationID id = GetGoogleVariationID(key, trial_name, group_name);
+  if (id != EMPTY_ID)
+    variation_ids_set_.insert(VariationIDEntry(id, key));
+}
+
 void VariationsHttpHeaderProvider::UpdateVariationIDsHeaderValue() {
   lock_.AssertAcquired();
 
   // The header value is a serialized protobuffer of Variation IDs which is
   // base64 encoded before transmitting as a string.
-  variation_ids_header_.clear();
+  cached_variation_ids_header_.clear();
+  cached_variation_ids_header_signed_in_.clear();
 
-  if (variation_ids_set_.empty() && default_variation_ids_set_.empty() &&
-      variation_trigger_ids_set_.empty() && default_trigger_id_set_.empty() &&
-      synthetic_variation_ids_set_.empty()) {
-    return;
+  // If successful, swap the header value with the new one.
+  // Note that the list of IDs and the header could be temporarily out of sync
+  // if IDs are added as the header is recreated. The receiving servers are OK
+  // with such discrepancies.
+  cached_variation_ids_header_ = GenerateBase64EncodedProto(false);
+  cached_variation_ids_header_signed_in_ = GenerateBase64EncodedProto(true);
+}
+
+std::string VariationsHttpHeaderProvider::GenerateBase64EncodedProto(
+    bool is_signed_in) {
+  std::set<VariationIDEntry> all_variation_ids_set = GetAllVariationIds();
+
+  ClientVariations proto;
+  for (const VariationIDEntry& entry : all_variation_ids_set) {
+    switch (entry.second) {
+      case GOOGLE_WEB_PROPERTIES_SIGNED_IN:
+        if (is_signed_in)
+          proto.add_variation_id(entry.first);
+        break;
+      case GOOGLE_WEB_PROPERTIES:
+        proto.add_variation_id(entry.first);
+        break;
+      case GOOGLE_WEB_PROPERTIES_TRIGGER:
+        proto.add_trigger_variation_id(entry.first);
+        break;
+      case CHROME_SYNC_SERVICE:
+      case ID_COLLECTION_COUNT:
+        // These cases included to get full enum coverage for switch, so that
+        // new enums introduce compiler warnings. Nothing to do for these.
+        break;
+    }
   }
 
+  const size_t total_id_count =
+      proto.variation_id_size() + proto.trigger_variation_id_size();
+
+  if (total_id_count == 0)
+    return std::string();
+
   // This is the bottleneck for the creation of the header, so validate the size
   // here. Force a hard maximum on the ID count in case the Variations server
   // returns too many IDs and DOSs receiving servers with large requests.
-  const size_t total_id_count =
-      variation_ids_set_.size() + variation_trigger_ids_set_.size();
   DCHECK_LE(total_id_count, 10U);
   UMA_HISTOGRAM_COUNTS_100("Variations.Headers.ExperimentCount",
                            total_id_count);
   if (total_id_count > 20)
-    return;
-
-  std::set<VariationID> all_variation_ids_set = GetAllVariationIds();
-  std::set<VariationID> all_trigger_ids_set = default_trigger_id_set_;
-  for (VariationID id : variation_trigger_ids_set_)
-    all_trigger_ids_set.insert(id);
-
-  ClientVariations proto;
-  for (VariationID id : all_variation_ids_set)
-    proto.add_variation_id(id);
-  for (VariationID id : all_trigger_ids_set)
-    proto.add_trigger_variation_id(id);
+    return std::string();
 
   std::string serialized;
   proto.SerializeToString(&serialized);
 
   std::string hashed;
   base::Base64Encode(serialized, &hashed);
-  // If successful, swap the header value with the new one.
-  // Note that the list of IDs and the header could be temporarily out of sync
-  // if IDs are added as the header is recreated. The receiving servers are OK
-  // with such discrepancies.
-  variation_ids_header_ = hashed;
+  return hashed;
 }
 
-std::set<VariationID> VariationsHttpHeaderProvider::GetAllVariationIds() {
+std::set<VariationsHttpHeaderProvider::VariationIDEntry>
+VariationsHttpHeaderProvider::GetAllVariationIds() {
   lock_.AssertAcquired();
 
-  std::set<VariationID> all_variation_ids_set = default_variation_ids_set_;
-  for (VariationID id : variation_ids_set_)
-    all_variation_ids_set.insert(id);
-  for (VariationID id : synthetic_variation_ids_set_)
-    all_variation_ids_set.insert(id);
+  std::set<VariationIDEntry> all_variation_ids_set = default_variation_ids_set_;
+  for (const VariationIDEntry& entry : variation_ids_set_) {
+    all_variation_ids_set.insert(entry);
+  }
+  for (const VariationIDEntry& entry : synthetic_variation_ids_set_) {
+    all_variation_ids_set.insert(entry);
+  }
   return all_variation_ids_set;
 }
 
diff --git a/components/variations/variations_http_header_provider.h b/components/variations/variations_http_header_provider.h
index 349fea9..184766d6 100644
--- a/components/variations/variations_http_header_provider.h
+++ b/components/variations/variations_http_header_provider.h
@@ -7,6 +7,7 @@
 
 #include <set>
 #include <string>
+#include <utility>
 #include <vector>
 
 #include "base/gtest_prod_util.h"
@@ -32,12 +33,15 @@
   static VariationsHttpHeaderProvider* GetInstance();
 
   // Returns the value of the client data header, computing and caching it if
-  // necessary.
-  std::string GetClientDataHeader();
+  // necessary. If |is_signed_in| is false, variation ids that should only be
+  // sent for signed in users (i.e. GOOGLE_WEB_PROPERTIES_SIGNED_IN entries)
+  // will not be included.
+  std::string GetClientDataHeader(bool is_signed_in);
 
   // Returns a space-separated string containing the list of current active
   // variations (as would be reported in the |variation_id| repeated field of
-  // the ClientVariations proto). The returned string is guaranteed to have a
+  // the ClientVariations proto). Does not include variation ids that should be
+  // sent for signed-in users only. The returned string is guaranteed to have a
   // a leading and trailing space, e.g. " 123 234 345 ".
   std::string GetVariationsString();
 
@@ -61,6 +65,8 @@
  private:
   friend struct base::DefaultSingletonTraits<VariationsHttpHeaderProvider>;
 
+  typedef std::pair<VariationID, IDCollectionKey> VariationIDEntry;
+
   FRIEND_TEST_ALL_PREFIXES(VariationsHttpHeaderProviderTest,
                            SetDefaultVariationIds_Valid);
   FRIEND_TEST_ALL_PREFIXES(VariationsHttpHeaderProviderTest,
@@ -88,35 +94,43 @@
   // new variation IDs.
   void InitVariationIDsCacheIfNeeded();
 
+  // Looks up the associated id for the given trial/group and adds an entry for
+  // it to |variation_ids_set_| if found.
+  void CacheVariationsId(const std::string& trial_name,
+                         const std::string& group_name,
+                         IDCollectionKey key);
+
   // Takes whatever is currently in |variation_ids_set_| and recreates
   // |variation_ids_header_| with it.  Assumes the the |lock_| is currently
   // held.
   void UpdateVariationIDsHeaderValue();
 
+  // Generates a base64-encoded proto to be used as a header value for the given
+  // |is_signed_in| state.
+  std::string GenerateBase64EncodedProto(bool is_signed_in);
+
   // Returns the currently active set of variation ids, which includes any
   // default values, synthetic variations and actual field trial variations.
-  std::set<VariationID> GetAllVariationIds();
+  std::set<VariationIDEntry> GetAllVariationIds();
 
-  // Guards |variation_ids_cache_initialized_|, |variation_ids_set_| and
-  // |variation_ids_header_|.
+  // Guards access to variables below.
   base::Lock lock_;
 
-  // Whether or not we've initialized the cache.
+  // Whether or not we've initialized the caches.
   bool variation_ids_cache_initialized_;
 
   // Keep a cache of variation IDs that are transmitted in headers to Google.
   // This consists of a list of valid IDs, and the actual transmitted header.
-  std::set<VariationID> variation_ids_set_;
-  std::set<VariationID> variation_trigger_ids_set_;
+  std::set<VariationIDEntry> variation_ids_set_;
 
   // Provides the google experiment ids forced from command line.
-  std::set<VariationID> default_variation_ids_set_;
-  std::set<VariationID> default_trigger_id_set_;
+  std::set<VariationIDEntry> default_variation_ids_set_;
 
   // Variations ids from synthetic field trials.
-  std::set<VariationID> synthetic_variation_ids_set_;
+  std::set<VariationIDEntry> synthetic_variation_ids_set_;
 
-  std::string variation_ids_header_;
+  std::string cached_variation_ids_header_;
+  std::string cached_variation_ids_header_signed_in_;
 
   DISALLOW_COPY_AND_ASSIGN(VariationsHttpHeaderProvider);
 };
diff --git a/components/variations/variations_http_header_provider_unittest.cc b/components/variations/variations_http_header_provider_unittest.cc
index a1b9d3da..394310a 100644
--- a/components/variations/variations_http_header_provider_unittest.cc
+++ b/components/variations/variations_http_header_provider_unittest.cc
@@ -67,7 +67,7 @@
   // Valid experiment ids.
   EXPECT_TRUE(provider.SetDefaultVariationIds({"12", "456", "t789"}));
   provider.InitVariationIDsCacheIfNeeded();
-  std::string variations = provider.GetClientDataHeader();
+  std::string variations = provider.GetClientDataHeader(false);
   EXPECT_FALSE(variations.empty());
   std::set<VariationID> variation_ids;
   std::set<VariationID> trigger_ids;
@@ -86,13 +86,13 @@
   EXPECT_FALSE(provider.SetDefaultVariationIds(
       std::vector<std::string>{"abcd12", "456"}));
   provider.InitVariationIDsCacheIfNeeded();
-  EXPECT_TRUE(provider.GetClientDataHeader().empty());
+  EXPECT_TRUE(provider.GetClientDataHeader(false).empty());
 
   // Invalid trigger experiment id
   EXPECT_FALSE(provider.SetDefaultVariationIds(
       std::vector<std::string>{"12", "tabc456"}));
   provider.InitVariationIDsCacheIfNeeded();
-  EXPECT_TRUE(provider.GetClientDataHeader().empty());
+  EXPECT_TRUE(provider.GetClientDataHeader(false).empty());
 }
 
 TEST_F(VariationsHttpHeaderProviderTest, OnFieldTrialGroupFinalized) {
@@ -104,25 +104,44 @@
   const std::string default_name = "default";
   scoped_refptr<base::FieldTrial> trial_1(CreateTrialAndAssociateId(
       "t1", default_name, GOOGLE_WEB_PROPERTIES, 123));
-
   ASSERT_EQ(default_name, trial_1->group_name());
 
   scoped_refptr<base::FieldTrial> trial_2(CreateTrialAndAssociateId(
       "t2", default_name, GOOGLE_WEB_PROPERTIES_TRIGGER, 456));
-
   ASSERT_EQ(default_name, trial_2->group_name());
 
+  scoped_refptr<base::FieldTrial> trial_3(CreateTrialAndAssociateId(
+      "t3", default_name, GOOGLE_WEB_PROPERTIES_SIGNED_IN, 789));
+  ASSERT_EQ(default_name, trial_3->group_name());
+
   // Run the message loop to make sure OnFieldTrialGroupFinalized is called for
   // the two field trials.
   base::RunLoop().RunUntilIdle();
 
-  std::string variations = provider.GetClientDataHeader();
+  // Get non-signed in ids.
+  {
+    std::string variations = provider.GetClientDataHeader(false);
+    std::set<VariationID> variation_ids;
+    std::set<VariationID> trigger_ids;
+    ASSERT_TRUE(ExtractVariationIds(variations, &variation_ids, &trigger_ids));
+    EXPECT_EQ(1U, variation_ids.size());
+    EXPECT_TRUE(variation_ids.find(123) != variation_ids.end());
+    EXPECT_EQ(1U, trigger_ids.size());
+    EXPECT_TRUE(trigger_ids.find(456) != trigger_ids.end());
+  }
 
-  std::set<VariationID> variation_ids;
-  std::set<VariationID> trigger_ids;
-  ASSERT_TRUE(ExtractVariationIds(variations, &variation_ids, &trigger_ids));
-  EXPECT_TRUE(variation_ids.find(123) != variation_ids.end());
-  EXPECT_TRUE(trigger_ids.find(456) != trigger_ids.end());
+  // Now, get signed-in ids.
+  {
+    std::string variations = provider.GetClientDataHeader(true);
+    std::set<VariationID> variation_ids;
+    std::set<VariationID> trigger_ids;
+    ASSERT_TRUE(ExtractVariationIds(variations, &variation_ids, &trigger_ids));
+    EXPECT_EQ(2U, variation_ids.size());
+    EXPECT_TRUE(variation_ids.find(123) != variation_ids.end());
+    EXPECT_TRUE(variation_ids.find(789) != variation_ids.end());
+    EXPECT_EQ(1U, trigger_ids.size());
+    EXPECT_TRUE(trigger_ids.find(456) != trigger_ids.end());
+  }
 }
 
 TEST_F(VariationsHttpHeaderProviderTest, GetVariationsString) {
@@ -131,6 +150,8 @@
 
   CreateTrialAndAssociateId("t1", "g1", GOOGLE_WEB_PROPERTIES, 123);
   CreateTrialAndAssociateId("t2", "g2", GOOGLE_WEB_PROPERTIES, 124);
+  // SIGNED_IN ids shouldn't be included.
+  CreateTrialAndAssociateId("t3", "g3", GOOGLE_WEB_PROPERTIES_SIGNED_IN, 125);
 
   VariationsHttpHeaderProvider provider;
   std::vector<std::string> ids;
diff --git a/content/app/content_main_runner.cc b/content/app/content_main_runner.cc
index 929756b..604acb0 100644
--- a/content/app/content_main_runner.cc
+++ b/content/app/content_main_runner.cc
@@ -453,6 +453,10 @@
   int Initialize(const ContentMainParams& params) override {
     ui_task_ = params.ui_task;
 
+#if defined(USE_AURA)
+    env_mode_ = params.env_mode;
+#endif
+
     base::EnableTerminationOnOutOfMemory();
 #if defined(OS_WIN)
     base::win::RegisterInvalidParamHandler();
@@ -782,6 +786,9 @@
 #elif defined(OS_MACOSX)
     main_params.autorelease_pool = autorelease_pool_.get();
 #endif
+#if defined(USE_AURA)
+    main_params.env_mode = env_mode_;
+#endif
 
     return RunNamedProcessTypeMain(process_type, main_params, delegate_);
   }
@@ -840,6 +847,10 @@
 
   base::Closure* ui_task_;
 
+#if defined(USE_AURA)
+  aura::Env::Mode env_mode_ = aura::Env::Mode::LOCAL;
+#endif
+
   DISALLOW_COPY_AND_ASSIGN(ContentMainRunnerImpl);
 };
 
diff --git a/content/browser/bluetooth/bluetooth_device_chooser_controller.cc b/content/browser/bluetooth/bluetooth_device_chooser_controller.cc
index 5d444c8..6a0e22a8 100644
--- a/content/browser/bluetooth/bluetooth_device_chooser_controller.cc
+++ b/content/browser/bluetooth/bluetooth_device_chooser_controller.cc
@@ -30,19 +30,45 @@
 
 namespace {
 
-// Anything worse than or equal to this will show 0 bars.
-const int kMinRSSI = -100;
-// Anything better than or equal to this will show the maximum bars.
-const int kMaxRSSI = -55;
-// Number of RSSI levels used in the signal strength image.
-const int kNumSignalStrengthLevels = 5;
-
-const content::UMARSSISignalStrengthLevel kRSSISignalStrengthEnumTable[] = {
-    content::UMARSSISignalStrengthLevel::LEVEL_0,
-    content::UMARSSISignalStrengthLevel::LEVEL_1,
-    content::UMARSSISignalStrengthLevel::LEVEL_2,
-    content::UMARSSISignalStrengthLevel::LEVEL_3,
-    content::UMARSSISignalStrengthLevel::LEVEL_4};
+// Signal Strength Display Notes:
+//
+// RSSI values are displayed by the chooser to empower a user to differentiate
+// between multiple devices with the same name, comparing devices with different
+// names is a secondary goal. It is important that a user is able to move closer
+// and farther away from a device and have it transition between two different
+// signal strength levels, thus we want to spread RSSI values out evenly accross
+// displayed levels.
+//
+// RSSI values from UMA in RecordRSSISignalStrength are charted here:
+// https://goo.gl/photos/pCoAkF7mPyza9B1k7 (2016-12-08)
+// with a copy-paste of table data at every 5dBm:
+//  dBm   CDF* Histogram Bucket Quantity (hand drawn estimate)
+// -100 00.0%  -
+//  -95 00.4%  --
+//  -90 01.9%  ---
+//  -85 05.1%  ---
+//  -80 09.2%  ----
+//  -75 14.9%  -----
+//  -70 22.0%  ------
+//  -65 32.4%  --------
+//  -60 47.9%  ---------
+//  -55 60.4%  --------
+//  -50 72.8%  ---------
+//  -45 85.5%  -------
+//  -40 94.5%  -----
+//  -35 97.4%  ---
+//  -30 99.0%  --
+//  -25 99.7%  -
+//
+// CDF: Cumulative Distribution Function:
+// https://en.wikipedia.org/wiki/Cumulative_distribution_function
+//
+// Conversion to signal strengths is done by selecting 4 threshold points
+// equally spaced through the CDF.
+const int k20thPercentileRSSI = -71;
+const int k40thPercentileRSSI = -63;
+const int k60thPercentileRSSI = -55;
+const int k80thPercentileRSSI = -47;
 
 }  // namespace
 
@@ -436,24 +462,22 @@
     int8_t rssi) {
   RecordRSSISignalStrength(rssi);
 
-  if (rssi <= kMinRSSI) {
-    RecordRSSISignalStrengthLevel(
-        UMARSSISignalStrengthLevel::LESS_THAN_OR_EQUAL_TO_MIN_RSSI);
+  if (rssi < k20thPercentileRSSI) {
+    RecordRSSISignalStrengthLevel(content::UMARSSISignalStrengthLevel::LEVEL_0);
     return 0;
+  } else if (rssi < k40thPercentileRSSI) {
+    RecordRSSISignalStrengthLevel(content::UMARSSISignalStrengthLevel::LEVEL_1);
+    return 1;
+  } else if (rssi < k60thPercentileRSSI) {
+    RecordRSSISignalStrengthLevel(content::UMARSSISignalStrengthLevel::LEVEL_2);
+    return 2;
+  } else if (rssi < k80thPercentileRSSI) {
+    RecordRSSISignalStrengthLevel(content::UMARSSISignalStrengthLevel::LEVEL_3);
+    return 3;
+  } else {
+    RecordRSSISignalStrengthLevel(content::UMARSSISignalStrengthLevel::LEVEL_4);
+    return 4;
   }
-
-  if (rssi >= kMaxRSSI) {
-    RecordRSSISignalStrengthLevel(
-        UMARSSISignalStrengthLevel::GREATER_THAN_OR_EQUAL_TO_MAX_RSSI);
-    return kNumSignalStrengthLevels - 1;
-  }
-
-  double input_range = kMaxRSSI - kMinRSSI;
-  double output_range = kNumSignalStrengthLevels - 1;
-  int level = static_cast<int>((rssi - kMinRSSI) * output_range / input_range);
-  DCHECK(kNumSignalStrengthLevels == arraysize(kRSSISignalStrengthEnumTable));
-  RecordRSSISignalStrengthLevel(kRSSISignalStrengthEnumTable[level]);
-  return level;
 }
 
 void BluetoothDeviceChooserController::SetTestScanDurationForTesting() {
diff --git a/content/browser/bluetooth/bluetooth_device_chooser_controller_unittest.cc b/content/browser/bluetooth/bluetooth_device_chooser_controller_unittest.cc
index 59f06ef..42e689d8 100644
--- a/content/browser/bluetooth/bluetooth_device_chooser_controller_unittest.cc
+++ b/content/browser/bluetooth/bluetooth_device_chooser_controller_unittest.cc
@@ -13,23 +13,25 @@
   EXPECT_EQ(
       0, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-128));
   EXPECT_EQ(
-      0, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-100));
+      0, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-72));
+
   EXPECT_EQ(
-      0, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-89));
+      1, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-71));
   EXPECT_EQ(
-      1, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-88));
+      1, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-64));
+
   EXPECT_EQ(
-      1, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-78));
+      2, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-63));
   EXPECT_EQ(
-      2, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-77));
+      2, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-56));
+
   EXPECT_EQ(
-      2, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-67));
+      3, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-55));
   EXPECT_EQ(
-      3, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-66));
+      3, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-48));
+
   EXPECT_EQ(
-      3, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-56));
-  EXPECT_EQ(
-      4, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-55));
+      4, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-47));
   EXPECT_EQ(
       4, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(127));
 }
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc
index e76edcb..9159fb8 100644
--- a/content/browser/browser_main_loop.cc
+++ b/content/browser/browser_main_loop.cc
@@ -1577,7 +1577,7 @@
 
   // Env creates the compositor. Aura widgets need the compositor to be created
   // before they can be initialized by the browser.
-  env_ = aura::Env::CreateInstance();
+  env_ = aura::Env::CreateInstance(parameters_.env_mode);
 #endif  // defined(USE_AURA)
 
   if (parts_)
diff --git a/content/browser/compositor/OWNERS b/content/browser/compositor/OWNERS
index 1e10cf3..2817671 100644
--- a/content/browser/compositor/OWNERS
+++ b/content/browser/compositor/OWNERS
@@ -2,6 +2,6 @@
 jbauman@chromium.org
 ccameron@chromium.org
 
-per-file *Mus*=fsamuel@chromium.org
-per-file *Mus*=sadrul@chromium.org
-per-file *Mus*=rjkroege@chromium.org
+per-file *mus*=fsamuel@chromium.org
+per-file *mus*=sadrul@chromium.org
+per-file *mus*=rjkroege@chromium.org
diff --git a/content/browser/compositor/mus_browser_compositor_output_surface.cc b/content/browser/compositor/mus_browser_compositor_output_surface.cc
index ce3b426a..a274eb9b 100644
--- a/content/browser/compositor/mus_browser_compositor_output_surface.cc
+++ b/content/browser/compositor/mus_browser_compositor_output_surface.cc
@@ -32,7 +32,8 @@
     : GpuBrowserCompositorOutputSurface(std::move(context),
                                         update_vsync_parameters_callback,
                                         std::move(overlay_candidate_validator)),
-      ui_window_(window) {
+      ui_window_(window),
+      window_(nullptr) {
   ui_compositor_frame_sink_ = ui_window_->RequestCompositorFrameSink(
       ui::mojom::CompositorFrameSinkType::DEFAULT, context,
       gpu_memory_buffer_manager);
@@ -49,6 +50,7 @@
     : GpuBrowserCompositorOutputSurface(std::move(context),
                                         update_vsync_parameters_callback,
                                         std::move(overlay_candidate_validator)),
+      ui_window_(nullptr),
       window_(window) {
   aura::WindowPortMus* window_port = aura::WindowPortMus::Get(window_);
   DCHECK(window_port);
diff --git a/content/browser/devtools/protocol/devtools_protocol_browsertest.cc b/content/browser/devtools/protocol/devtools_protocol_browsertest.cc
index 75a1d71..c6e228f 100644
--- a/content/browser/devtools/protocol/devtools_protocol_browsertest.cc
+++ b/content/browser/devtools/protocol/devtools_protocol_browsertest.cc
@@ -186,16 +186,13 @@
     agent_host_->DispatchProtocolMessage(this, json_command);
     // Some messages are dispatched synchronously.
     // Only run loop if we are not finished yet.
-    if (in_dispatch_ && wait)
-      WaitForResponse();
+    if (in_dispatch_ && wait) {
+      waiting_for_command_result_id_ = last_sent_id_;
+      base::RunLoop().Run();
+    }
     in_dispatch_ = false;
   }
 
-  void WaitForResponse() {
-    waiting_for_command_result_id_ = last_sent_id_;
-    base::RunLoop().Run();
-  }
-
   bool HasValue(const std::string& path) {
     base::Value* value = 0;
     return result_->Get(path, &value);
@@ -412,26 +409,14 @@
                     int modifier,
                     int windowsKeyCode,
                     int nativeKeyCode,
-                    const std::string& key,
-                    bool wait) {
+                    const std::string& key) {
     std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue());
     params->SetString("type", type);
     params->SetInteger("modifiers", modifier);
     params->SetInteger("windowsVirtualKeyCode", windowsKeyCode);
     params->SetInteger("nativeVirtualKeyCode", nativeKeyCode);
     params->SetString("key", key);
-    SendCommand("Input.dispatchKeyEvent", std::move(params), wait);
-  }
-};
-
-class SyntheticMouseEventTest : public DevToolsProtocolTest {
- protected:
-  void SendMouseEvent(const std::string& type, int x, int y, bool wait) {
-    std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue());
-    params->SetString("type", type);
-    params->SetInteger("x", x);
-    params->SetInteger("y", y);
-    SendCommand("Input.dispatchMouseEvent", std::move(params), wait);
+    SendCommand("Input.dispatchKeyEvent", std::move(params));
   }
 };
 
@@ -450,8 +435,8 @@
   DOMMessageQueue dom_message_queue;
 
   // Send enter (keycode 13).
-  SendKeyEvent("rawKeyDown", 0, 13, 13, "Enter", true);
-  SendKeyEvent("keyUp", 0, 13, 13, "Enter", true);
+  SendKeyEvent("rawKeyDown", 0, 13, 13, "Enter");
+  SendKeyEvent("keyUp", 0, 13, 13, "Enter");
 
   std::string key;
   ASSERT_TRUE(dom_message_queue.WaitForMessage(&key));
@@ -460,8 +445,8 @@
   EXPECT_EQ("\"Enter\"", key);
 
   // Send escape (keycode 27).
-  SendKeyEvent("rawKeyDown", 0, 27, 27, "Escape", true);
-  SendKeyEvent("keyUp", 0, 27, 27, "Escape", true);
+  SendKeyEvent("rawKeyDown", 0, 27, 27, "Escape");
+  SendKeyEvent("keyUp", 0, 27, 27, "Escape");
 
   ASSERT_TRUE(dom_message_queue.WaitForMessage(&key));
   EXPECT_EQ("\"Escape\"", key);
@@ -469,59 +454,6 @@
   EXPECT_EQ("\"Escape\"", key);
 }
 
-IN_PROC_BROWSER_TEST_F(SyntheticKeyEventTest, KeyboardEventAck) {
-  NavigateToURLBlockUntilNavigationsComplete(shell(), GURL("about:blank"), 1);
-  Attach();
-  ASSERT_TRUE(content::ExecuteScript(
-      shell()->web_contents()->GetRenderViewHost(),
-      "document.body.addEventListener('keydown', () => console.log('x'));"));
-
-  scoped_refptr<InputMsgWatcher> filter = new InputMsgWatcher(
-      RenderWidgetHostImpl::From(
-          shell()->web_contents()->GetRenderViewHost()->GetWidget()),
-      blink::WebInputEvent::MouseMove);
-
-  SendCommand("Runtime.enable", nullptr);
-  SendKeyEvent("rawKeyDown", 0, 13, 13, "Enter", false);
-
-  // We expect that the console log message event arrives *before* the input
-  // event ack, and the subsequent command response for Input.dispatchKeyEvent.
-  WaitForNotification("Runtime.consoleAPICalled");
-  EXPECT_THAT(console_messages_, ElementsAre("x"));
-  EXPECT_FALSE(filter->HasReceivedAck());
-  EXPECT_EQ(1u, result_ids_.size());
-
-  WaitForResponse();
-  EXPECT_EQ(2u, result_ids_.size());
-}
-
-IN_PROC_BROWSER_TEST_F(SyntheticMouseEventTest, MouseEventAck) {
-  NavigateToURLBlockUntilNavigationsComplete(shell(), GURL("about:blank"), 1);
-  Attach();
-  ASSERT_TRUE(content::ExecuteScript(
-      shell()->web_contents()->GetRenderViewHost(),
-      "document.body.addEventListener('mousemove', () => console.log('x'));"));
-
-  scoped_refptr<InputMsgWatcher> filter = new InputMsgWatcher(
-      RenderWidgetHostImpl::From(
-          shell()->web_contents()->GetRenderViewHost()->GetWidget()),
-      blink::WebInputEvent::MouseMove);
-
-  SendCommand("Runtime.enable", nullptr);
-  SendMouseEvent("mouseMoved", 15, 15, false);
-
-  // We expect that the console log message event arrives *before* the input
-  // event ack, and the subsequent command response for
-  // Input.dispatchMouseEvent.
-  WaitForNotification("Runtime.consoleAPICalled");
-  EXPECT_THAT(console_messages_, ElementsAre("x"));
-  EXPECT_FALSE(filter->HasReceivedAck());
-  EXPECT_EQ(1u, result_ids_.size());
-
-  WaitForResponse();
-  EXPECT_EQ(2u, result_ids_.size());
-}
-
 namespace {
 bool DecodePNG(std::string base64_data, SkBitmap* bitmap) {
   std::string png_data;
diff --git a/content/browser/devtools/protocol/devtools_protocol_handler_generator.py b/content/browser/devtools/protocol/devtools_protocol_handler_generator.py
index 45fc22d..ca6f1ca8 100755
--- a/content/browser/devtools/protocol/devtools_protocol_handler_generator.py
+++ b/content/browser/devtools/protocol/devtools_protocol_handler_generator.py
@@ -663,8 +663,6 @@
     "Network.getCookies",
     "Network.deleteCookie",
     "Network.setCookie",
-    "Input.dispatchKeyEvent",
-    "Input.dispatchMouseEvent",
     "Input.synthesizePinchGesture",
     "Input.synthesizeScrollGesture",
     "Input.synthesizeTapGesture"]
diff --git a/content/browser/devtools/protocol/input_handler.cc b/content/browser/devtools/protocol/input_handler.cc
index 1c0526f..b963044 100644
--- a/content/browser/devtools/protocol/input_handler.cc
+++ b/content/browser/devtools/protocol/input_handler.cc
@@ -130,7 +130,6 @@
 
 InputHandler::InputHandler()
     : host_(NULL),
-      input_queued_(false),
       page_scale_factor_(1.0),
       weak_factory_(this) {
 }
@@ -138,30 +137,8 @@
 InputHandler::~InputHandler() {
 }
 
-void InputHandler::OnInputEvent(const blink::WebInputEvent& event) {
-  input_queued_ = true;
-}
-
-void InputHandler::OnInputEventAck(const blink::WebInputEvent& event) {
-  if (blink::WebInputEvent::isKeyboardEventType(event.type) &&
-      !pending_key_command_ids_.empty()) {
-    SendDispatchKeyEventResponse(pending_key_command_ids_.front());
-    pending_key_command_ids_.pop_front();
-  } else if (blink::WebInputEvent::isMouseEventType(event.type) &&
-             !pending_mouse_command_ids_.empty()) {
-    SendDispatchMouseEventResponse(pending_mouse_command_ids_.front());
-    pending_mouse_command_ids_.pop_front();
-  }
-}
-
 void InputHandler::SetRenderWidgetHost(RenderWidgetHostImpl* host) {
-  ClearPendingKeyCommands();
-  ClearPendingMouseCommands();
-  if (host_)
-    host_->RemoveInputEventObserver(this);
   host_ = host;
-  if (host)
-    host->AddInputEventObserver(this);
 }
 
 void InputHandler::SetClient(std::unique_ptr<Client> client) {
@@ -174,15 +151,7 @@
   scrollable_viewport_size_ = frame_metadata.scrollable_viewport_size;
 }
 
-void InputHandler::Detached() {
-  ClearPendingKeyCommands();
-  ClearPendingMouseCommands();
-  if (host_)
-    host_->RemoveInputEventObserver(this);
-}
-
 Response InputHandler::DispatchKeyEvent(
-    DevToolsCommandId command_id,
     const std::string& type,
     const int* modifiers,
     const double* timestamp,
@@ -244,17 +213,11 @@
     return Response::ServerError("Could not connect to view");
 
   host_->Focus();
-  input_queued_ = false;
   host_->ForwardKeyboardEvent(event);
-  if (input_queued_)
-    pending_key_command_ids_.push_back(command_id);
-  else
-    SendDispatchKeyEventResponse(command_id);
   return Response::OK();
 }
 
 Response InputHandler::DispatchMouseEvent(
-    DevToolsCommandId command_id,
     const std::string& type,
     int x,
     int y,
@@ -286,12 +249,7 @@
     return Response::ServerError("Could not connect to view");
 
   host_->Focus();
-  input_queued_ = false;
   host_->ForwardMouseEvent(event);
-  if (input_queued_)
-    pending_mouse_command_ids_.push_back(command_id);
-  else
-    SendDispatchMouseEventResponse(command_id);
   return Response::OK();
 }
 
@@ -521,17 +479,6 @@
   return Response::FallThrough();
 }
 
-void InputHandler::SendDispatchKeyEventResponse(DevToolsCommandId command_id) {
-  client_->SendDispatchKeyEventResponse(
-      command_id, DispatchKeyEventResponse::Create());
-}
-
-void InputHandler::SendDispatchMouseEventResponse(
-    DevToolsCommandId command_id) {
-  client_->SendDispatchMouseEventResponse(
-      command_id, DispatchMouseEventResponse::Create());
-}
-
 void InputHandler::SendSynthesizePinchGestureResponse(
     DevToolsCommandId command_id,
     SyntheticGesture::Result result) {
@@ -574,18 +521,6 @@
   }
 }
 
-void InputHandler::ClearPendingKeyCommands() {
-  for (const DevToolsCommandId& command_id : pending_key_command_ids_)
-    SendDispatchKeyEventResponse(command_id);
-  pending_key_command_ids_.clear();
-}
-
-void InputHandler::ClearPendingMouseCommands() {
-  for (const DevToolsCommandId& command_id : pending_mouse_command_ids_)
-    SendDispatchMouseEventResponse(command_id);
-  pending_mouse_command_ids_.clear();
-}
-
 }  // namespace input
 }  // namespace devtools
 }  // namespace content
diff --git a/content/browser/devtools/protocol/input_handler.h b/content/browser/devtools/protocol/input_handler.h
index e98c527..691cad2 100644
--- a/content/browser/devtools/protocol/input_handler.h
+++ b/content/browser/devtools/protocol/input_handler.h
@@ -10,7 +10,6 @@
 #include "content/browser/devtools/protocol/devtools_protocol_dispatcher.h"
 #include "content/browser/renderer_host/input/synthetic_gesture.h"
 #include "content/common/input/synthetic_smooth_scroll_gesture_params.h"
-#include "content/public/browser/render_widget_host.h"
 #include "ui/gfx/geometry/size_f.h"
 
 namespace cc {
@@ -24,20 +23,18 @@
 namespace devtools {
 namespace input {
 
-class InputHandler : public RenderWidgetHost::InputEventObserver {
+class InputHandler {
  public:
   typedef DevToolsProtocolClient::Response Response;
 
   InputHandler();
-  ~InputHandler() override;
+  virtual ~InputHandler();
 
   void SetRenderWidgetHost(RenderWidgetHostImpl* host);
   void SetClient(std::unique_ptr<Client> client);
   void OnSwapCompositorFrame(const cc::CompositorFrameMetadata& frame_metadata);
-  void Detached();
 
-  Response DispatchKeyEvent(DevToolsCommandId command_id,
-                            const std::string& type,
+  Response DispatchKeyEvent(const std::string& type,
                             const int* modifiers,
                             const double* timestamp,
                             const std::string* text,
@@ -51,8 +48,7 @@
                             const bool* is_keypad,
                             const bool* is_system_key);
 
-  Response DispatchMouseEvent(DevToolsCommandId command_id,
-                              const std::string& type,
+  Response DispatchMouseEvent(const std::string& type,
                               int x,
                               int y,
                               const int* modifiers,
@@ -105,13 +101,6 @@
       const double* timestamp);
 
  private:
-  // InputEventObserver
-  void OnInputEvent(const blink::WebInputEvent& event) override;
-  void OnInputEventAck(const blink::WebInputEvent& event) override;
-
-  void SendDispatchKeyEventResponse(DevToolsCommandId command_id);
-  void SendDispatchMouseEventResponse(DevToolsCommandId command_id);
-
   void SendSynthesizePinchGestureResponse(DevToolsCommandId command_id,
                                           SyntheticGesture::Result result);
 
@@ -136,16 +125,8 @@
                         DevToolsCommandId command_id,
                         SyntheticGesture::Result result);
 
-  void ClearPendingKeyCommands();
-  void ClearPendingMouseCommands();
-
   RenderWidgetHostImpl* host_;
   std::unique_ptr<Client> client_;
-  // DevToolsCommandIds for calls to Input.dispatchKey/MouseEvent that have been
-  // sent to the renderer, but that we haven't yet received an ack for.
-  bool input_queued_;
-  std::deque<DevToolsCommandId> pending_key_command_ids_;
-  std::deque<DevToolsCommandId> pending_mouse_command_ids_;
   float page_scale_factor_;
   gfx::SizeF scrollable_viewport_size_;
   base::WeakPtrFactory<InputHandler> weak_factory_;
diff --git a/content/browser/devtools/render_frame_devtools_agent_host.cc b/content/browser/devtools/render_frame_devtools_agent_host.cc
index 43253f6f9..dd1ee7ad 100644
--- a/content/browser/devtools/render_frame_devtools_agent_host.cc
+++ b/content/browser/devtools/render_frame_devtools_agent_host.cc
@@ -584,7 +584,6 @@
     emulation_handler_->Detached();
   if (page_handler_)
     page_handler_->Detached();
-  input_handler_->Detached();
   service_worker_handler_->Detached();
   target_handler_->Detached();
   frame_trace_recorder_.reset();
diff --git a/content/browser/frame_host/render_widget_host_view_child_frame.cc b/content/browser/frame_host/render_widget_host_view_child_frame.cc
index 56e95b8..a574092 100644
--- a/content/browser/frame_host/render_widget_host_view_child_frame.cc
+++ b/content/browser/frame_host/render_widget_host_view_child_frame.cc
@@ -543,9 +543,14 @@
     const gfx::Point& point,
     RenderWidgetHostViewBase* target_view,
     gfx::Point* transformed_point) {
-  if (!frame_connector_ || !local_frame_id_.is_valid() || target_view == this)
+  if (!frame_connector_ || !local_frame_id_.is_valid())
     return false;
 
+  if (target_view == this) {
+    *transformed_point = point;
+    return true;
+  }
+
   return frame_connector_->TransformPointToCoordSpaceForView(
       point, target_view, cc::SurfaceId(frame_sink_id_, local_frame_id_),
       transformed_point);
diff --git a/content/browser/indexed_db/indexed_db_database_unittest.cc b/content/browser/indexed_db/indexed_db_database_unittest.cc
index 5d85503..953b720 100644
--- a/content/browser/indexed_db/indexed_db_database_unittest.cc
+++ b/content/browser/indexed_db/indexed_db_database_unittest.cc
@@ -377,6 +377,10 @@
 
   void RunPostedTasks() { base::RunLoop().RunUntilIdle(); }
 
+private:
+  // Needs to outlive |db_|.
+  content::TestBrowserThreadBundle thread_bundle_;
+
  protected:
   scoped_refptr<IndexedDBFakeBackingStore> backing_store_;
   scoped_refptr<IndexedDBDatabase> db_;
@@ -389,7 +393,6 @@
 
  private:
   scoped_refptr<MockIndexedDBFactory> factory_;
-  content::TestBrowserThreadBundle thread_bundle_;
 
   DISALLOW_COPY_AND_ASSIGN(IndexedDBDatabaseOperationTest);
 };
diff --git a/content/browser/renderer_host/input/gesture_event_queue.cc b/content/browser/renderer_host/input/gesture_event_queue.cc
index a0a80e3..6952862 100644
--- a/content/browser/renderer_host/input/gesture_event_queue.cc
+++ b/content/browser/renderer_host/input/gesture_event_queue.cc
@@ -163,6 +163,9 @@
     case WebInputEvent::GestureTapCancel:
     case WebInputEvent::GestureTap:
     case WebInputEvent::GestureDoubleTap:
+    case WebInputEvent::GestureLongPress:
+    case WebInputEvent::GestureLongTap:
+    case WebInputEvent::GestureTwoFingerTap:
       if (gesture_event.event.sourceDevice ==
           blink::WebGestureDeviceTouchscreen) {
         return !touchscreen_tap_suppression_controller_.FilterTapEvent(
diff --git a/content/browser/renderer_host/input/input_router_config_helper.cc b/content/browser/renderer_host/input/input_router_config_helper.cc
index 53aaee3..a41f0ec 100644
--- a/content/browser/renderer_host/input/input_router_config_helper.cc
+++ b/content/browser/renderer_host/input/input_router_config_helper.cc
@@ -49,9 +49,16 @@
   config.touchscreen_tap_suppression_config.max_cancel_to_down_time =
       base::TimeDelta::FromMilliseconds(
           gesture_config->fling_max_cancel_to_down_time_in_ms());
+
+  // Tap suppression controller forwards the stashed tapDown and drops the rest
+  // of the stashed events when the tapDownTimer expires. If a fling cancel ack
+  // with |processed = false| arrives before the timer expiration, all stashed
+  // events will be forwarded. The timer is used to avoid waiting for an
+  // arbitrarily late fling cancel ack. Its delay should be large enough for
+  // a long press to get stashed and forwarded if needed.
   config.touchscreen_tap_suppression_config.max_tap_gap_time =
       base::TimeDelta::FromMilliseconds(
-          gesture_config->long_press_time_in_ms());
+          gesture_config->long_press_time_in_ms() + 50);
 
   config.touchpad_tap_suppression_config.enabled =
       gesture_config->fling_touchpad_tap_suppression_enabled();
diff --git a/content/browser/renderer_host/input/tap_suppression_controller.cc b/content/browser/renderer_host/input/tap_suppression_controller.cc
index 78b3a07..008feb2 100644
--- a/content/browser/renderer_host/input/tap_suppression_controller.cc
+++ b/content/browser/renderer_host/input/tap_suppression_controller.cc
@@ -7,13 +7,27 @@
 #include "base/logging.h"
 #include "base/trace_event/trace_event.h"
 #include "content/browser/renderer_host/input/tap_suppression_controller_client.h"
+#include "ui/events/gesture_detection/gesture_configuration.h"
 
 namespace content {
 
+// The tapDownTimer is used to avoid waiting for an arbitrarily late fling
+// cancel ack. While the timer is running, if a fling cancel ack with
+// |Processed = false| arrives, all stashed gesture events get forwarded. If
+// the timer expires, the controller forwards stashed GestureTapDown only, and
+// drops the rest of the stashed events. The timer delay should be large enough
+// for a GestureLongPress to get stashed and forwarded if needed. It's still
+// possible for a GestureLongPress to arrive after the timer expiration. In
+// this case, it will be suppressed if the controller is in SUPPRESSING_TAPS
+// state.
+
 TapSuppressionController::Config::Config()
     : enabled(false),
-      max_cancel_to_down_time(base::TimeDelta::FromMilliseconds(180)),
-      max_tap_gap_time(base::TimeDelta::FromMilliseconds(500)) {
+      max_cancel_to_down_time(base::TimeDelta::FromMilliseconds(180)) {
+  ui::GestureConfiguration* gesture_config =
+      ui::GestureConfiguration::GetInstance();
+  max_tap_gap_time = base::TimeDelta::FromMilliseconds(
+      gesture_config->long_press_time_in_ms() + 50);
 }
 
 TapSuppressionController::TapSuppressionController(
@@ -34,6 +48,7 @@
     case NOTHING:
     case GFC_IN_PROGRESS:
     case LAST_CANCEL_STOPPED_FLING:
+    case SUPPRESSING_TAPS:
       state_ = GFC_IN_PROGRESS;
       break;
     case TAP_DOWN_STASHED:
@@ -46,6 +61,7 @@
   switch (state_) {
     case DISABLED:
     case NOTHING:
+    case SUPPRESSING_TAPS:
       break;
     case GFC_IN_PROGRESS:
       if (processed)
@@ -57,7 +73,9 @@
         TRACE_EVENT0("browser",
                      "TapSuppressionController::GestureFlingCancelAck");
         StopTapDownTimer();
-        client_->ForwardStashedTapDown();
+        // If the fling cancel is not processed, forward all stashed
+        // gesture events.
+        client_->ForwardStashedGestureEvents();
         state_ = NOTHING;
       }  // Else waiting for the timer to release the stashed tap down.
       break;
@@ -89,6 +107,10 @@
         state_ = NOTHING;
         return false;
       }
+    // Stop suppressing tap end events.
+    case SUPPRESSING_TAPS:
+      state_ = NOTHING;
+      return false;
   }
   NOTREACHED() << "Invalid state";
   return false;
@@ -101,12 +123,17 @@
     case GFC_IN_PROGRESS:
       return false;
     case TAP_DOWN_STASHED:
-      state_ = NOTHING;
+      // A tap cancel happens before long tap and two finger tap events. To
+      // drop the latter events as well as the tap cancel, change the state
+      // to "SUPPRESSING_TAPS" when the stashed tap down is dropped.
+      state_ = SUPPRESSING_TAPS;
       StopTapDownTimer();
       client_->DropStashedTapDown();
       return true;
     case LAST_CANCEL_STOPPED_FLING:
       NOTREACHED() << "Invalid tap end on LAST_CANCEL_STOPPED_FLING state";
+    case SUPPRESSING_TAPS:
+      return true;
   }
   return false;
 }
@@ -128,6 +155,7 @@
   switch (state_) {
     case DISABLED:
     case NOTHING:
+    case SUPPRESSING_TAPS:
       NOTREACHED() << "Timer fired on invalid state.";
       break;
     case GFC_IN_PROGRESS:
@@ -138,8 +166,10 @@
     case TAP_DOWN_STASHED:
       TRACE_EVENT0("browser",
                    "TapSuppressionController::TapDownTimerExpired");
+      // When the timer expires, only forward the stashed tap down event, and
+      // drop other stashed gesture events (show press or long press).
       client_->ForwardStashedTapDown();
-      state_ = NOTHING;
+      state_ = SUPPRESSING_TAPS;
       break;
   }
 }
diff --git a/content/browser/renderer_host/input/tap_suppression_controller.h b/content/browser/renderer_host/input/tap_suppression_controller.h
index dc0def5..b238258b 100644
--- a/content/browser/renderer_host/input/tap_suppression_controller.h
+++ b/content/browser/renderer_host/input/tap_suppression_controller.h
@@ -70,6 +70,12 @@
     GFC_IN_PROGRESS,
     TAP_DOWN_STASHED,
     LAST_CANCEL_STOPPED_FLING,
+    // When the stashed TapDown event is dropped or forwarded due to tap down
+    // timer expiration, the controller enters the SUPPRESSING_TAPS state.
+    // This state shows that the controller will suppress LongTap,
+    // TwoFingerTap, and TapCancel gesture events until the next tapDown event
+    // arrives.
+    SUPPRESSING_TAPS,
   };
 
   TapSuppressionControllerClient* client_;
diff --git a/content/browser/renderer_host/input/tap_suppression_controller_client.h b/content/browser/renderer_host/input/tap_suppression_controller_client.h
index d55613c9..0b917a6 100644
--- a/content/browser/renderer_host/input/tap_suppression_controller_client.h
+++ b/content/browser/renderer_host/input/tap_suppression_controller_client.h
@@ -18,9 +18,14 @@
   // Called whenever the deferred tap down (if saved) should be dropped totally.
   virtual void DropStashedTapDown() = 0;
 
-  // Called whenever the deferred tap down (if saved) should be forwarded to the
-  // renderer. The tap down should go back to normal path it was
-  // on before being deferred.
+  // Called whenever the deferred tap down and other gesture events (if saved)
+  // should be forwarded to the renderer. The tap down (and possibly other
+  // gesture events) should go back to normal path they were on before being
+  // deferred.
+  virtual void ForwardStashedGestureEvents() = 0;
+
+  // Called whenever only the deferred tap down (if saved) should be forwarded
+  // to the renderer. Other saved gesture events will be dropped.
   virtual void ForwardStashedTapDown() = 0;
 
  protected:
diff --git a/content/browser/renderer_host/input/tap_suppression_controller_unittest.cc b/content/browser/renderer_host/input/tap_suppression_controller_unittest.cc
index 3dd0834..195a4962 100644
--- a/content/browser/renderer_host/input/tap_suppression_controller_unittest.cc
+++ b/content/browser/renderer_host/input/tap_suppression_controller_unittest.cc
@@ -22,6 +22,7 @@
   using TapSuppressionController::GFC_IN_PROGRESS;
   using TapSuppressionController::TAP_DOWN_STASHED;
   using TapSuppressionController::LAST_CANCEL_STOPPED_FLING;
+  using TapSuppressionController::SUPPRESSING_TAPS;
 
   enum Action {
     NONE                                 = 0,
@@ -104,6 +105,10 @@
   // TapSuppressionControllerClient implementation
   void DropStashedTapDown() override { last_actions_ |= TAP_DOWN_DROPPED; }
 
+  void ForwardStashedGestureEvents() override {
+    last_actions_ |= STASHED_TAP_DOWN_FORWARDED;
+  }
+
   void ForwardStashedTapDown() override {
     last_actions_ |= STASHED_TAP_DOWN_FORWARDED;
   }
@@ -178,7 +183,7 @@
   EXPECT_EQ(MockTapSuppressionController::TAP_UP_SUPPRESSED |
             MockTapSuppressionController::TAP_DOWN_DROPPED,
             tap_suppression_controller_->last_actions());
-  EXPECT_EQ(MockTapSuppressionController::NOTHING,
+  EXPECT_EQ(MockTapSuppressionController::SUPPRESSING_TAPS,
             tap_suppression_controller_->state());
 }
 
@@ -219,7 +224,7 @@
   EXPECT_EQ(MockTapSuppressionController::TAP_UP_SUPPRESSED |
             MockTapSuppressionController::TAP_DOWN_DROPPED,
             tap_suppression_controller_->last_actions());
-  EXPECT_EQ(MockTapSuppressionController::NOTHING,
+  EXPECT_EQ(MockTapSuppressionController::SUPPRESSING_TAPS,
             tap_suppression_controller_->state());
 }
 
@@ -252,14 +257,16 @@
   tap_suppression_controller_->AdvanceTime(TimeDelta::FromMilliseconds(13));
   EXPECT_EQ(MockTapSuppressionController::STASHED_TAP_DOWN_FORWARDED,
             tap_suppression_controller_->last_actions());
-  EXPECT_EQ(MockTapSuppressionController::NOTHING,
+  EXPECT_EQ(MockTapSuppressionController::SUPPRESSING_TAPS,
             tap_suppression_controller_->state());
 
-  // Send TapUp. This TapUp should not be suppressed.
+  // Send TapUp. This TapUp should be still suppressed.
+  // LongTap should be suppressed when the previously suppressed TapDown is
+  // forwarded because of the timer expiration.
   tap_suppression_controller_->SendTapUp();
-  EXPECT_EQ(MockTapSuppressionController::TAP_UP_FORWARDED,
+  EXPECT_EQ(MockTapSuppressionController::TAP_UP_SUPPRESSED,
             tap_suppression_controller_->last_actions());
-  EXPECT_EQ(MockTapSuppressionController::NOTHING,
+  EXPECT_EQ(MockTapSuppressionController::SUPPRESSING_TAPS,
             tap_suppression_controller_->state());
 }
 
@@ -300,7 +307,7 @@
   EXPECT_EQ(MockTapSuppressionController::TAP_UP_SUPPRESSED |
             MockTapSuppressionController::TAP_DOWN_DROPPED,
             tap_suppression_controller_->last_actions());
-  EXPECT_EQ(MockTapSuppressionController::NOTHING,
+  EXPECT_EQ(MockTapSuppressionController::SUPPRESSING_TAPS,
             tap_suppression_controller_->state());
 }
 
@@ -406,7 +413,7 @@
   EXPECT_EQ(MockTapSuppressionController::TAP_UP_SUPPRESSED |
             MockTapSuppressionController::TAP_DOWN_DROPPED,
             tap_suppression_controller_->last_actions());
-  EXPECT_EQ(MockTapSuppressionController::NOTHING,
+  EXPECT_EQ(MockTapSuppressionController::SUPPRESSING_TAPS,
             tap_suppression_controller_->state());
 }
 
@@ -447,7 +454,7 @@
   EXPECT_EQ(MockTapSuppressionController::TAP_UP_SUPPRESSED |
             MockTapSuppressionController::TAP_DOWN_DROPPED,
             tap_suppression_controller_->last_actions());
-  EXPECT_EQ(MockTapSuppressionController::NOTHING,
+  EXPECT_EQ(MockTapSuppressionController::SUPPRESSING_TAPS,
             tap_suppression_controller_->state());
 }
 
@@ -480,14 +487,16 @@
   tap_suppression_controller_->AdvanceTime(TimeDelta::FromMilliseconds(13));
   EXPECT_EQ(MockTapSuppressionController::STASHED_TAP_DOWN_FORWARDED,
             tap_suppression_controller_->last_actions());
-  EXPECT_EQ(MockTapSuppressionController::NOTHING,
+  EXPECT_EQ(MockTapSuppressionController::SUPPRESSING_TAPS,
             tap_suppression_controller_->state());
 
-  // Send TapUp. This TapUp should not be suppressed.
+  // Send TapUp. This TapUp should be still suppressed.
+  // LongTap should be suppressed when the previously suppressed TapDown is
+  // forwarded because of timer expiration.
   tap_suppression_controller_->SendTapUp();
-  EXPECT_EQ(MockTapSuppressionController::TAP_UP_FORWARDED,
+  EXPECT_EQ(MockTapSuppressionController::TAP_UP_SUPPRESSED,
             tap_suppression_controller_->last_actions());
-  EXPECT_EQ(MockTapSuppressionController::NOTHING,
+  EXPECT_EQ(MockTapSuppressionController::SUPPRESSING_TAPS,
             tap_suppression_controller_->state());
 }
 
diff --git a/content/browser/renderer_host/input/touchpad_tap_suppression_controller.cc b/content/browser/renderer_host/input/touchpad_tap_suppression_controller.cc
index d309742..dac3af2 100644
--- a/content/browser/renderer_host/input/touchpad_tap_suppression_controller.cc
+++ b/content/browser/renderer_host/input/touchpad_tap_suppression_controller.cc
@@ -37,6 +37,12 @@
 void TouchpadTapSuppressionController::DropStashedTapDown() {
 }
 
+void TouchpadTapSuppressionController::ForwardStashedGestureEvents() {
+  // Mouse downs are not handled by gesture event filter; so, they are
+  // immediately forwarded to the renderer.
+  client_->SendMouseEventImmediately(stashed_mouse_down_);
+}
+
 void TouchpadTapSuppressionController::ForwardStashedTapDown() {
   // Mouse downs are not handled by gesture event filter; so, they are
   // immediately forwarded to the renderer.
diff --git a/content/browser/renderer_host/input/touchpad_tap_suppression_controller.h b/content/browser/renderer_host/input/touchpad_tap_suppression_controller.h
index 1934ad6..88b08058 100644
--- a/content/browser/renderer_host/input/touchpad_tap_suppression_controller.h
+++ b/content/browser/renderer_host/input/touchpad_tap_suppression_controller.h
@@ -54,6 +54,7 @@
 
   // TapSuppressionControllerClient implementation.
   void DropStashedTapDown() override;
+  void ForwardStashedGestureEvents() override;
   void ForwardStashedTapDown() override;
 
   TouchpadTapSuppressionControllerClient* client_;
diff --git a/content/browser/renderer_host/input/touchscreen_tap_suppression_controller.cc b/content/browser/renderer_host/input/touchscreen_tap_suppression_controller.cc
index a5ffc01..45d5212 100644
--- a/content/browser/renderer_host/input/touchscreen_tap_suppression_controller.cc
+++ b/content/browser/renderer_host/input/touchscreen_tap_suppression_controller.cc
@@ -44,12 +44,24 @@
       stashed_show_press_.reset(new GestureEventWithLatencyInfo(event));
       return true;
 
+    case WebInputEvent::GestureLongPress:
+      // It is possible that a GestureLongPress arrives after tapDownTimer
+      // expiration, in this case it should still get filtered if the
+      // controller suppresses the tap end events.
+      if (!stashed_tap_down_)
+        return controller_.ShouldSuppressTapEnd();
+
+      stashed_long_press_.reset(new GestureEventWithLatencyInfo(event));
+      return true;
+
     case WebInputEvent::GestureTapUnconfirmed:
       return !!stashed_tap_down_;
 
     case WebInputEvent::GestureTapCancel:
     case WebInputEvent::GestureTap:
     case WebInputEvent::GestureDoubleTap:
+    case WebInputEvent::GestureLongTap:
+    case WebInputEvent::GestureTwoFingerTap:
       return controller_.ShouldSuppressTapEnd();
 
     default:
@@ -61,15 +73,27 @@
 void TouchscreenTapSuppressionController::DropStashedTapDown() {
   stashed_tap_down_.reset();
   stashed_show_press_.reset();
+  stashed_long_press_.reset();
+}
+
+void TouchscreenTapSuppressionController::ForwardStashedGestureEvents() {
+  DCHECK(stashed_tap_down_);
+  ScopedGestureEvent tap_down = std::move(stashed_tap_down_);
+  ScopedGestureEvent show_press = std::move(stashed_show_press_);
+  ScopedGestureEvent long_press = std::move(stashed_long_press_);
+  gesture_event_queue_->ForwardGestureEvent(*tap_down);
+  if (show_press)
+    gesture_event_queue_->ForwardGestureEvent(*show_press);
+  if (long_press)
+    gesture_event_queue_->ForwardGestureEvent(*long_press);
 }
 
 void TouchscreenTapSuppressionController::ForwardStashedTapDown() {
   DCHECK(stashed_tap_down_);
   ScopedGestureEvent tap_down = std::move(stashed_tap_down_);
-  ScopedGestureEvent show_press = std::move(stashed_show_press_);
   gesture_event_queue_->ForwardGestureEvent(*tap_down);
-  if (show_press)
-    gesture_event_queue_->ForwardGestureEvent(*show_press);
+  stashed_show_press_.reset();
+  stashed_long_press_.reset();
 }
 
 }  // namespace content
diff --git a/content/browser/renderer_host/input/touchscreen_tap_suppression_controller.h b/content/browser/renderer_host/input/touchscreen_tap_suppression_controller.h
index 3e7623e..c7a3039 100644
--- a/content/browser/renderer_host/input/touchscreen_tap_suppression_controller.h
+++ b/content/browser/renderer_host/input/touchscreen_tap_suppression_controller.h
@@ -40,6 +40,7 @@
  private:
   // TapSuppressionControllerClient implementation.
   void DropStashedTapDown() override;
+  void ForwardStashedGestureEvents() override;
   void ForwardStashedTapDown() override;
 
   GestureEventQueue* gesture_event_queue_;
@@ -47,6 +48,7 @@
   typedef std::unique_ptr<GestureEventWithLatencyInfo> ScopedGestureEvent;
   ScopedGestureEvent stashed_tap_down_;
   ScopedGestureEvent stashed_show_press_;
+  ScopedGestureEvent stashed_long_press_;
 
   // The core controller of tap suppression.
   TapSuppressionController controller_;
diff --git a/content/browser/renderer_host/media/audio_output_authorization_handler.cc b/content/browser/renderer_host/media/audio_output_authorization_handler.cc
index 9c8a1f4..56f27ea1 100644
--- a/content/browser/renderer_host/media/audio_output_authorization_handler.cc
+++ b/content/browser/renderer_host/media/audio_output_authorization_handler.cc
@@ -82,8 +82,8 @@
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
   if (!IsValidDeviceId(device_id)) {
-    bad_message::ReceivedBadMessage(render_process_id_,
-                                    bad_message::AOAH_NONSENSE_DEVICE_ID);
+    cb.Run(media::OUTPUT_DEVICE_STATUS_ERROR_NOT_FOUND, false,
+           media::AudioParameters::UnavailableDeviceParams(), std::string());
     return;
   }
 
diff --git a/content/browser/renderer_host/media/audio_output_authorization_handler_unittest.cc b/content/browser/renderer_host/media/audio_output_authorization_handler_unittest.cc
index 9b5c54d..e0e42c5 100644
--- a/content/browser/renderer_host/media/audio_output_authorization_handler_unittest.cc
+++ b/content/browser/renderer_host/media/audio_output_authorization_handler_unittest.cc
@@ -260,8 +260,7 @@
   SyncWithAllThreads();
 }
 
-TEST_F(AudioOutputAuthorizationHandlerTest,
-       AuthorizeInvalidDeviceId_BadMessage) {
+TEST_F(AudioOutputAuthorizationHandlerTest, AuthorizeInvalidDeviceId_NotFound) {
   std::unique_ptr<TestBrowserContext> context =
       base::MakeUnique<TestBrowserContext>();
   std::unique_ptr<MockRenderProcessHost> RPH =
@@ -272,7 +271,10 @@
           GetAudioManager(), GetMediaStreamManager(), RPH->GetID(), kSalt);
   EXPECT_EQ(RPH->bad_msg_count(), 0);
 
-  EXPECT_CALL(listener, MockAuthorizationCallback(_, _, _, _)).Times(0);
+  EXPECT_CALL(listener,
+              MockAuthorizationCallback(
+                  media::OUTPUT_DEVICE_STATUS_ERROR_NOT_FOUND, _, _, _))
+      .Times(1);
 
   BrowserThread::PostTask(
       BrowserThread::IO, FROM_HERE,
@@ -281,7 +283,9 @@
                   kInvalidDeviceId, SecurityOrigin(), listener.GetCallback())));
 
   SyncWithAllThreads();
-  EXPECT_EQ(RPH->bad_msg_count(), 1);
+  // It is possible to request an invalid device id from JS APIs,
+  // so we don't want to crash the renderer for this.
+  EXPECT_EQ(RPH->bad_msg_count(), 0);
   BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, handler.release());
   SyncWithAllThreads();
   RPH.reset();
diff --git a/content/browser/renderer_host/media/audio_renderer_host_unittest.cc b/content/browser/renderer_host/media/audio_renderer_host_unittest.cc
index 04b7209b..88dc9d37 100644
--- a/content/browser/renderer_host/media/audio_renderer_host_unittest.cc
+++ b/content/browser/renderer_host/media/audio_renderer_host_unittest.cc
@@ -609,9 +609,8 @@
 }
 
 TEST_F(AudioRendererHostTest, CreateInvalidDevice) {
-  Create(kInvalidDeviceId, url::Origin(GURL(kSecurityOrigin)), true, false);
+  Create(kInvalidDeviceId, url::Origin(GURL(kSecurityOrigin)), true, true);
   Close();
-  AssertBadMsgReported();
 }
 
 TEST_F(AudioRendererHostTest, CreateFailsForInvalidRenderFrame) {
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
index dd33dfe..6141da6 100644
--- a/content/browser/renderer_host/render_widget_host_impl.cc
+++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -2153,8 +2153,6 @@
       const NativeWebKeyboardEventWithLatencyInfo& event,
       InputEventAckState ack_result) {
   latency_tracker_.OnInputEventAck(event.event, &event.latency, ack_result);
-  for (auto& input_event_observer : input_event_observers_)
-    input_event_observer.OnInputEventAck(event.event);
 
   const bool processed = (INPUT_EVENT_ACK_STATE_CONSUMED == ack_result);
 
@@ -2175,8 +2173,6 @@
     InputEventAckState ack_result) {
   latency_tracker_.OnInputEventAck(mouse_event.event, &mouse_event.latency,
                                    ack_result);
-  for (auto& input_event_observer : input_event_observers_)
-    input_event_observer.OnInputEventAck(mouse_event.event);
 }
 
 void RenderWidgetHostImpl::OnWheelEventAck(
@@ -2184,8 +2180,6 @@
     InputEventAckState ack_result) {
   latency_tracker_.OnInputEventAck(wheel_event.event, &wheel_event.latency,
                                    ack_result);
-  for (auto& input_event_observer : input_event_observers_)
-    input_event_observer.OnInputEventAck(wheel_event.event);
 
   if (!is_hidden() && view_) {
     if (ack_result != INPUT_EVENT_ACK_STATE_CONSUMED &&
@@ -2200,8 +2194,6 @@
     const GestureEventWithLatencyInfo& event,
     InputEventAckState ack_result) {
   latency_tracker_.OnInputEventAck(event.event, &event.latency, ack_result);
-  for (auto& input_event_observer : input_event_observers_)
-    input_event_observer.OnInputEventAck(event.event);
 
   if (view_)
     view_->GestureEventAck(event.event, ack_result);
@@ -2211,8 +2203,6 @@
     const TouchEventWithLatencyInfo& event,
     InputEventAckState ack_result) {
   latency_tracker_.OnInputEventAck(event.event, &event.latency, ack_result);
-  for (auto& input_event_observer : input_event_observers_)
-    input_event_observer.OnInputEventAck(event.event);
 
   if (touch_emulator_ &&
       touch_emulator_->HandleTouchEventAck(event.event, ack_result)) {
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc
index 508ae90e..49da75d 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -1657,6 +1657,11 @@
     const gfx::Point& point,
     RenderWidgetHostViewBase* target_view,
     gfx::Point* transformed_point) {
+  if (target_view == this) {
+    *transformed_point = point;
+    return true;
+  }
+
   // In TransformPointToLocalCoordSpace() there is a Point-to-Pixel conversion,
   // but it is not necessary here because the final target view is responsible
   // for converting before computing the final transform.
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 c7a78ff..5bef4d0 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -1579,6 +1579,11 @@
     const gfx::Point& point,
     RenderWidgetHostViewBase* target_view,
     gfx::Point* transformed_point) {
+  if (target_view == this) {
+    *transformed_point = point;
+    return true;
+  }
+
   return browser_compositor_->GetDelegatedFrameHost()
       ->TransformPointToCoordSpaceForView(point, target_view,
                                           transformed_point);
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc
index ed7de52..c3014f3 100644
--- a/content/browser/site_per_process_browsertest.cc
+++ b/content/browser/site_per_process_browsertest.cc
@@ -589,6 +589,26 @@
   }
 };
 
+//
+// SitePerProcessNonIntegerScaleFactorBrowserTest
+//
+
+class SitePerProcessNonIntegerScaleFactorBrowserTest
+    : public SitePerProcessBrowserTest {
+ public:
+  const double kDeviceScaleFactor = 1.5;
+
+  SitePerProcessNonIntegerScaleFactorBrowserTest() {}
+
+ protected:
+  void SetUpCommandLine(base::CommandLine* command_line) override {
+    SitePerProcessBrowserTest::SetUpCommandLine(command_line);
+    command_line->AppendSwitchASCII(
+        switches::kForceDeviceScaleFactor,
+        base::StringPrintf("%f", kDeviceScaleFactor));
+  }
+};
+
 // SitePerProcessIgnoreCertErrorsBrowserTest
 
 class SitePerProcessIgnoreCertErrorsBrowserTest
@@ -8833,4 +8853,59 @@
             child->current_frame_host()->GetProcess());
 }
 
+// Test that MouseDown and MouseUp to the same coordinates do not result in
+// different coordinates after routing. See bug https://crbug.com/670253.
+#if defined(OS_ANDROID)
+// Browser process hit testing is not implemented on Android.
+// https://crbug.com/491334
+#define MAYBE_MouseClickWithNonIntegerScaleFactor \
+  DISABLED_MouseClickWithNonIntegerScaleFactor
+#else
+#define MAYBE_MouseClickWithNonIntegerScaleFactor \
+  MouseClickWithNonIntegerScaleFactor
+#endif
+IN_PROC_BROWSER_TEST_F(SitePerProcessNonIntegerScaleFactorBrowserTest,
+                       MAYBE_MouseClickWithNonIntegerScaleFactor) {
+  GURL initial_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), initial_url));
+
+  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+                            ->GetFrameTree()
+                            ->root();
+
+  RenderWidgetHostViewBase* rwhv = static_cast<RenderWidgetHostViewBase*>(
+      root->current_frame_host()->GetRenderWidgetHost()->GetView());
+
+  RenderWidgetHostInputEventRouter* router =
+      static_cast<WebContentsImpl*>(shell()->web_contents())
+          ->GetInputEventRouter();
+
+  // Create listener for input events.
+  RenderWidgetHostMouseEventMonitor event_monitor(
+      root->current_frame_host()->GetRenderWidgetHost());
+
+  blink::WebMouseEvent mouse_event;
+  mouse_event.type = blink::WebInputEvent::MouseDown;
+  mouse_event.button = blink::WebPointerProperties::Button::Left;
+  mouse_event.x = 75;
+  mouse_event.y = 75;
+  mouse_event.clickCount = 1;
+  event_monitor.ResetEventReceived();
+  router->RouteMouseEvent(rwhv, &mouse_event, ui::LatencyInfo());
+
+  EXPECT_TRUE(event_monitor.EventWasReceived());
+  gfx::Point mouse_down_coords =
+      gfx::Point(event_monitor.event().x, event_monitor.event().y);
+  event_monitor.ResetEventReceived();
+
+  mouse_event.type = blink::WebInputEvent::MouseUp;
+  mouse_event.x = 75;
+  mouse_event.y = 75;
+  router->RouteMouseEvent(rwhv, &mouse_event, ui::LatencyInfo());
+
+  EXPECT_TRUE(event_monitor.EventWasReceived());
+  EXPECT_EQ(mouse_down_coords,
+            gfx::Point(event_monitor.event().x, event_monitor.event().y));
+}
+
 }  // namespace content
diff --git a/content/content_resources.grd b/content/content_resources.grd
index 030506b..39cbab2 100644
--- a/content/content_resources.grd
+++ b/content/content_resources.grd
@@ -55,6 +55,7 @@
         <include name="IDR_MOJO_CODEC_JS" file="../mojo/public/js/codec.js" flattenhtml="true" type="BINDATA" />
         <include name="IDR_MOJO_CONNECTION_JS" file="../mojo/public/js/connection.js" flattenhtml="true" type="BINDATA" />
         <include name="IDR_MOJO_CONNECTOR_JS" file="../mojo/public/js/connector.js" flattenhtml="true" type="BINDATA" />
+        <include name="IDR_MOJO_INTERFACE_TYPES_JS" file="../mojo/public/js/interface_types.js" flattenhtml="true" type="BINDATA" />
         <include name="IDR_MOJO_ROUTER_JS" file="../mojo/public/js/router.js" flattenhtml="true" type="BINDATA" />
         <include name="IDR_MOJO_UNICODE_JS" file="../mojo/public/js/unicode.js" flattenhtml="true" type="BINDATA" />
         <include name="IDR_MOJO_VALIDATOR_JS" file="../mojo/public/js/validator.js" flattenhtml="true" type="BINDATA" />
diff --git a/content/public/android/BUILD.gn b/content/public/android/BUILD.gn
index 9b1487c..59d3a32 100644
--- a/content/public/android/BUILD.gn
+++ b/content/public/android/BUILD.gn
@@ -76,23 +76,6 @@
     "java/src/org/chromium/content/app/PrivilegedProcessService0.java",
     "java/src/org/chromium/content/app/PrivilegedProcessService1.java",
     "java/src/org/chromium/content/app/PrivilegedProcessService2.java",
-    "java/src/org/chromium/content/app/PrivilegedProcessService3.java",
-    "java/src/org/chromium/content/app/PrivilegedProcessService4.java",
-    "java/src/org/chromium/content/app/PrivilegedProcessService5.java",
-    "java/src/org/chromium/content/app/PrivilegedProcessService6.java",
-    "java/src/org/chromium/content/app/PrivilegedProcessService7.java",
-    "java/src/org/chromium/content/app/PrivilegedProcessService8.java",
-    "java/src/org/chromium/content/app/PrivilegedProcessService9.java",
-    "java/src/org/chromium/content/app/PrivilegedProcessService10.java",
-    "java/src/org/chromium/content/app/PrivilegedProcessService11.java",
-    "java/src/org/chromium/content/app/PrivilegedProcessService12.java",
-    "java/src/org/chromium/content/app/PrivilegedProcessService13.java",
-    "java/src/org/chromium/content/app/PrivilegedProcessService14.java",
-    "java/src/org/chromium/content/app/PrivilegedProcessService15.java",
-    "java/src/org/chromium/content/app/PrivilegedProcessService16.java",
-    "java/src/org/chromium/content/app/PrivilegedProcessService17.java",
-    "java/src/org/chromium/content/app/PrivilegedProcessService18.java",
-    "java/src/org/chromium/content/app/PrivilegedProcessService19.java",
     "java/src/org/chromium/content/app/SandboxedProcessService.java",
     "java/src/org/chromium/content/app/SandboxedProcessService0.java",
     "java/src/org/chromium/content/app/SandboxedProcessService1.java",
diff --git a/content/public/android/java/src/org/chromium/content/app/ChildProcessService.java b/content/public/android/java/src/org/chromium/content/app/ChildProcessService.java
index 376f319..9a9f212 100644
--- a/content/public/android/java/src/org/chromium/content/app/ChildProcessService.java
+++ b/content/public/android/java/src/org/chromium/content/app/ChildProcessService.java
@@ -6,7 +6,6 @@
 
 import android.app.Service;
 import android.content.Intent;
-import android.os.Bundle;
 import android.os.IBinder;
 
 import org.chromium.base.annotations.JNINamespace;
@@ -48,20 +47,4 @@
         stopSelf();
         return mChildProcessServiceImpl.bind(intent, -1);
     }
-
-    /**
-     * Helper method to initialize the params from intent.
-     * @param intent Intent to launch the service.
-     */
-    protected void initializeParams(Intent intent) {
-        mChildProcessServiceImpl.initializeParams(intent);
-    }
-
-    /**
-     * Helper method to get the information about the service from a given bundle.
-     * @param bundle Bundle that contains the information to start the service.
-     */
-    protected void getServiceInfo(Bundle bundle) {
-        mChildProcessServiceImpl.getServiceInfo(bundle);
-    }
 }
diff --git a/content/public/android/java/src/org/chromium/content/app/ChildProcessServiceImpl.java b/content/public/android/java/src/org/chromium/content/app/ChildProcessServiceImpl.java
index a3748f8..40d63878 100644
--- a/content/public/android/java/src/org/chromium/content/app/ChildProcessServiceImpl.java
+++ b/content/public/android/java/src/org/chromium/content/app/ChildProcessServiceImpl.java
@@ -70,8 +70,6 @@
 
     private static AtomicReference<Context> sContext = new AtomicReference<>(null);
     private boolean mLibraryInitialized = false;
-    // Becomes true once the service is bound. Access must synchronize around mMainThread.
-    private boolean mIsBound = false;
 
     /**
      * If >= 0 enables "validation of caller of {@link mBinder}'s methods". A RemoteException
@@ -164,11 +162,7 @@
                     Linker linker = null;
                     boolean requestedSharedRelro = false;
                     if (Linker.isUsed()) {
-                        synchronized (mMainThread) {
-                            while (!mIsBound) {
-                                mMainThread.wait();
-                            }
-                        }
+                        assert mLinkerParams != null;
                         linker = getLinker();
                         if (mLinkerParams.mWaitForSharedRelro) {
                             requestedSharedRelro = true;
@@ -282,28 +276,24 @@
         return mBinder;
     }
 
-    void initializeParams(Intent intent) {
+    private void initializeParams(Intent intent) {
         synchronized (mMainThread) {
-            mCommandLineParams =
-                    intent.getStringArrayExtra(ChildProcessConstants.EXTRA_COMMAND_LINE);
             // mLinkerParams is never used if Linker.isUsed() returns false.
             // See onCreate().
             mLinkerParams = new ChromiumLinkerParams(intent);
             mLibraryProcessType = ChildProcessCreationParams.getLibraryProcessType(intent);
-            mIsBound = true;
             mMainThread.notifyAll();
         }
     }
 
-    void getServiceInfo(Bundle bundle) {
+    private void getServiceInfo(Bundle bundle) {
         // Required to unparcel FileDescriptorInfo.
         bundle.setClassLoader(mHostClassLoader);
         synchronized (mMainThread) {
-            // Allow the command line to be set via bind() intent or setupConnection, but
-            // the FD can only be transferred here.
             if (mCommandLineParams == null) {
                 mCommandLineParams =
                         bundle.getStringArray(ChildProcessConstants.EXTRA_COMMAND_LINE);
+                mMainThread.notifyAll();
             }
             // We must have received the command line by now
             assert mCommandLineParams != null;
diff --git a/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService0.java b/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService0.java
index 4976d67e..a3c9c5b8 100644
--- a/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService0.java
+++ b/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService0.java
@@ -6,7 +6,7 @@
 
 /**
  * This is needed to register multiple PrivilegedProcess services so that we can have
- * more than one privileged process.
+ * more than one sandboxed process.
  */
 public class PrivilegedProcessService0 extends PrivilegedProcessService {
 
diff --git a/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService1.java b/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService1.java
index 0da1fffa..bd16f07 100644
--- a/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService1.java
+++ b/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService1.java
@@ -6,7 +6,7 @@
 
 /**
  * This is needed to register multiple PrivilegedProcess services so that we can have
- * more than one privileged process.
+ * more than one sandboxed process.
  */
 public class PrivilegedProcessService1 extends PrivilegedProcessService {
 
diff --git a/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService10.java b/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService10.java
deleted file mode 100644
index 2187f15c..0000000
--- a/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService10.java
+++ /dev/null
@@ -1,13 +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.
-
-package org.chromium.content.app;
-
-/**
- * This is needed to register multiple PrivilegedProcess services so that we can have
- * more than one privileged process.
- */
-public class PrivilegedProcessService10 extends PrivilegedProcessService {
-
-}
diff --git a/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService11.java b/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService11.java
deleted file mode 100644
index ef91c07..0000000
--- a/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService11.java
+++ /dev/null
@@ -1,13 +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.
-
-package org.chromium.content.app;
-
-/**
- * This is needed to register multiple PrivilegedProcess services so that we can have
- * more than one privileged process.
- */
-public class PrivilegedProcessService11 extends PrivilegedProcessService {
-
-}
diff --git a/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService12.java b/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService12.java
deleted file mode 100644
index ada05b6e..0000000
--- a/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService12.java
+++ /dev/null
@@ -1,13 +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.
-
-package org.chromium.content.app;
-
-/**
- * This is needed to register multiple PrivilegedProcess services so that we can have
- * more than one privileged process.
- */
-public class PrivilegedProcessService12 extends PrivilegedProcessService {
-
-}
diff --git a/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService13.java b/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService13.java
deleted file mode 100644
index e003b77b..0000000
--- a/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService13.java
+++ /dev/null
@@ -1,13 +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.
-
-package org.chromium.content.app;
-
-/**
- * This is needed to register multiple PrivilegedProcess services so that we can have
- * more than one privileged process.
- */
-public class PrivilegedProcessService13 extends PrivilegedProcessService {
-
-}
diff --git a/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService14.java b/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService14.java
deleted file mode 100644
index e2cd356..0000000
--- a/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService14.java
+++ /dev/null
@@ -1,13 +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.
-
-package org.chromium.content.app;
-
-/**
- * This is needed to register multiple PrivilegedProcess services so that we can have
- * more than one privileged process.
- */
-public class PrivilegedProcessService14 extends PrivilegedProcessService {
-
-}
diff --git a/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService15.java b/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService15.java
deleted file mode 100644
index 9233e779..0000000
--- a/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService15.java
+++ /dev/null
@@ -1,13 +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.
-
-package org.chromium.content.app;
-
-/**
- * This is needed to register multiple PrivilegedProcess services so that we can have
- * more than one privileged process.
- */
-public class PrivilegedProcessService15 extends PrivilegedProcessService {
-
-}
diff --git a/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService16.java b/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService16.java
deleted file mode 100644
index 04dd5ef..0000000
--- a/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService16.java
+++ /dev/null
@@ -1,13 +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.
-
-package org.chromium.content.app;
-
-/**
- * This is needed to register multiple PrivilegedProcess services so that we can have
- * more than one privileged process.
- */
-public class PrivilegedProcessService16 extends PrivilegedProcessService {
-
-}
diff --git a/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService17.java b/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService17.java
deleted file mode 100644
index 98c3534..0000000
--- a/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService17.java
+++ /dev/null
@@ -1,13 +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.
-
-package org.chromium.content.app;
-
-/**
- * This is needed to register multiple PrivilegedProcess services so that we can have
- * more than one privileged process.
- */
-public class PrivilegedProcessService17 extends PrivilegedProcessService {
-
-}
diff --git a/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService18.java b/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService18.java
deleted file mode 100644
index 769a9a9..0000000
--- a/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService18.java
+++ /dev/null
@@ -1,13 +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.
-
-package org.chromium.content.app;
-
-/**
- * This is needed to register multiple PrivilegedProcess services so that we can have
- * more than one privileged process.
- */
-public class PrivilegedProcessService18 extends PrivilegedProcessService {
-
-}
diff --git a/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService19.java b/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService19.java
deleted file mode 100644
index 3303b0f..0000000
--- a/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService19.java
+++ /dev/null
@@ -1,13 +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.
-
-package org.chromium.content.app;
-
-/**
- * This is needed to register multiple PrivilegedProcess services so that we can have
- * more than one privileged process.
- */
-public class PrivilegedProcessService19 extends PrivilegedProcessService {
-
-}
diff --git a/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService2.java b/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService2.java
index ea2c482..3f40406 100644
--- a/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService2.java
+++ b/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService2.java
@@ -6,7 +6,7 @@
 
 /**
  * This is needed to register multiple PrivilegedProcess services so that we can have
- * more than one privileged process.
+ * more than one sandboxed process.
  */
 public class PrivilegedProcessService2 extends PrivilegedProcessService {
 
diff --git a/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService3.java b/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService3.java
deleted file mode 100644
index 9307bb7..0000000
--- a/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService3.java
+++ /dev/null
@@ -1,13 +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.
-
-package org.chromium.content.app;
-
-/**
- * This is needed to register multiple PrivilegedProcess services so that we can have
- * more than one privileged process.
- */
-public class PrivilegedProcessService3 extends PrivilegedProcessService {
-
-}
diff --git a/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService4.java b/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService4.java
deleted file mode 100644
index 5ed2799..0000000
--- a/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService4.java
+++ /dev/null
@@ -1,13 +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.
-
-package org.chromium.content.app;
-
-/**
- * This is needed to register multiple PrivilegedProcess services so that we can have
- * more than one privileged process.
- */
-public class PrivilegedProcessService4 extends PrivilegedProcessService {
-
-}
diff --git a/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService5.java b/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService5.java
deleted file mode 100644
index 1fc3a90b..0000000
--- a/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService5.java
+++ /dev/null
@@ -1,13 +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.
-
-package org.chromium.content.app;
-
-/**
- * This is needed to register multiple PrivilegedProcess services so that we can have
- * more than one privileged process.
- */
-public class PrivilegedProcessService5 extends PrivilegedProcessService {
-
-}
diff --git a/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService6.java b/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService6.java
deleted file mode 100644
index 34ff845..0000000
--- a/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService6.java
+++ /dev/null
@@ -1,13 +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.
-
-package org.chromium.content.app;
-
-/**
- * This is needed to register multiple PrivilegedProcess services so that we can have
- * more than one privileged process.
- */
-public class PrivilegedProcessService6 extends PrivilegedProcessService {
-
-}
diff --git a/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService7.java b/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService7.java
deleted file mode 100644
index c8439ab..0000000
--- a/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService7.java
+++ /dev/null
@@ -1,13 +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.
-
-package org.chromium.content.app;
-
-/**
- * This is needed to register multiple PrivilegedProcess services so that we can have
- * more than one privileged process.
- */
-public class PrivilegedProcessService7 extends PrivilegedProcessService {
-
-}
diff --git a/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService8.java b/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService8.java
deleted file mode 100644
index 63d9e49..0000000
--- a/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService8.java
+++ /dev/null
@@ -1,13 +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.
-
-package org.chromium.content.app;
-
-/**
- * This is needed to register multiple PrivilegedProcess services so that we can have
- * more than one privileged process.
- */
-public class PrivilegedProcessService8 extends PrivilegedProcessService {
-
-}
diff --git a/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService9.java b/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService9.java
deleted file mode 100644
index a5d71b7..0000000
--- a/content/public/android/java/src/org/chromium/content/app/PrivilegedProcessService9.java
+++ /dev/null
@@ -1,13 +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.
-
-package org.chromium.content.app;
-
-/**
- * This is needed to register multiple PrivilegedProcess services so that we can have
- * more than one privileged process.
- */
-public class PrivilegedProcessService9 extends PrivilegedProcessService {
-
-}
diff --git a/content/public/android/java/src/org/chromium/content/browser/ChildProcessConnectionImpl.java b/content/public/android/java/src/org/chromium/content/browser/ChildProcessConnectionImpl.java
index 99032d4..4eb35a5 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ChildProcessConnectionImpl.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ChildProcessConnectionImpl.java
@@ -130,9 +130,9 @@
                 try {
                     TraceEvent.begin("ChildProcessConnectionImpl.ChildServiceConnection.bind");
                     final Intent intent = createServiceBindIntent();
-                    if (commandLine != null) {
-                        intent.putExtra(ChildProcessConstants.EXTRA_COMMAND_LINE, commandLine);
-                    }
+                    // Note, the intent may be saved and re-used by Android for re-launching the
+                    // child service. Do not pass data that is different for each child; command
+                    // line arguments for example.
                     if (mLinkerParams != null) {
                         mLinkerParams.addIntentExtras(intent);
                     }
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/SelectPopupDropdown.java b/content/public/android/java/src/org/chromium/content/browser/input/SelectPopupDropdown.java
index b9437f0..9410271 100644
--- a/content/public/android/java/src/org/chromium/content/browser/input/SelectPopupDropdown.java
+++ b/content/public/android/java/src/org/chromium/content/browser/input/SelectPopupDropdown.java
@@ -44,7 +44,9 @@
             initialSelection = selected[0];
         }
         mDropdownPopupWindow.setInitialSelection(initialSelection);
-        mDropdownPopupWindow.setAdapter(new DropdownAdapter(mContext, items, null));
+        mDropdownPopupWindow.setAdapter(new DropdownAdapter(
+                mContext, items, null /* separators */, null /* backgroundColor */,
+                null /* dividerColor */, null /* dropdownItemHeight */));
         mDropdownPopupWindow.setRtl(rightAligned);
         mDropdownPopupWindow.setOnDismissListener(
                 new PopupWindow.OnDismissListener() {
diff --git a/content/public/app/BUILD.gn b/content/public/app/BUILD.gn
index 620f1706..d09712d 100644
--- a/content/public/app/BUILD.gn
+++ b/content/public/app/BUILD.gn
@@ -21,6 +21,7 @@
 #       //content/public/app:both_sources (source set)
 
 import("//build/config/chrome_build.gni")
+import("//build/config/ui.gni")
 import("//services/service_manager/public/service_manifest.gni")
 
 public_app_shared_sources = [
@@ -42,6 +43,10 @@
   "//content/public/utility:utility_sources",
 ]
 
+if (use_aura) {
+  public_app_shared_deps += [ "//ui/aura" ]
+}
+
 if (is_component_build) {
   source_set("both_sources") {
     # Only the main content shared library can pull this in.
diff --git a/content/public/app/content_main.h b/content/public/app/content_main.h
index 201fca7..0c718bf 100644
--- a/content/public/app/content_main.h
+++ b/content/public/app/content_main.h
@@ -15,6 +15,10 @@
 #include <windows.h>
 #endif
 
+#if defined(USE_AURA)
+#include "ui/aura/env.h"
+#endif
+
 namespace sandbox {
 struct SandboxInterfaceInfo;
 }
@@ -51,6 +55,10 @@
   // Used by browser_tests. If non-null BrowserMain schedules this task to run
   // on the MessageLoop. It's owned by the test code.
   base::Closure* ui_task;
+
+#if defined(USE_AURA)
+  aura::Env::Mode env_mode = aura::Env::Mode::LOCAL;
+#endif
 };
 
 #if defined(OS_ANDROID)
diff --git a/content/public/browser/render_widget_host.h b/content/public/browser/render_widget_host.h
index 7005ece92..0cda573d 100644
--- a/content/public/browser/render_widget_host.h
+++ b/content/public/browser/render_widget_host.h
@@ -243,13 +243,12 @@
   virtual void AddMouseEventCallback(const MouseEventCallback& callback) = 0;
   virtual void RemoveMouseEventCallback(const MouseEventCallback& callback) = 0;
 
-  // Observer for WebInputEvents.
+  // Observer for WebInputEvents (but not input event acks).
   class InputEventObserver {
    public:
     virtual ~InputEventObserver() {}
 
-    virtual void OnInputEvent(const blink::WebInputEvent&) {};
-    virtual void OnInputEventAck(const blink::WebInputEvent&) {};
+    virtual void OnInputEvent(const blink::WebInputEvent&) = 0;
   };
 
   // Add/remove an input event observer.
diff --git a/content/public/common/BUILD.gn b/content/public/common/BUILD.gn
index c0a8a030..dc256d5 100644
--- a/content/public/common/BUILD.gn
+++ b/content/public/common/BUILD.gn
@@ -5,6 +5,7 @@
 import("//build/buildflag_header.gni")
 import("//build/config/chromecast_build.gni")
 import("//build/config/features.gni")
+import("//build/config/ui.gni")
 import("//media/media_options.gni")
 import("//mojo/public/tools/bindings/mojom.gni")
 import("//ppapi/features/features.gni")
@@ -273,6 +274,10 @@
     "//ui/gfx/ipc/skia",
   ]
 
+  if (use_aura) {
+    deps += [ "//ui/aura" ]
+  }
+
   # //content/common needs to include public headers.
   allow_circular_includes_from = [
     "//content/common",
diff --git a/content/public/common/main_function_params.h b/content/public/common/main_function_params.h
index 913e9b26..dac29913 100644
--- a/content/public/common/main_function_params.h
+++ b/content/public/common/main_function_params.h
@@ -25,6 +25,10 @@
 }
 #endif
 
+#if defined(USE_AURA)
+#include "ui/aura/env.h"
+#endif
+
 namespace content {
 
 struct MainFunctionParams {
@@ -50,6 +54,10 @@
   bool zygote_child;
 #endif
 
+#if defined(USE_AURA)
+  aura::Env::Mode env_mode = aura::Env::Mode::LOCAL;
+#endif
+
   // Used by InProcessBrowserTest. If non-null BrowserMain schedules this
   // task to run on the MessageLoop and BrowserInit is not invoked.
   base::Closure* ui_task;
diff --git a/content/public/test/browser_test_utils.cc b/content/public/test/browser_test_utils.cc
index a39b5f8b..0bac669 100644
--- a/content/public/test/browser_test_utils.cc
+++ b/content/public/test/browser_test_utils.cc
@@ -1531,13 +1531,9 @@
   return false;
 }
 
-bool InputMsgWatcher::HasReceivedAck() const {
-  return ack_result_ != INPUT_EVENT_ACK_STATE_UNKNOWN;
-}
-
 uint32_t InputMsgWatcher::WaitForAck() {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  if (HasReceivedAck())
+  if (ack_result_ != INPUT_EVENT_ACK_STATE_UNKNOWN)
     return ack_result_;
   base::RunLoop run_loop;
   base::AutoReset<base::Closure> reset_quit(&quit_, run_loop.QuitClosure());
diff --git a/content/public/test/browser_test_utils.h b/content/public/test/browser_test_utils.h
index 1d05389..e39416c 100644
--- a/content/public/test/browser_test_utils.h
+++ b/content/public/test/browser_test_utils.h
@@ -556,8 +556,6 @@
   InputMsgWatcher(RenderWidgetHost* render_widget_host,
                   blink::WebInputEvent::Type type);
 
-  bool HasReceivedAck() const;
-
   // Wait until ack message occurs, returning the ack result from
   // the message.
   uint32_t WaitForAck();
diff --git a/content/renderer/gamepad_shared_memory_reader.cc b/content/renderer/gamepad_shared_memory_reader.cc
index f1eb932..62dd301c 100644
--- a/content/renderer/gamepad_shared_memory_reader.cc
+++ b/content/renderer/gamepad_shared_memory_reader.cc
@@ -29,14 +29,7 @@
 
 void GamepadSharedMemoryReader::SendStartMessage() {
   if (gamepad_monitor_) {
-    mojo::ScopedSharedBufferHandle buffer_handle;
-    gamepad_monitor_->GamepadStartPolling(&buffer_handle);
-    // TODO(heke): Use mojo::SharedBuffer rather than base::SharedMemory. See
-    // crbug.com/670655.
-    MojoResult result = mojo::UnwrapSharedMemoryHandle(
-        std::move(buffer_handle), &renderer_shared_memory_handle_, nullptr,
-        nullptr);
-    CHECK_EQ(MOJO_RESULT_OK, result);
+    gamepad_monitor_->GamepadStartPolling(&renderer_shared_buffer_handle_);
   }
 }
 
@@ -52,16 +45,15 @@
 
   // If we don't get a valid handle from the browser, don't try to Map (we're
   // probably out of memory or file handles).
-  bool valid_handle = base::SharedMemory::IsHandleValid(
-      renderer_shared_memory_handle_);
+  bool valid_handle = renderer_shared_buffer_handle_.is_valid();
   UMA_HISTOGRAM_BOOLEAN("Gamepad.ValidSharedMemoryHandle", valid_handle);
   if (!valid_handle)
     return;
 
-  renderer_shared_memory_.reset(
-      new base::SharedMemory(renderer_shared_memory_handle_, true));
-  CHECK(renderer_shared_memory_->Map(sizeof(GamepadHardwareBuffer)));
-  void *memory = renderer_shared_memory_->memory();
+  renderer_shared_buffer_mapping_ =
+      renderer_shared_buffer_handle_->Map(sizeof(GamepadHardwareBuffer));
+  CHECK(renderer_shared_buffer_mapping_);
+  void* memory = renderer_shared_buffer_mapping_.get();
   CHECK(memory);
   gamepad_hardware_buffer_ =
       static_cast<GamepadHardwareBuffer*>(memory);
@@ -80,7 +72,7 @@
   blink::WebGamepads read_into;
   TRACE_EVENT0("GAMEPAD", "SampleGamepads");
 
-  if (!base::SharedMemory::IsHandleValid(renderer_shared_memory_handle_))
+  if (!renderer_shared_buffer_handle_.is_valid())
     return;
 
   // Only try to read this many times before failing to avoid waiting here
diff --git a/content/renderer/gamepad_shared_memory_reader.h b/content/renderer/gamepad_shared_memory_reader.h
index af4530f3..05369cb 100644
--- a/content/renderer/gamepad_shared_memory_reader.h
+++ b/content/renderer/gamepad_shared_memory_reader.h
@@ -8,12 +8,11 @@
 #include <memory>
 
 #include "base/macros.h"
-#include "base/memory/shared_memory.h"
 #include "content/public/renderer/renderer_gamepad_provider.h"
 #include "device/base/synchronization/shared_memory_seqlock_buffer.h"
 #include "device/gamepad/public/interfaces/gamepad.mojom.h"
 #include "mojo/public/cpp/bindings/binding.h"
-#include "mojo/public/cpp/system/platform_handle.h"
+#include "mojo/public/cpp/system/buffer.h"
 #include "third_party/WebKit/public/platform/WebGamepads.h"
 
 namespace content {
@@ -42,8 +41,8 @@
   void GamepadDisconnected(int index,
                            const blink::WebGamepad& gamepad) override;
 
-  base::SharedMemoryHandle renderer_shared_memory_handle_;
-  std::unique_ptr<base::SharedMemory> renderer_shared_memory_;
+  mojo::ScopedSharedBufferHandle renderer_shared_buffer_handle_;
+  mojo::ScopedSharedBufferMapping renderer_shared_buffer_mapping_;
   GamepadHardwareBuffer* gamepad_hardware_buffer_;
 
   bool ever_interacted_with_;
diff --git a/content/renderer/history_serialization.cc b/content/renderer/history_serialization.cc
index 7adf199..c9a7b200 100644
--- a/content/renderer/history_serialization.cc
+++ b/content/renderer/history_serialization.cc
@@ -52,7 +52,7 @@
   state->document_sequence_number =
       item.documentSequenceNumber();
   state->page_scale_factor = item.pageScaleFactor();
-  ToNullableString16Vector(item.documentState(), &state->document_state);
+  ToNullableString16Vector(item.getDocumentState(), &state->document_state);
 
   state->http_body.http_content_type = item.httpContentType();
   const WebHTTPBody& http_body = item.httpBody();
diff --git a/content/renderer/mojo_context_state.cc b/content/renderer/mojo_context_state.cc
index 5bba47d3..1a7f1b26 100644
--- a/content/renderer/mojo_context_state.cc
+++ b/content/renderer/mojo_context_state.cc
@@ -66,6 +66,7 @@
     { mojo::kCodecModuleName, IDR_MOJO_CODEC_JS },
     { mojo::kConnectionModuleName, IDR_MOJO_CONNECTION_JS },
     { mojo::kConnectorModuleName, IDR_MOJO_CONNECTOR_JS },
+    { mojo::kInterfaceTypesModuleName, IDR_MOJO_INTERFACE_TYPES_JS },
     { mojo::kRouterModuleName, IDR_MOJO_ROUTER_JS },
     { mojo::kUnicodeModuleName, IDR_MOJO_UNICODE_JS },
     { mojo::kValidatorModuleName, IDR_MOJO_VALIDATOR_JS },
diff --git a/content/renderer/pepper/host_dispatcher_wrapper.cc b/content/renderer/pepper/host_dispatcher_wrapper.cc
index 75b58ef..29a523c 100644
--- a/content/renderer/pepper/host_dispatcher_wrapper.cc
+++ b/content/renderer/pepper/host_dispatcher_wrapper.cc
@@ -83,11 +83,8 @@
   if (host) {
     RenderFrame* render_frame = host->GetRenderFrameForInstance(instance);
     PepperPluginInstance* plugin_instance = host->GetPluginInstance(instance);
-    blink::WebString unused;
     bool is_privileged_context =
-        plugin_instance->GetContainer()
-            ->document()
-            .isSecureContext(unused) &&
+        plugin_instance->GetContainer()->document().isSecureContext() &&
         content::IsOriginSecure(plugin_instance->GetPluginURL());
     render_frame->Send(new FrameHostMsg_DidCreateOutOfProcessPepperInstance(
         plugin_child_id_, instance,
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 5007f28f..28b5013 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -4255,9 +4255,8 @@
   extra_data->set_download_to_network_cache_only(
       is_prefetch &&
       WebURLRequestToResourceType(request) != RESOURCE_TYPE_MAIN_FRAME);
-  WebString error;
   extra_data->set_initiated_in_secure_context(
-      frame->document().isSecureContext(error));
+      frame->document().isSecureContext());
 
   // Renderer process transfers apply only to navigational requests.
   bool is_navigational_request =
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc
index d3d457c..4012f0f 100644
--- a/content/renderer/render_thread_impl.cc
+++ b/content/renderer/render_thread_impl.cc
@@ -1811,20 +1811,20 @@
 namespace {
 
 static size_t GetMallocUsage() {
-  // Only checks the default process heap.
-  HANDLE heap = ::GetProcessHeap();
-  if (heap == NULL)
+  // Iterate through whichever heap the CRT is using.
+  HANDLE crt_heap = reinterpret_cast<HANDLE>(_get_heap_handle());
+  if (crt_heap == NULL)
     return 0;
-  if (!::HeapLock(heap))
+  if (!::HeapLock(crt_heap))
     return 0 ;
   size_t malloc_usage = 0;
   PROCESS_HEAP_ENTRY heap_entry;
   heap_entry.lpData = NULL;
-  while (::HeapWalk(heap, &heap_entry) != 0) {
+  while (::HeapWalk(crt_heap, &heap_entry) != 0) {
     if ((heap_entry.wFlags & PROCESS_HEAP_ENTRY_BUSY) != 0)
       malloc_usage += heap_entry.cbData;
   }
-  ::HeapUnlock(heap);
+  ::HeapUnlock(crt_heap);
   return malloc_usage;
 }
 
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc
index a086f7b..e47f7f6 100644
--- a/content/renderer/render_widget.cc
+++ b/content/renderer/render_widget.cc
@@ -1518,7 +1518,6 @@
     return;
   ImeEventGuard guard(this);
   blink::WebInputMethodController* controller = GetInputMethodController();
-  DCHECK(controller);
   if (!controller ||
       !controller->setComposition(
           text, WebVector<WebCompositionUnderline>(underlines), selection_start,
diff --git a/content/shell/android/browsertests_apk/AndroidManifest.xml.jinja2 b/content/shell/android/browsertests_apk/AndroidManifest.xml.jinja2
index f41aa9c..11e6b27 100644
--- a/content/shell/android/browsertests_apk/AndroidManifest.xml.jinja2
+++ b/content/shell/android/browsertests_apk/AndroidManifest.xml.jinja2
@@ -48,7 +48,7 @@
                  android:exported="false" />
         {% endfor %}
 
-        {% set num_privileged_services = 20 %}
+        {% set num_privileged_services = 3 %}
         <meta-data android:name="org.chromium.content.browser.NUM_PRIVILEGED_SERVICES"
                    android:value="{{ num_privileged_services }}"/>
         {% for i in range(num_privileged_services) %}
diff --git a/content/shell/android/linker_test_apk/AndroidManifest.xml.jinja2 b/content/shell/android/linker_test_apk/AndroidManifest.xml.jinja2
index 9f79475..d621791 100644
--- a/content/shell/android/linker_test_apk/AndroidManifest.xml.jinja2
+++ b/content/shell/android/linker_test_apk/AndroidManifest.xml.jinja2
@@ -47,7 +47,7 @@
                  android:exported="false" />
         {% endfor %}
 
-        {% set num_privileged_services = 20 %}
+        {% set num_privileged_services = 3 %}
         <meta-data android:name="org.chromium.content.browser.NUM_PRIVILEGED_SERVICES"
                    android:value="{{ num_privileged_services }}"/>
         {% for i in range(num_privileged_services) %}
diff --git a/content/shell/android/shell_apk/AndroidManifest.xml.jinja2 b/content/shell/android/shell_apk/AndroidManifest.xml.jinja2
index ecca6c27..f2e149f4 100644
--- a/content/shell/android/shell_apk/AndroidManifest.xml.jinja2
+++ b/content/shell/android/shell_apk/AndroidManifest.xml.jinja2
@@ -49,7 +49,7 @@
                  android:exported="false" />
         {% endfor %}
 
-        {% set num_privileged_services = 20 %}
+        {% set num_privileged_services = 3 %}
         <meta-data android:name="org.chromium.content.browser.NUM_PRIVILEGED_SERVICES"
                    android:value="{{ num_privileged_services }}"/>
         {% for i in range(num_privileged_services) %}
diff --git a/content/test/gpu/generate_buildbot_json.py b/content/test/gpu/generate_buildbot_json.py
index 1ae945b..e91fd7d 100755
--- a/content/test/gpu/generate_buildbot_json.py
+++ b/content/test/gpu/generate_buildbot_json.py
@@ -765,10 +765,12 @@
         # added.
         'build_configs': ['Release', 'Release_x64'],
         'swarming_dimension_sets': [
+          # NVIDIA Win 7
           {
             'gpu': '10de:104a',
             'os': 'Windows-2008ServerR2-SP1'
           },
+          # AMD Win 7
           {
             'gpu': '1002:6613',
             'os': 'Windows-2008ServerR2-SP1'
@@ -796,6 +798,7 @@
         # trybots) for the time being, at least until more capacity is added.
         'build_configs': ['Release', 'Release_x64'],
         'swarming_dimension_sets': [
+          # NVIDIA Linux
           {
             'gpu': '10de:104a',
             'os': 'Linux'
@@ -823,6 +826,7 @@
         # Run on Nexus 5X swarmed bots.
         'build_configs': ['android-chromium'],
         'swarming_dimension_sets': [
+          # Nexus 5X
           {
             'device_type': 'bullhead',
             'device_os': 'M',
@@ -846,16 +850,21 @@
     'tester_configs': [
       {
         'fyi_only': True,
-        # TODO(jmadill): Run this on the optional tryservers.
+        # TODO(jmadill): Run this on ANGLE roll tryservers.
         'run_on_optional': False,
-        # Run only on the Win7 Release NVIDIA 32-bit bots (and trybots) for the
-        # time being, at least until more capacity is added.
-        # TODO(jmadill): Run on the Win AMD R7 240 bots once they are swarmed.
+        # Run only on the NVIDIA and AMD Win7 bots (and trybots) for the time
+        # being, at least until more capacity is added.
         'build_configs': ['Release'],
         'swarming_dimension_sets': [
+          # NVIDIA Win 7
           {
             'gpu': '10de:104a',
             'os': 'Windows-2008ServerR2-SP1'
+          },
+          # AMD Win 7
+          {
+            'gpu': '1002:6613',
+            'os': 'Windows-2008ServerR2-SP1'
           }
         ],
       }
@@ -874,12 +883,13 @@
     'tester_configs': [
       {
         'fyi_only': True,
-        # TODO(jmadill): Run this on the optional tryservers.
+        # TODO(jmadill): Run this on ANGLE roll tryservers.
         'run_on_optional': False,
         # Run only on the Linux Release NVIDIA 32-bit bots (and trybots) for
         # the time being, at least until more capacity is added.
         'build_configs': ['Release'],
         'swarming_dimension_sets': [
+          # NVIDIA Linux
           {
             'gpu': '10de:104a',
             'os': 'Linux'
diff --git a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
index 48874a3f..e57b499 100644
--- a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
+++ b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
@@ -44,13 +44,6 @@
     self.Flaky('conformance2/query/occlusion-query.html', bug=603168)
     self.Fail('conformance2/glsl3/tricky-loop-conditions.html', bug=483282)
 
-    # This next one fails reliably on Linux AMD and is flaky everywhere
-    # else. Unfortunately, this means the expectation needs to be
-    # complicated to avoid collisions (and unit test failures).
-    self.Flaky('conformance2/misc/uninitialized-test-2.html',
-        ['win', 'mac', 'chromeos', 'android'], bug=671791)
-    self.Flaky('conformance2/misc/uninitialized-test-2.html',
-        ['linux', 'intel', 'nvidia'], bug=671791)
     self.Fail('conformance2/rendering/depth-stencil-feedback-loop.html',
         bug=660844) # WebGL 2.0.1
     self.Fail('conformance2/rendering/rendering-sampling-feedback-loop.html',
diff --git a/content/test/test_blink_web_unit_test_support.cc b/content/test/test_blink_web_unit_test_support.cc
index f4fcdbd..6708ae6d 100644
--- a/content/test/test_blink_web_unit_test_support.cc
+++ b/content/test/test_blink_web_unit_test_support.cc
@@ -52,7 +52,7 @@
 #if BUILDFLAG(ENABLE_WEBRTC)
 #include "content/renderer/media/rtc_certificate.h"
 #include "third_party/WebKit/public/platform/WebRTCCertificateGenerator.h"
-#include "third_party/webrtc/base/rtccertificate.h"
+#include "third_party/webrtc/base/rtccertificate.h"  // nogncheck
 #endif
 
 namespace {
diff --git a/extensions/browser/api/cast_channel/cast_channel_api.cc b/extensions/browser/api/cast_channel/cast_channel_api.cc
index dc4da0f0..b8fd3b2b 100644
--- a/extensions/browser/api/cast_channel/cast_channel_api.cc
+++ b/extensions/browser/api/cast_channel/cast_channel_api.cc
@@ -225,7 +225,7 @@
   channel_info.error_state = error;
   channel_info.connect_info.ip_address = "";
   channel_info.connect_info.port = 0;
-  channel_info.connect_info.auth = cast_channel::CHANNEL_AUTH_TYPE_SSL;
+  channel_info.connect_info.auth = cast_channel::CHANNEL_AUTH_TYPE_SSL_VERIFIED;
   SetResultFromChannelInfo(channel_info);
   SetError("Channel error = " + base::IntToString(error));
 }
diff --git a/extensions/browser/api/cast_channel/cast_channel_api_unittest.cc b/extensions/browser/api/cast_channel/cast_channel_api_unittest.cc
index 6cc9124..0797716e 100644
--- a/extensions/browser/api/cast_channel/cast_channel_api_unittest.cc
+++ b/extensions/browser/api/cast_channel/cast_channel_api_unittest.cc
@@ -22,7 +22,7 @@
   ConnectInfo connect_info;
   connect_info.ip_address = "192.0.0.1";
   connect_info.port = 8009;
-  connect_info.auth = CHANNEL_AUTH_TYPE_SSL;
+  connect_info.auth = CHANNEL_AUTH_TYPE_SSL_VERIFIED;
 
   ip_endpoint.reset(ccof::ParseConnectInfo(connect_info));
   EXPECT_TRUE(ip_endpoint);
diff --git a/extensions/browser/api/cast_channel/cast_channel_apitest.cc b/extensions/browser/api/cast_channel/cast_channel_apitest.cc
index fd972f7..565f616a 100644
--- a/extensions/browser/api/cast_channel/cast_channel_apitest.cc
+++ b/extensions/browser/api/cast_channel/cast_channel_apitest.cc
@@ -108,7 +108,7 @@
     ON_CALL(*mock_cast_socket_, ip_endpoint())
         .WillByDefault(ReturnRef(ip_endpoint_));
     ON_CALL(*mock_cast_socket_, channel_auth())
-        .WillByDefault(Return(cast_channel::CHANNEL_AUTH_TYPE_SSL));
+        .WillByDefault(Return(cast_channel::CHANNEL_AUTH_TYPE_SSL_VERIFIED));
     ON_CALL(*mock_cast_socket_, keep_alive()).WillByDefault(Return(false));
   }
 
@@ -388,16 +388,18 @@
   cast_channel_open_function = CreateOpenFunction(empty_extension);
   std::string error = utils::RunFunctionAndReturnError(
       cast_channel_open_function.get(),
-      "[{\"ipAddress\": \"invalid_ip\", \"port\": 8009, \"auth\": \"ssl\"}]",
+      "[{\"ipAddress\": \"invalid_ip\", \"port\": 8009, \"auth\": "
+      "\"ssl_verified\"}]",
       browser());
   EXPECT_EQ(error, "Invalid connect_info (invalid IP address)");
 
   // Invalid port
   cast_channel_open_function = CreateOpenFunction(empty_extension);
-  error = utils::RunFunctionAndReturnError(
-      cast_channel_open_function.get(),
-      "[{\"ipAddress\": \"127.0.0.1\", \"port\": -200, \"auth\": \"ssl\"}]",
-      browser());
+  error = utils::RunFunctionAndReturnError(cast_channel_open_function.get(),
+                                           "[{\"ipAddress\": \"127.0.0.1\", "
+                                           "\"port\": -200, \"auth\": "
+                                           "\"ssl_verified\"}]",
+                                           browser());
   EXPECT_EQ(error, "Invalid connect_info (invalid port)");
 }
 
@@ -415,7 +417,7 @@
       "\"audioOnly\": false, "
       "\"connectInfo\": "
       "{\"ipAddress\": \"127.0.0.1\", \"port\": 8009, "
-      "\"auth\": \"ssl\"}, \"readyState\": \"open\"}, "
+      "\"auth\": \"ssl_verified\"}, \"readyState\": \"open\"}, "
       "{\"namespace_\": \"foo\", \"sourceId\": \"src\", "
       "\"destinationId\": \"dest\", \"data\": 1235}]",
       browser()));
@@ -430,7 +432,7 @@
       "\"audioOnly\": false, "
       "\"connectInfo\": "
       "{\"ipAddress\": \"127.0.0.1\", \"port\": 8009, "
-      "\"auth\": \"ssl\"}, \"readyState\": \"open\"}, "
+      "\"auth\": \"ssl_verified\"}, \"readyState\": \"open\"}, "
       "{\"namespace_\": \"\", \"sourceId\": \"src\", "
       "\"destinationId\": \"dest\", \"data\": \"data\"}]",
       browser());
@@ -445,7 +447,7 @@
       "\"audioOnly\": false, "
       "\"connectInfo\": "
       "{\"ipAddress\": \"127.0.0.1\", \"port\": 8009, "
-      "\"auth\": \"ssl\"}, \"readyState\": \"open\"}, "
+      "\"auth\": \"ssl_verified\"}, \"readyState\": \"open\"}, "
       "{\"namespace_\": \"foo\", \"sourceId\": \"\", "
       "\"destinationId\": \"dest\", \"data\": \"data\"}]",
       browser());
@@ -460,7 +462,7 @@
       "\"audioOnly\": false, "
       "\"connectInfo\": "
       "{\"ipAddress\": \"127.0.0.1\", \"port\": 8009, "
-      "\"auth\": \"ssl\"}, \"readyState\": \"open\"}, "
+      "\"auth\": \"ssl_verified\"}, \"readyState\": \"open\"}, "
       "{\"namespace_\": \"foo\", \"sourceId\": \"src\", "
       "\"destinationId\": \"\", \"data\": \"data\"}]",
       browser());
diff --git a/extensions/browser/api/cast_channel/cast_socket.cc b/extensions/browser/api/cast_channel/cast_socket.cc
index 5cf9f29..3bb675c 100644
--- a/extensions/browser/api/cast_channel/cast_socket.cc
+++ b/extensions/browser/api/cast_channel/cast_socket.cc
@@ -132,8 +132,6 @@
       ready_state_(READY_STATE_NONE),
       auth_delegate_(nullptr) {
   DCHECK(net_log_);
-  DCHECK(channel_auth_ == CHANNEL_AUTH_TYPE_SSL ||
-         channel_auth_ == CHANNEL_AUTH_TYPE_SSL_VERIFIED);
   net_log_source_.type = net::NetLogSourceType::SOCKET;
   net_log_source_.id = net_log_->NextID();
 }
@@ -436,13 +434,7 @@
     }
     auth_delegate_ = new AuthTransportDelegate(this);
     transport_->SetReadDelegate(base::WrapUnique(auth_delegate_));
-    if (channel_auth_ == CHANNEL_AUTH_TYPE_SSL_VERIFIED) {
-      // Additionally verify the connection with a handshake.
-      SetConnectState(proto::CONN_STATE_AUTH_CHALLENGE_SEND);
-    } else {
-      SetConnectState(proto::CONN_STATE_FINISHED);
-      transport_->Start();
-    }
+    SetConnectState(proto::CONN_STATE_AUTH_CHALLENGE_SEND);
   } else if (result == net::ERR_CONNECTION_TIMED_OUT) {
     SetConnectState(proto::CONN_STATE_FINISHED);
     SetErrorState(CHANNEL_ERROR_CONNECT_TIMEOUT);
diff --git a/extensions/browser/api/cast_channel/cast_socket_unittest.cc b/extensions/browser/api/cast_channel/cast_socket_unittest.cc
index 2201bf9..48e60c8 100644
--- a/extensions/browser/api/cast_channel/cast_socket_unittest.cc
+++ b/extensions/browser/api/cast_channel/cast_socket_unittest.cc
@@ -28,6 +28,7 @@
 #include "extensions/browser/api/cast_channel/cast_transport.h"
 #include "extensions/browser/api/cast_channel/logger.h"
 #include "extensions/common/api/cast_channel/cast_channel.pb.h"
+#include "extensions/common/api/cast_channel/logging.pb.h"
 #include "net/base/address_list.h"
 #include "net/base/net_errors.h"
 #include "net/log/test_net_log.h"
@@ -173,14 +174,6 @@
 
 class TestCastSocket : public CastSocketImpl {
  public:
-  static std::unique_ptr<TestCastSocket> Create(
-      Logger* logger,
-      uint64_t device_capabilities = cast_channel::CastDeviceCapability::NONE) {
-    return std::unique_ptr<TestCastSocket>(
-        new TestCastSocket(CreateIPEndPointForTest(), CHANNEL_AUTH_TYPE_SSL,
-                           kDistantTimeoutMillis, logger, device_capabilities));
-  }
-
   static std::unique_ptr<TestCastSocket> CreateSecure(
       Logger* logger,
       uint64_t device_capabilities = cast_channel::CastDeviceCapability::NONE) {
@@ -372,8 +365,6 @@
     }
   }
 
-  void CreateCastSocket() { socket_ = TestCastSocket::Create(logger_); }
-
   void CreateCastSocketSecure() {
     socket_ = TestCastSocket::CreateSecure(logger_);
   }
@@ -412,68 +403,6 @@
   DISALLOW_COPY_AND_ASSIGN(CastSocketTest);
 };
 
-// Tests connecting and closing the socket.
-TEST_F(CastSocketTest, TestConnectAndClose) {
-  CreateCastSocket();
-  socket_->SetupMockTransport();
-  socket_->SetupTcpConnect(net::SYNCHRONOUS, net::OK);
-  socket_->SetupSslConnect(net::SYNCHRONOUS, net::OK);
-
-  EXPECT_CALL(handler_, OnConnectComplete(CHANNEL_ERROR_NONE));
-  socket_->Connect(std::move(delegate_),
-                   base::Bind(&CompleteHandler::OnConnectComplete,
-                              base::Unretained(&handler_)));
-  RunPendingTasks();
-
-  EXPECT_EQ(cast_channel::READY_STATE_OPEN, socket_->ready_state());
-  EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state());
-
-  EXPECT_CALL(handler_, OnCloseComplete(net::OK));
-  socket_->Close(base::Bind(&CompleteHandler::OnCloseComplete,
-                            base::Unretained(&handler_)));
-  EXPECT_EQ(cast_channel::READY_STATE_CLOSED, socket_->ready_state());
-  EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state());
-}
-
-// Tests that the following connection flow works:
-// - TCP connection succeeds (async)
-// - SSL connection succeeds (async)
-TEST_F(CastSocketTest, TestConnect) {
-  CreateCastSocket();
-  socket_->SetupTcpConnect(net::ASYNC, net::OK);
-  socket_->SetupSslConnect(net::ASYNC, net::OK);
-  socket_->AddReadResult(net::ASYNC, net::ERR_IO_PENDING);
-
-  EXPECT_CALL(handler_, OnConnectComplete(CHANNEL_ERROR_NONE));
-  socket_->Connect(std::move(delegate_),
-                   base::Bind(&CompleteHandler::OnConnectComplete,
-                              base::Unretained(&handler_)));
-  RunPendingTasks();
-
-  EXPECT_EQ(cast_channel::READY_STATE_OPEN, socket_->ready_state());
-  EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state());
-}
-
-// Tests that the following connection flow works:
-// - TCP connection fails (async)
-TEST_F(CastSocketTest, TestConnectFails) {
-  CreateCastSocket();
-  socket_->SetupTcpConnect(net::ASYNC, net::ERR_FAILED);
-
-  EXPECT_CALL(handler_, OnConnectComplete(CHANNEL_ERROR_CONNECT_ERROR));
-  socket_->Connect(std::move(delegate_),
-                   base::Bind(&CompleteHandler::OnConnectComplete,
-                              base::Unretained(&handler_)));
-  RunPendingTasks();
-
-  EXPECT_EQ(cast_channel::READY_STATE_CLOSED, socket_->ready_state());
-  EXPECT_EQ(cast_channel::CHANNEL_ERROR_CONNECT_ERROR, socket_->error_state());
-  EXPECT_EQ(proto::TCP_SOCKET_CONNECT_COMPLETE,
-            logger_->GetLastErrors(socket_->id()).event_type);
-  EXPECT_EQ(net::ERR_FAILED,
-            logger_->GetLastErrors(socket_->id()).net_return_value);
-}
-
 // Tests that the following connection flow works:
 // - TCP connection succeeds (async)
 // - SSL connection succeeds (async)
@@ -692,44 +621,6 @@
             socket_->error_state());
 }
 
-// Test connection error - cert extraction error (async)
-TEST_F(CastSocketTest, TestConnectCertExtractionErrorAsync) {
-  CreateCastSocket();
-  socket_->SetupTcpConnect(net::ASYNC, net::OK);
-  socket_->SetupSslConnect(net::ASYNC, net::OK);
-  // Set cert extraction to fail
-  socket_->SetExtractCertResult(false);
-
-  EXPECT_CALL(handler_, OnConnectComplete(CHANNEL_ERROR_AUTHENTICATION_ERROR));
-  socket_->Connect(std::move(delegate_),
-                   base::Bind(&CompleteHandler::OnConnectComplete,
-                              base::Unretained(&handler_)));
-  RunPendingTasks();
-
-  EXPECT_EQ(cast_channel::READY_STATE_CLOSED, socket_->ready_state());
-  EXPECT_EQ(cast_channel::CHANNEL_ERROR_AUTHENTICATION_ERROR,
-            socket_->error_state());
-}
-
-// Test connection error - cert extraction error (sync)
-TEST_F(CastSocketTest, TestConnectCertExtractionErrorSync) {
-  CreateCastSocket();
-  socket_->SetupTcpConnect(net::SYNCHRONOUS, net::OK);
-  socket_->SetupSslConnect(net::SYNCHRONOUS, net::OK);
-  // Set cert extraction to fail
-  socket_->SetExtractCertResult(false);
-
-  EXPECT_CALL(handler_, OnConnectComplete(CHANNEL_ERROR_AUTHENTICATION_ERROR));
-  socket_->Connect(std::move(delegate_),
-                   base::Bind(&CompleteHandler::OnConnectComplete,
-                              base::Unretained(&handler_)));
-  RunPendingTasks();
-
-  EXPECT_EQ(cast_channel::READY_STATE_CLOSED, socket_->ready_state());
-  EXPECT_EQ(cast_channel::CHANNEL_ERROR_AUTHENTICATION_ERROR,
-            socket_->error_state());
-}
-
 // Test connection error - challenge send fails
 TEST_F(CastSocketTest, TestConnectChallengeSendError) {
   CreateCastSocketSecure();
@@ -890,24 +781,6 @@
   EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state());
 }
 
-// Tests channel policy verification for device with no capabilities.
-TEST_F(CastSocketTest, TestChannelPolicyVerificationCapabilitiesNone) {
-  socket_ =
-      TestCastSocket::Create(logger_, cast_channel::CastDeviceCapability::NONE);
-  EXPECT_TRUE(socket_->TestVerifyChannelPolicyNone());
-  EXPECT_TRUE(socket_->TestVerifyChannelPolicyAudioOnly());
-}
-
-// Tests channel policy verification for device with video out capability.
-TEST_F(CastSocketTest, TestChannelPolicyVerificationCapabilitiesVideoOut) {
-  socket_ = TestCastSocket::Create(
-      logger_, cast_channel::CastDeviceCapability::VIDEO_OUT);
-  EXPECT_FALSE(socket_->audio_only());
-  EXPECT_TRUE(socket_->TestVerifyChannelPolicyNone());
-  EXPECT_FALSE(socket_->audio_only());
-  EXPECT_FALSE(socket_->TestVerifyChannelPolicyAudioOnly());
-  EXPECT_TRUE(socket_->audio_only());
-}
 }  // namespace cast_channel
 }  // namespace api
 }  // namespace extensions
diff --git a/extensions/browser/api/cast_channel/logger.cc b/extensions/browser/api/cast_channel/logger.cc
index eff4c8a..1a33008 100644
--- a/extensions/browser/api/cast_channel/logger.cc
+++ b/extensions/browser/api/cast_channel/logger.cc
@@ -157,10 +157,7 @@
   const net::IPAddress& ip = cast_socket.ip_endpoint().address();
   DCHECK(ip.IsValid());
   aggregated_socket_event.set_endpoint_id(ip.bytes().back());
-  aggregated_socket_event.set_channel_auth_type(cast_socket.channel_auth() ==
-                                                        CHANNEL_AUTH_TYPE_SSL
-                                                    ? proto::SSL
-                                                    : proto::SSL_VERIFIED);
+  aggregated_socket_event.set_channel_auth_type(proto::SSL_VERIFIED);
 }
 
 void Logger::LogSocketEvent(int channel_id, EventType event_type) {
diff --git a/extensions/common/api/cast_channel.idl b/extensions/common/api/cast_channel.idl
index 33af514fd..0d695b6 100644
--- a/extensions/common/api/cast_channel.idl
+++ b/extensions/common/api/cast_channel.idl
@@ -51,8 +51,6 @@
 
   // Authentication methods that may be required to connect to a Cast receiver.
   enum ChannelAuthType {
-    // SSL over TCP.
-    ssl,
     // SSL over TCP with challenge and receiver signature verification.
     ssl_verified
   };
diff --git a/extensions/renderer/dispatcher.cc b/extensions/renderer/dispatcher.cc
index 7e464779..0642390 100644
--- a/extensions/renderer/dispatcher.cc
+++ b/extensions/renderer/dispatcher.cc
@@ -747,6 +747,8 @@
       std::make_pair(mojo::kConnectionModuleName, IDR_MOJO_CONNECTION_JS));
   resources.push_back(
       std::make_pair(mojo::kConnectorModuleName, IDR_MOJO_CONNECTOR_JS));
+  resources.push_back(std::make_pair(mojo::kInterfaceTypesModuleName,
+                                     IDR_MOJO_INTERFACE_TYPES_JS));
   resources.push_back(
       std::make_pair(mojo::kRouterModuleName, IDR_MOJO_ROUTER_JS));
   resources.push_back(
diff --git a/extensions/renderer/request_sender.cc b/extensions/renderer/request_sender.cc
index 896008d..76ed369 100644
--- a/extensions/renderer/request_sender.cc
+++ b/extensions/renderer/request_sender.cc
@@ -102,7 +102,7 @@
   params.request_id = request_id;
   params.has_callback = has_callback;
   params.user_gesture =
-      blink::WebUserGestureIndicator::isProcessingUserGesture();
+      blink::WebUserGestureIndicator::isProcessingUserGestureThreadSafe();
 
   // Set Service Worker specific params to default values.
   params.worker_thread_id = -1;
diff --git a/extensions/renderer/resources/media_router_bindings.js b/extensions/renderer/resources/media_router_bindings.js
index 16c8643..40ebfab8 100644
--- a/extensions/renderer/resources/media_router_bindings.js
+++ b/extensions/renderer/resources/media_router_bindings.js
@@ -206,15 +206,6 @@
     this.mrpm_ = new MediaRouteProvider(this);
 
     /**
-     * The message pipe that connects the Media Router to mrpm_ across
-     * browser/renderer IPC boundaries. Object must remain in scope for the
-     * lifetime of the connection to prevent the connection from closing
-     * automatically.
-     * @type {!mojo.MessagePipe}
-     */
-    this.pipe_ = core.createMessagePipe();
-
-    /**
      * Handle to a KeepAlive service object, which prevents the extension from
      * being suspended as long as it remains in scope.
      * @type {boolean}
@@ -222,16 +213,13 @@
     this.keepAlive_ = null;
 
     /**
-     * The stub used to bind the service delegate to the Mojo interface.
+     * The bindings to bind the service delegate to the Mojo interface.
      * Object must remain in scope for the lifetime of the connection to
      * prevent the connection from closing automatically.
-     * @type {!mojom.MediaRouter}
+     * @type {!bindings.Binding}
      */
-    this.mediaRouteProviderStub_ = connector.bindHandleToStub(
-        this.pipe_.handle0, mediaRouterMojom.MediaRouteProvider);
-
-    // Link mediaRouteProviderStub_ to the provider manager delegate.
-    bindings.StubBindings(this.mediaRouteProviderStub_).delegate = this.mrpm_;
+    this.mediaRouteProviderBinding_ = new bindings.Binding(
+        mediaRouterMojom.MediaRouteProvider, this.mrpm_);
   }
 
   /**
@@ -239,10 +227,11 @@
    * @return {!Promise<string>} Instance ID for the Media Router.
    */
   MediaRouter.prototype.start = function() {
-    return this.service_.registerMediaRouteProvider(this.pipe_.handle1).then(
-        function(result) {
-          return result.instance_id;
-        }.bind(this));
+    return this.service_.registerMediaRouteProvider(
+        this.mediaRouteProviderBinding_.createInterfacePtrAndBind()).then(
+            function(result) {
+      return result.instance_id;
+    }.bind(this));
   }
 
   /**
@@ -716,14 +705,14 @@
   /**
    * Sends a binary message to the route designated by |routeId|.
    * @param {!string} routeId
-   * @param {!Uint8Array} data
+   * @param {!Array<number>} data
    * @return {!Promise.<boolean>} Resolved with true if the data was sent,
    *    or false on failure.
    */
   MediaRouteProvider.prototype.sendRouteBinaryMessage = function(
     routeId, data) {
     this.handlers_.onBeforeInvokeHandler();
-    return this.handlers_.sendRouteBinaryMessage(routeId, data)
+    return this.handlers_.sendRouteBinaryMessage(routeId, new Uint8Array(data))
         .then(function() {
           return {'sent': true};
         }, function() {
diff --git a/gpu/BUILD.gn b/gpu/BUILD.gn
index cca31195..844a14eb 100644
--- a/gpu/BUILD.gn
+++ b/gpu/BUILD.gn
@@ -402,7 +402,7 @@
   libfuzzer_options = [ "max_len=16384" ]
 }
 
-fuzzer_test("gpu_fuzzer_angle") {
+fuzzer_test("gpu_angle_fuzzer") {
   sources = [
     "command_buffer/tests/fuzzer_main.cc",
   ]
diff --git a/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_stream_texture_matrix.txt b/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_stream_texture_matrix.txt
index 1744f895..62626cf8 100644
--- a/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_stream_texture_matrix.txt
+++ b/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_stream_texture_matrix.txt
@@ -23,6 +23,8 @@
     of a stream texture.  Intended for use with Android SurfaceTexture, which
     doesn't provide the value until the front buffer is latched.
 
+    Also allows hints about whether an image could be promoted to an overlay.
+
 New Procedures and Functions
 
     The command
@@ -44,6 +46,29 @@
     <transform> Provides an additional transform matrix that is applied
       prior to the the stream texture transformation matrix.
 
+    The command
+
+       void OverlayPromotionHintCHROMIUM(
+               GLuint texture,
+               GLboolean promotion_hint,
+               GLint display_x,
+               GLint display_y)
+
+    Provides a hint about whether the GLImage bound to texture could be promoted
+    to an overlay or not.
+
+    <texture> is the texture id, which should have a stream texture image bound
+      to it.
+    <promotion_hint> indicates whether the GLImage could be promoted.
+    <display_x> is the x coordinate of the origin of the overlay if the image
+      could be promoted.  Otherwise, it is 0.
+    <display_y> is the y coordinate of the origin of the overlay if the image
+      could be promoted.  Otherwise, it is 0.
+
+
+    If <texture> is not a valid texture, or if it doesn't have a stream texture
+    image bound to it, then no action is taken.
+
 Errors
 
     None.
diff --git a/gpu/GLES2/gl2chromium_autogen.h b/gpu/GLES2/gl2chromium_autogen.h
index ad54560b..4a703a8 100644
--- a/gpu/GLES2/gl2chromium_autogen.h
+++ b/gpu/GLES2/gl2chromium_autogen.h
@@ -382,6 +382,8 @@
 #define glGetFragDataIndexEXT GLES2_GET_FUN(GetFragDataIndexEXT)
 #define glUniformMatrix4fvStreamTextureMatrixCHROMIUM \
   GLES2_GET_FUN(UniformMatrix4fvStreamTextureMatrixCHROMIUM)
+#define glOverlayPromotionHintCHROMIUM \
+  GLES2_GET_FUN(OverlayPromotionHintCHROMIUM)
 #define glSwapBuffersWithDamageCHROMIUM \
   GLES2_GET_FUN(SwapBuffersWithDamageCHROMIUM)
 
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py
index 2cb8a76..dab6327 100755
--- a/gpu/command_buffer/build_gles2_cmd_buffer.py
+++ b/gpu/command_buffer/build_gles2_cmd_buffer.py
@@ -3480,6 +3480,12 @@
     'result': ['uint32_t'],
     'trace_level': 1,
   },
+  'OverlayPromotionHintCHROMIUM': {
+    'decoder_func': 'DoOverlayPromotionHintCHROMIUM',
+    'extension': "CHROMIUM_uniform_stream_texture_matrix",
+    'unit_test': False,
+    'client_test': False,
+  },
   'PauseTransformFeedback': {
     'decoder_func': 'DoPauseTransformFeedback',
     'unit_test': False,
diff --git a/gpu/command_buffer/client/gles2_c_lib_autogen.h b/gpu/command_buffer/client/gles2_c_lib_autogen.h
index 934fe97..ebf22172 100644
--- a/gpu/command_buffer/client/gles2_c_lib_autogen.h
+++ b/gpu/command_buffer/client/gles2_c_lib_autogen.h
@@ -1709,6 +1709,13 @@
   gles2::GetGLContext()->UniformMatrix4fvStreamTextureMatrixCHROMIUM(
       location, transpose, transform);
 }
+void GL_APIENTRY GLES2OverlayPromotionHintCHROMIUM(GLuint texture,
+                                                   GLboolean promotion_hint,
+                                                   GLint display_x,
+                                                   GLint display_y) {
+  gles2::GetGLContext()->OverlayPromotionHintCHROMIUM(texture, promotion_hint,
+                                                      display_x, display_y);
+}
 void GL_APIENTRY GLES2SwapBuffersWithDamageCHROMIUM(GLint x,
                                                     GLint y,
                                                     GLint width,
@@ -3015,6 +3022,10 @@
             glUniformMatrix4fvStreamTextureMatrixCHROMIUM),
     },
     {
+        "glOverlayPromotionHintCHROMIUM",
+        reinterpret_cast<GLES2FunctionPointer>(glOverlayPromotionHintCHROMIUM),
+    },
+    {
         "glSwapBuffersWithDamageCHROMIUM",
         reinterpret_cast<GLES2FunctionPointer>(glSwapBuffersWithDamageCHROMIUM),
     },
diff --git a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
index 5cb4479..c893a28 100644
--- a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
+++ b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
@@ -3166,6 +3166,17 @@
   }
 }
 
+void OverlayPromotionHintCHROMIUM(GLuint texture,
+                                  GLboolean promotion_hint,
+                                  GLint display_x,
+                                  GLint display_y) {
+  gles2::cmds::OverlayPromotionHintCHROMIUM* c =
+      GetCmdSpace<gles2::cmds::OverlayPromotionHintCHROMIUM>();
+  if (c) {
+    c->Init(texture, promotion_hint, display_x, display_y);
+  }
+}
+
 void SwapBuffersWithDamageCHROMIUM(GLint x,
                                    GLint y,
                                    GLint width,
diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h
index 0635ca1e..23efadd 100644
--- a/gpu/command_buffer/client/gles2_implementation_autogen.h
+++ b/gpu/command_buffer/client/gles2_implementation_autogen.h
@@ -1199,6 +1199,11 @@
     GLboolean transpose,
     const GLfloat* transform) override;
 
+void OverlayPromotionHintCHROMIUM(GLuint texture,
+                                  GLboolean promotion_hint,
+                                  GLint display_x,
+                                  GLint display_y) override;
+
 void SwapBuffersWithDamageCHROMIUM(GLint x,
                                    GLint y,
                                    GLint width,
diff --git a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h
index 7f55484..4dfde269 100644
--- a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h
+++ b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h
@@ -3488,4 +3488,18 @@
   CheckGLError();
 }
 
+void GLES2Implementation::OverlayPromotionHintCHROMIUM(GLuint texture,
+                                                       GLboolean promotion_hint,
+                                                       GLint display_x,
+                                                       GLint display_y) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glOverlayPromotionHintCHROMIUM("
+                     << texture << ", "
+                     << GLES2Util::GetStringBool(promotion_hint) << ", "
+                     << display_x << ", " << display_y << ")");
+  helper_->OverlayPromotionHintCHROMIUM(texture, promotion_hint, display_x,
+                                        display_y);
+  CheckGLError();
+}
+
 #endif  // GPU_COMMAND_BUFFER_CLIENT_GLES2_IMPLEMENTATION_IMPL_AUTOGEN_H_
diff --git a/gpu/command_buffer/client/gles2_interface_autogen.h b/gpu/command_buffer/client/gles2_interface_autogen.h
index 0055e6c..4f57e64 100644
--- a/gpu/command_buffer/client/gles2_interface_autogen.h
+++ b/gpu/command_buffer/client/gles2_interface_autogen.h
@@ -886,6 +886,10 @@
     GLint location,
     GLboolean transpose,
     const GLfloat* transform) = 0;
+virtual void OverlayPromotionHintCHROMIUM(GLuint texture,
+                                          GLboolean promotion_hint,
+                                          GLint display_x,
+                                          GLint display_y) = 0;
 virtual void SwapBuffersWithDamageCHROMIUM(GLint x,
                                            GLint y,
                                            GLint width,
diff --git a/gpu/command_buffer/client/gles2_interface_stub_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_autogen.h
index 75af490..6851bf9 100644
--- a/gpu/command_buffer/client/gles2_interface_stub_autogen.h
+++ b/gpu/command_buffer/client/gles2_interface_stub_autogen.h
@@ -860,6 +860,10 @@
     GLint location,
     GLboolean transpose,
     const GLfloat* transform) override;
+void OverlayPromotionHintCHROMIUM(GLuint texture,
+                                  GLboolean promotion_hint,
+                                  GLint display_x,
+                                  GLint display_y) override;
 void SwapBuffersWithDamageCHROMIUM(GLint x,
                                    GLint y,
                                    GLint width,
diff --git a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
index ce62d91..bc012cd 100644
--- a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
+++ b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
@@ -1163,6 +1163,11 @@
     GLint /* location */,
     GLboolean /* transpose */,
     const GLfloat* /* transform */) {}
+void GLES2InterfaceStub::OverlayPromotionHintCHROMIUM(
+    GLuint /* texture */,
+    GLboolean /* promotion_hint */,
+    GLint /* display_x */,
+    GLint /* display_y */) {}
 void GLES2InterfaceStub::SwapBuffersWithDamageCHROMIUM(GLint /* x */,
                                                        GLint /* y */,
                                                        GLint /* width */,
diff --git a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h
index 9277de1..f69cddc 100644
--- a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h
+++ b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h
@@ -860,6 +860,10 @@
     GLint location,
     GLboolean transpose,
     const GLfloat* transform) override;
+void OverlayPromotionHintCHROMIUM(GLuint texture,
+                                  GLboolean promotion_hint,
+                                  GLint display_x,
+                                  GLint display_y) override;
 void SwapBuffersWithDamageCHROMIUM(GLint x,
                                    GLint y,
                                    GLint width,
diff --git a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h
index 2d08ece..abeb69d 100644
--- a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h
+++ b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h
@@ -2488,6 +2488,17 @@
                                                    transform);
 }
 
+void GLES2TraceImplementation::OverlayPromotionHintCHROMIUM(
+    GLuint texture,
+    GLboolean promotion_hint,
+    GLint display_x,
+    GLint display_y) {
+  TRACE_EVENT_BINARY_EFFICIENT0("gpu",
+                                "GLES2Trace::OverlayPromotionHintCHROMIUM");
+  gl_->OverlayPromotionHintCHROMIUM(texture, promotion_hint, display_x,
+                                    display_y);
+}
+
 void GLES2TraceImplementation::SwapBuffersWithDamageCHROMIUM(GLint x,
                                                              GLint y,
                                                              GLint width,
diff --git a/gpu/command_buffer/cmd_buffer_functions.txt b/gpu/command_buffer/cmd_buffer_functions.txt
index 1f579fdb..9372810 100644
--- a/gpu/command_buffer/cmd_buffer_functions.txt
+++ b/gpu/command_buffer/cmd_buffer_functions.txt
@@ -361,5 +361,6 @@
 
 // Extension CHROMIUM_stream_texture_matrix
 GL_APICALL void         GL_APIENTRY glUniformMatrix4fvStreamTextureMatrixCHROMIUM (GLintUniformLocation location, GLbooleanFalseOnly transpose, const GLfloat* transform);
+GL_APICALL void         GL_APIENTRY glOverlayPromotionHintCHROMIUM (GLidBindTexture texture, GLboolean promotion_hint, GLint display_x, GLint display_y);
 
 GL_APICALL void         GL_APIENTRY glSwapBuffersWithDamageCHROMIUM (GLint x, GLint y, GLint width, GLint height);
diff --git a/gpu/command_buffer/common/gles2_cmd_format_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_autogen.h
index ff02094..8383d51 100644
--- a/gpu/command_buffer/common/gles2_cmd_format_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_format_autogen.h
@@ -15553,6 +15553,60 @@
               "offset of UniformMatrix4fvStreamTextureMatrixCHROMIUMImmediate "
               "transpose should be 8");
 
+struct OverlayPromotionHintCHROMIUM {
+  typedef OverlayPromotionHintCHROMIUM ValueType;
+  static const CommandId kCmdId = kOverlayPromotionHintCHROMIUM;
+  static const cmd::ArgFlags kArgFlags = cmd::kFixed;
+  static const uint8_t cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
+
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
+  }
+
+  void SetHeader() { header.SetCmd<ValueType>(); }
+
+  void Init(GLuint _texture,
+            GLboolean _promotion_hint,
+            GLint _display_x,
+            GLint _display_y) {
+    SetHeader();
+    texture = _texture;
+    promotion_hint = _promotion_hint;
+    display_x = _display_x;
+    display_y = _display_y;
+  }
+
+  void* Set(void* cmd,
+            GLuint _texture,
+            GLboolean _promotion_hint,
+            GLint _display_x,
+            GLint _display_y) {
+    static_cast<ValueType*>(cmd)->Init(_texture, _promotion_hint, _display_x,
+                                       _display_y);
+    return NextCmdAddress<ValueType>(cmd);
+  }
+
+  gpu::CommandHeader header;
+  uint32_t texture;
+  uint32_t promotion_hint;
+  int32_t display_x;
+  int32_t display_y;
+};
+
+static_assert(sizeof(OverlayPromotionHintCHROMIUM) == 20,
+              "size of OverlayPromotionHintCHROMIUM should be 20");
+static_assert(offsetof(OverlayPromotionHintCHROMIUM, header) == 0,
+              "offset of OverlayPromotionHintCHROMIUM header should be 0");
+static_assert(offsetof(OverlayPromotionHintCHROMIUM, texture) == 4,
+              "offset of OverlayPromotionHintCHROMIUM texture should be 4");
+static_assert(
+    offsetof(OverlayPromotionHintCHROMIUM, promotion_hint) == 8,
+    "offset of OverlayPromotionHintCHROMIUM promotion_hint should be 8");
+static_assert(offsetof(OverlayPromotionHintCHROMIUM, display_x) == 12,
+              "offset of OverlayPromotionHintCHROMIUM display_x should be 12");
+static_assert(offsetof(OverlayPromotionHintCHROMIUM, display_y) == 16,
+              "offset of OverlayPromotionHintCHROMIUM display_y should be 16");
+
 struct SwapBuffersWithDamageCHROMIUM {
   typedef SwapBuffersWithDamageCHROMIUM ValueType;
   static const CommandId kCmdId = kSwapBuffersWithDamageCHROMIUM;
diff --git a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
index 68f1dce..a44c706 100644
--- a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
@@ -5214,6 +5214,22 @@
       next_cmd, sizeof(cmd) + RoundSizeToMultipleOfEntries(sizeof(data)));
 }
 
+TEST_F(GLES2FormatTest, OverlayPromotionHintCHROMIUM) {
+  cmds::OverlayPromotionHintCHROMIUM& cmd =
+      *GetBufferAs<cmds::OverlayPromotionHintCHROMIUM>();
+  void* next_cmd =
+      cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<GLboolean>(12),
+              static_cast<GLint>(13), static_cast<GLint>(14));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::OverlayPromotionHintCHROMIUM::kCmdId),
+            cmd.header.command);
+  EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
+  EXPECT_EQ(static_cast<GLuint>(11), cmd.texture);
+  EXPECT_EQ(static_cast<GLboolean>(12), cmd.promotion_hint);
+  EXPECT_EQ(static_cast<GLint>(13), cmd.display_x);
+  EXPECT_EQ(static_cast<GLint>(14), cmd.display_y);
+  CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
+}
+
 TEST_F(GLES2FormatTest, SwapBuffersWithDamageCHROMIUM) {
   cmds::SwapBuffersWithDamageCHROMIUM& cmd =
       *GetBufferAs<cmds::SwapBuffersWithDamageCHROMIUM>();
diff --git a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
index a69e5e9..3c92dc4 100644
--- a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
@@ -328,7 +328,8 @@
   OP(BindFragDataLocationEXTBucket)                        /* 569 */ \
   OP(GetFragDataIndexEXT)                                  /* 570 */ \
   OP(UniformMatrix4fvStreamTextureMatrixCHROMIUMImmediate) /* 571 */ \
-  OP(SwapBuffersWithDamageCHROMIUM)                        /* 572 */
+  OP(OverlayPromotionHintCHROMIUM)                         /* 572 */ \
+  OP(SwapBuffersWithDamageCHROMIUM)                        /* 573 */
 
 enum CommandId {
   kOneBeforeStartPoint =
diff --git a/gpu/command_buffer/service/gl_stream_texture_image.h b/gpu/command_buffer/service/gl_stream_texture_image.h
index daaa158e..5ab4f75 100644
--- a/gpu/command_buffer/service/gl_stream_texture_image.h
+++ b/gpu/command_buffer/service/gl_stream_texture_image.h
@@ -25,6 +25,10 @@
 
   void Flush() override {}
 
+  virtual void NotifyPromotionHint(bool promotion_hint,
+                                   int display_x,
+                                   int display_y) {}
+
  protected:
   ~GLStreamTextureImage() override {}
 
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 1746557..ba6b5ef 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -1672,6 +1672,12 @@
   // Wrapper for glLinkProgram
   void DoLinkProgram(GLuint program);
 
+  // Wrapper for glOverlayPromotionHintCHROMIUIM
+  void DoOverlayPromotionHintCHROMIUM(GLuint client_id,
+                                      GLboolean promotion_hint,
+                                      GLint display_x,
+                                      GLint display_y);
+
   // Wrapper for glReadBuffer
   void DoReadBuffer(GLenum src);
 
@@ -8556,6 +8562,31 @@
   ExitCommandProcessingEarly();
 }
 
+void GLES2DecoderImpl::DoOverlayPromotionHintCHROMIUM(GLuint client_id,
+                                                      GLboolean promotion_hint,
+                                                      GLint display_x,
+                                                      GLint display_y) {
+  if (client_id == 0)
+    return;
+
+  TextureRef* texture_ref = GetTexture(client_id);
+  if (!texture_ref) {
+    LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glOverlayPromotionHintCHROMIUM",
+                       "invalid texture id");
+    return;
+  }
+  GLStreamTextureImage* image =
+      texture_ref->texture()->GetLevelStreamTextureImage(
+          GL_TEXTURE_EXTERNAL_OES, 0);
+  if (!image) {
+    LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glOverlayPromotionHintCHROMIUM",
+                       "texture has no StreamTextureImage");
+    return;
+  }
+
+  image->NotifyPromotionHint(promotion_hint != GL_FALSE, display_x, display_y);
+}
+
 void GLES2DecoderImpl::DoReadBuffer(GLenum src) {
   Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER);
   if (framebuffer) {
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
index 1f961d1..2d8c7a4 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
@@ -5107,6 +5107,20 @@
   return error::kNoError;
 }
 
+error::Error GLES2DecoderImpl::HandleOverlayPromotionHintCHROMIUM(
+    uint32_t immediate_data_size,
+    const volatile void* cmd_data) {
+  const volatile gles2::cmds::OverlayPromotionHintCHROMIUM& c =
+      *static_cast<const volatile gles2::cmds::OverlayPromotionHintCHROMIUM*>(
+          cmd_data);
+  GLuint texture = c.texture;
+  GLboolean promotion_hint = static_cast<GLboolean>(c.promotion_hint);
+  GLint display_x = static_cast<GLint>(c.display_x);
+  GLint display_y = static_cast<GLint>(c.display_y);
+  DoOverlayPromotionHintCHROMIUM(texture, promotion_hint, display_x, display_y);
+  return error::kNoError;
+}
+
 bool GLES2DecoderImpl::SetCapabilityState(GLenum cap, bool enabled) {
   switch (cap) {
     case GL_BLEND:
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h
index e362fde..13cc98e 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h
@@ -945,3 +945,8 @@
     GLint location,
     GLboolean transpose,
     const volatile GLfloat* defaultValue);
+
+error::Error DoOverlayPromotionHintCHROMIUM(GLuint texture,
+                                            GLboolean promotion_hint,
+                                            GLint display_x,
+                                            GLint display_y);
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
index 554200f..5686838 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
@@ -3309,5 +3309,14 @@
   return error::kNoError;
 }
 
+error::Error GLES2DecoderPassthroughImpl::DoOverlayPromotionHintCHROMIUM(
+    GLuint texture,
+    GLboolean promotion_hint,
+    GLint display_x,
+    GLint display_y) {
+  NOTIMPLEMENTED();
+  return error::kNoError;
+}
+
 }  // namespace gles2
 }  // namespace gpu
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc
index 6f3935fa..811f0a13 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc
@@ -4130,5 +4130,23 @@
   return error::kNoError;
 }
 
+error::Error GLES2DecoderPassthroughImpl::HandleOverlayPromotionHintCHROMIUM(
+    uint32_t immediate_data_size,
+    const volatile void* cmd_data) {
+  const volatile gles2::cmds::OverlayPromotionHintCHROMIUM& c =
+      *static_cast<const volatile gles2::cmds::OverlayPromotionHintCHROMIUM*>(
+          cmd_data);
+  GLuint texture = c.texture;
+  GLboolean promotion_hint = static_cast<GLboolean>(c.promotion_hint);
+  GLint display_x = static_cast<GLint>(c.display_x);
+  GLint display_y = static_cast<GLint>(c.display_y);
+  error::Error error = DoOverlayPromotionHintCHROMIUM(texture, promotion_hint,
+                                                      display_x, display_y);
+  if (error != error::kNoError) {
+    return error;
+  }
+  return error::kNoError;
+}
+
 }  // namespace gles2
 }  // namespace gpu
diff --git a/ios/chrome/app/application_delegate/memory_warning_helper.h b/ios/chrome/app/application_delegate/memory_warning_helper.h
index 1d720d3f..28a3c07 100644
--- a/ios/chrome/app/application_delegate/memory_warning_helper.h
+++ b/ios/chrome/app/application_delegate/memory_warning_helper.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 IOS_CHROME_APP_APPLICATION_DELEGATE_MEMORY_RECOVERY_HELPER_H_
-#define IOS_CHROME_APP_APPLICATION_DELEGATE_MEMORY_RECOVERY_HELPER_H_
+#ifndef IOS_CHROME_APP_APPLICATION_DELEGATE_MEMORY_WARNING_HELPER_H_
+#define IOS_CHROME_APP_APPLICATION_DELEGATE_MEMORY_WARNING_HELPER_H_
 
 #import <Foundation/Foundation.h>
 
@@ -24,4 +24,4 @@
 
 @end
 
-#endif  // IOS_CHROME_APP_APPLICATION_DELEGATE_MEMORY_RECOVERY_HELPER_H_
+#endif  // IOS_CHROME_APP_APPLICATION_DELEGATE_MEMORY_WARNING_HELPER_H_
diff --git a/ios/chrome/browser/BUILD.gn b/ios/chrome/browser/BUILD.gn
index e5b8f4fa..5a7d3de 100644
--- a/ios/chrome/browser/BUILD.gn
+++ b/ios/chrome/browser/BUILD.gn
@@ -5,6 +5,7 @@
 import("//build/buildflag_header.gni")
 import("//build/config/features.gni")
 import("//build/config/ios/rules.gni")
+import("//rlz/features/features.gni")
 import("//third_party/protobuf/proto_library.gni")
 
 declare_args() {
@@ -121,6 +122,7 @@
     "//ios/web",
     "//ios/web:user_agent",
     "//net",
+    "//rlz/features",
     "//url",
   ]
   allow_circular_includes_from = [
@@ -182,6 +184,7 @@
     "//ios/web",
     "//ios/web/public/app",
     "//net",
+    "//rlz/features",
     "//ui/base",
   ]
 
diff --git a/ios/chrome/browser/DEPS b/ios/chrome/browser/DEPS
index 6b5b985..49d7087 100644
--- a/ios/chrome/browser/DEPS
+++ b/ios/chrome/browser/DEPS
@@ -94,6 +94,7 @@
   "+ios/public/provider/web",
   "+ios/web/public",
   "+net",
+  "+rlz/features",
   "+third_party/brotli",
   "+third_party/google_toolbox_for_mac",
   "+ui",
diff --git a/ios/chrome/browser/browser_state/chrome_browser_state_impl.h b/ios/chrome/browser/browser_state/chrome_browser_state_impl.h
index 54d5292..b1a99a1 100644
--- a/ios/chrome/browser/browser_state/chrome_browser_state_impl.h
+++ b/ios/chrome/browser/browser_state/chrome_browser_state_impl.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 IOS_CHROME_BROWSER_BROWSER_STATE_CHROME_BROWSER_STATE_IMPL_
-#define IOS_CHROME_BROWSER_BROWSER_STATE_CHROME_BROWSER_STATE_IMPL_
+#ifndef IOS_CHROME_BROWSER_BROWSER_STATE_CHROME_BROWSER_STATE_IMPL_H_
+#define IOS_CHROME_BROWSER_BROWSER_STATE_CHROME_BROWSER_STATE_IMPL_H_
 
 #include <memory>
 
@@ -105,4 +105,4 @@
   DISALLOW_COPY_AND_ASSIGN(ChromeBrowserStateImpl);
 };
 
-#endif  // IOS_CHROME_BROWSER_BROWSER_STATE_CHROME_BROWSER_STATE_IMPL_
+#endif  // IOS_CHROME_BROWSER_BROWSER_STATE_CHROME_BROWSER_STATE_IMPL_H_
diff --git a/ios/chrome/browser/browser_state_metrics/browser_state_metrics.h b/ios/chrome/browser/browser_state_metrics/browser_state_metrics.h
index dc3e048..397c93c 100644
--- a/ios/chrome/browser/browser_state_metrics/browser_state_metrics.h
+++ b/ios/chrome/browser/browser_state_metrics/browser_state_metrics.h
@@ -21,4 +21,4 @@
 
 void LogNumberOfBrowserStates(ios::ChromeBrowserStateManager* manager);
 
-#endif  // IOS_CHROME_BROWSER_BROWSER_STATE_BROWSER_STATE_METRICS_H_
+#endif  // IOS_CHROME_BROWSER_BROWSER_STATE_METRICS_BROWSER_STATE_METRICS_H_
diff --git a/ios/chrome/browser/browsing_data/browsing_data_counter_wrapper.h b/ios/chrome/browser/browsing_data/browsing_data_counter_wrapper.h
index 3428994..14f354c 100644
--- a/ios/chrome/browser/browsing_data/browsing_data_counter_wrapper.h
+++ b/ios/chrome/browser/browsing_data/browsing_data_counter_wrapper.h
@@ -57,4 +57,4 @@
   DISALLOW_COPY_AND_ASSIGN(BrowsingDataCounterWrapper);
 };
 
-#endif  // IOS_CHROME_BROWSER_BROWSING_DATA_BROWSING_DATA_COUNTER_WRAPPER_
+#endif  // IOS_CHROME_BROWSER_BROWSING_DATA_BROWSING_DATA_COUNTER_WRAPPER_H_
diff --git a/ios/chrome/browser/geolocation/CLLocation+OmniboxGeolocation.h b/ios/chrome/browser/geolocation/CLLocation+OmniboxGeolocation.h
index a535714..730b2f8 100644
--- a/ios/chrome/browser/geolocation/CLLocation+OmniboxGeolocation.h
+++ b/ios/chrome/browser/geolocation/CLLocation+OmniboxGeolocation.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 IOS_CHROME_BROWSER_GEOLOCATION_CLLOCATION_OMNIBOX_GEOLOCATION_H_
-#define IOS_CHROME_BROWSER_GEOLOCATION_CLLOCATION_OMNIBOX_GEOLOCATION_H_
+#ifndef IOS_CHROME_BROWSER_GEOLOCATION_CLLOCATION_OMNIBOXGEOLOCATION_H_
+#define IOS_CHROME_BROWSER_GEOLOCATION_CLLOCATION_OMNIBOXGEOLOCATION_H_
 
 #import <CoreLocation/CoreLocation.h>
 
@@ -24,4 +24,4 @@
 
 @end
 
-#endif  // IOS_CHROME_BROWSER_GEOLOCATION_CLLOCATION_OMNIBOX_GEOLOCATION_H_
+#endif  // IOS_CHROME_BROWSER_GEOLOCATION_CLLOCATION_OMNIBOXGEOLOCATION_H_
diff --git a/ios/chrome/browser/infobars/confirm_infobar_controller+protected.h b/ios/chrome/browser/infobars/confirm_infobar_controller+protected.h
index 6bf3b7f..04611cc 100644
--- a/ios/chrome/browser/infobars/confirm_infobar_controller+protected.h
+++ b/ios/chrome/browser/infobars/confirm_infobar_controller+protected.h
@@ -16,4 +16,4 @@
 - (void)updateInfobarLabel:(UIView<InfoBarViewProtocol>*)view;
 @end
 
-#endif  // IOS_CHROME_BROWSER_INFOBARS_CONFIRM_INFOBAR_CONTROLLER+PROTECTED_H_
+#endif  // IOS_CHROME_BROWSER_INFOBARS_CONFIRM_INFOBAR_CONTROLLER_PROTECTED_H_
diff --git a/ios/chrome/browser/ios_chrome_main_parts.mm b/ios/chrome/browser/ios_chrome_main_parts.mm
index 722cad2b..0b1e819 100644
--- a/ios/chrome/browser/ios_chrome_main_parts.mm
+++ b/ios/chrome/browser/ios_chrome_main_parts.mm
@@ -52,10 +52,11 @@
 #include "net/http/http_network_layer.h"
 #include "net/http/http_stream_factory.h"
 #include "net/url_request/url_request.h"
+#include "rlz/features/features.h"
 #include "ui/base/l10n/l10n_util_mac.h"
 #include "ui/base/resource/resource_bundle.h"
 
-#if defined(ENABLE_RLZ)
+#if BUILDFLAG(ENABLE_RLZ)
 #include "components/rlz/rlz_tracker.h"                        // nogncheck
 #include "ios/chrome/browser/rlz/rlz_tracker_delegate_impl.h"  // nogncheck
 #endif
@@ -172,7 +173,7 @@
   ios::ChromeBrowserState* last_used_browser_state =
       browser_state_manager->GetLastUsedBrowserState();
 
-#if defined(ENABLE_RLZ)
+#if BUILDFLAG(ENABLE_RLZ)
   // Init the RLZ library. This just schedules a task on the file thread to be
   // run sometime later. If this is the first run we record the installation
   // event.
@@ -187,7 +188,7 @@
       RLZTrackerDelegateImpl::IsGoogleDefaultSearch(last_used_browser_state),
       RLZTrackerDelegateImpl::IsGoogleHomepage(last_used_browser_state),
       RLZTrackerDelegateImpl::IsGoogleInStartpages(last_used_browser_state));
-#endif  // defined(ENABLE_RLZ)
+#endif  // BUILDFLAG(ENABLE_RLZ)
 
   TranslateServiceIOS::Initialize();
   language_usage_metrics::LanguageUsageMetrics::RecordAcceptLanguages(
diff --git a/ios/chrome/browser/metrics/ios_chrome_stability_metrics_provider.h b/ios/chrome/browser/metrics/ios_chrome_stability_metrics_provider.h
index 23c3969c..6f426cc 100644
--- a/ios/chrome/browser/metrics/ios_chrome_stability_metrics_provider.h
+++ b/ios/chrome/browser/metrics/ios_chrome_stability_metrics_provider.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 IOS_CHROME_BROWSER_METRICS_CHROME_STABILITY_METRICS_PROVIDER_H_
-#define IOS_CHROME_BROWSER_METRICS_CHROME_STABILITY_METRICS_PROVIDER_H_
+#ifndef IOS_CHROME_BROWSER_METRICS_IOS_CHROME_STABILITY_METRICS_PROVIDER_H_
+#define IOS_CHROME_BROWSER_METRICS_IOS_CHROME_STABILITY_METRICS_PROVIDER_H_
 
 #include "base/macros.h"
 #include "base/metrics/user_metrics.h"
@@ -43,4 +43,4 @@
   DISALLOW_COPY_AND_ASSIGN(IOSChromeStabilityMetricsProvider);
 };
 
-#endif  // IOS_CHROME_BROWSER_METRICS_CHROME_STABILITY_METRICS_PROVIDER_H_
+#endif  // IOS_CHROME_BROWSER_METRICS_IOS_CHROME_STABILITY_METRICS_PROVIDER_H_
diff --git a/ios/chrome/browser/passwords/ios_chrome_password_manager_setting_migrator_service_factory.h b/ios/chrome/browser/passwords/ios_chrome_password_manager_setting_migrator_service_factory.h
index d8f1f66..8b1a9d4 100644
--- a/ios/chrome/browser/passwords/ios_chrome_password_manager_setting_migrator_service_factory.h
+++ b/ios/chrome/browser/passwords/ios_chrome_password_manager_setting_migrator_service_factory.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 IOS_CHROME_BROWSER_PASSWORDS_IOS_PASSWORD_MANAGER_SETTING_MIGRATOR_SERVICE_FACTORY_H_
-#define IOS_CHROME_BROWSER_PASSWORDS_IOS_PASSWORD_MANAGER_SETTING_MIGRATOR_SERVICE_FACTORY_H_
+#ifndef IOS_CHROME_BROWSER_PASSWORDS_IOS_CHROME_PASSWORD_MANAGER_SETTING_MIGRATOR_SERVICE_FACTORY_H_
+#define IOS_CHROME_BROWSER_PASSWORDS_IOS_CHROME_PASSWORD_MANAGER_SETTING_MIGRATOR_SERVICE_FACTORY_H_
 
 #include <memory>
 
@@ -47,4 +47,4 @@
       web::BrowserState* context) const override;
 };
 
-#endif  // IOS_CHROME_BROWSER_PASSWORDS_IOS_PASSWORD_MANAGER_SETTING_MIGRATOR_SERVICE_FACTORY_H_
+#endif  // IOS_CHROME_BROWSER_PASSWORDS_IOS_CHROME_PASSWORD_MANAGER_SETTING_MIGRATOR_SERVICE_FACTORY_H_
diff --git a/ios/chrome/browser/physical_web/BUILD.gn b/ios/chrome/browser/physical_web/BUILD.gn
index 6a9caf1..5dd0611 100644
--- a/ios/chrome/browser/physical_web/BUILD.gn
+++ b/ios/chrome/browser/physical_web/BUILD.gn
@@ -20,6 +20,7 @@
     "//components/pref_registry",
     "//components/prefs",
     "//ios/chrome/browser",
+    "//ios/chrome/browser/browser_state",
     "//ios/chrome/browser/geolocation",
     "//ios/chrome/common/physical_web",
     "//url",
diff --git a/ios/chrome/browser/physical_web/ios_chrome_physical_web_data_source.h b/ios/chrome/browser/physical_web/ios_chrome_physical_web_data_source.h
index 76385430..40d0ebb 100644
--- a/ios/chrome/browser/physical_web/ios_chrome_physical_web_data_source.h
+++ b/ios/chrome/browser/physical_web/ios_chrome_physical_web_data_source.h
@@ -44,4 +44,4 @@
   DISALLOW_COPY_AND_ASSIGN(IOSChromePhysicalWebDataSource);
 };
 
-#endif  // IOS_CHROME_COMMON_PHYSICAL_WEB_IOS_CHROME_PHYSICAL_WEB_DATA_SOURCE_H_
+#endif  // IOS_CHROME_BROWSER_PHYSICAL_WEB_IOS_CHROME_PHYSICAL_WEB_DATA_SOURCE_H_
diff --git a/ios/chrome/browser/physical_web/start_physical_web_discovery.h b/ios/chrome/browser/physical_web/start_physical_web_discovery.h
index d6468b3..43901d1 100644
--- a/ios/chrome/browser/physical_web/start_physical_web_discovery.h
+++ b/ios/chrome/browser/physical_web/start_physical_web_discovery.h
@@ -7,8 +7,20 @@
 
 #include "components/prefs/pref_service.h"
 
+namespace ios {
+class ChromeBrowserState;
+}
+
 // Checks the environment and starts Physical Web discovery if the required
 // conditions are met.
+// Deprecated, use the version below that takes an ios::ChromeBrowserState.
+// TODO(mattreynolds): remove once downstream users have been switched to the
+// new method.
 void StartPhysicalWebDiscovery(PrefService* pref_service, bool is_incognito);
 
+// Checks the environment and starts Physical Web discovery if the required
+// conditions are met.
+void StartPhysicalWebDiscovery(PrefService* pref_service,
+                               ios::ChromeBrowserState* browser_state);
+
 #endif  // IOS_CHROME_BROWSER_PHYSICAL_WEB_START_PHYSICAL_WEB_DISCOVERY_H_
diff --git a/ios/chrome/browser/physical_web/start_physical_web_discovery.mm b/ios/chrome/browser/physical_web/start_physical_web_discovery.mm
index d6f37f0c..e1b9502 100644
--- a/ios/chrome/browser/physical_web/start_physical_web_discovery.mm
+++ b/ios/chrome/browser/physical_web/start_physical_web_discovery.mm
@@ -8,6 +8,7 @@
 
 #include "components/physical_web/data_source/physical_web_data_source.h"
 #include "ios/chrome/browser/application_context.h"
+#include "ios/chrome/browser/browser_state/chrome_browser_state.h"
 #import "ios/chrome/browser/experimental_flags.h"
 #import "ios/chrome/browser/geolocation/omnibox_geolocation_config.h"
 #include "ios/chrome/browser/physical_web/physical_web_constants.h"
@@ -58,3 +59,8 @@
     GetApplicationContext()->GetPhysicalWebDataSource()->StopDiscovery();
   }
 }
+
+void StartPhysicalWebDiscovery(PrefService* pref_service,
+                               ios::ChromeBrowserState* browser_state) {
+  StartPhysicalWebDiscovery(pref_service, browser_state->IsOffTheRecord());
+}
diff --git a/ios/chrome/browser/search_engines/BUILD.gn b/ios/chrome/browser/search_engines/BUILD.gn
index f101496c..d2226cb 100644
--- a/ios/chrome/browser/search_engines/BUILD.gn
+++ b/ios/chrome/browser/search_engines/BUILD.gn
@@ -3,6 +3,7 @@
 # found in the LICENSE file.
 
 import("//build/config/features.gni")
+import("//rlz/features/features.gni")
 
 source_set("search_engines") {
   sources = [
@@ -33,6 +34,7 @@
     "//ios/chrome/common",
     "//ios/web",
     "//net",
+    "//rlz/features",
     "//ui/base",
     "//url",
   ]
diff --git a/ios/chrome/browser/search_engines/template_url_service_factory.cc b/ios/chrome/browser/search_engines/template_url_service_factory.cc
index 65b0a25..1a95c85 100644
--- a/ios/chrome/browser/search_engines/template_url_service_factory.cc
+++ b/ios/chrome/browser/search_engines/template_url_service_factory.cc
@@ -20,8 +20,9 @@
 #include "ios/chrome/browser/search_engines/template_url_service_client_impl.h"
 #include "ios/chrome/browser/search_engines/ui_thread_search_terms_data.h"
 #include "ios/chrome/browser/web_data_service_factory.h"
+#include "rlz/features/features.h"
 
-#if defined(ENABLE_RLZ)
+#if BUILDFLAG(ENABLE_RLZ)
 #include "components/rlz/rlz_tracker.h"  // nogncheck
 #endif
 
@@ -29,7 +30,7 @@
 namespace {
 
 base::Closure GetDefaultSearchProviderChangedCallback() {
-#if defined(ENABLE_RLZ)
+#if BUILDFLAG(ENABLE_RLZ)
   return base::Bind(base::IgnoreResult(&rlz::RLZTracker::RecordProductEvent),
                     rlz_lib::CHROME, rlz::RLZTracker::ChromeOmnibox(),
                     rlz_lib::SET_TO_GOOGLE);
diff --git a/ios/chrome/browser/search_engines/ui_thread_search_terms_data.cc b/ios/chrome/browser/search_engines/ui_thread_search_terms_data.cc
index 44669b1e..03eaaba 100644
--- a/ios/chrome/browser/search_engines/ui_thread_search_terms_data.cc
+++ b/ios/chrome/browser/search_engines/ui_thread_search_terms_data.cc
@@ -18,9 +18,10 @@
 #include "ios/chrome/common/channel_info.h"
 #include "ios/web/public/web_thread.h"
 #include "net/base/escape.h"
+#include "rlz/features/features.h"
 #include "url/gurl.h"
 
-#if defined(ENABLE_RLZ)
+#if BUILDFLAG(ENABLE_RLZ)
 #include "components/rlz/rlz_tracker.h"  // nogncheck
 #endif
 
@@ -60,7 +61,7 @@
   DCHECK(!from_app_list);
   DCHECK(thread_checker_.CalledOnValidThread());
   base::string16 rlz_string;
-#if defined(ENABLE_RLZ)
+#if BUILDFLAG(ENABLE_RLZ)
   // For organic brandcode do not use rlz at all.
   std::string brand;
   if (ios::google_brand::GetBrand(&brand) &&
diff --git a/ios/chrome/browser/share_extension/share_extension_item_receiver.h b/ios/chrome/browser/share_extension/share_extension_item_receiver.h
index 5cdd2fd..409d018 100644
--- a/ios/chrome/browser/share_extension/share_extension_item_receiver.h
+++ b/ios/chrome/browser/share_extension/share_extension_item_receiver.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 IOS_CHROME_BROWSER_UI_SHARE_EXTENSION_SHARE_EXTENSION_ITEM_RECEIVER_H_
-#define IOS_CHROME_BROWSER_UI_SHARE_EXTENSION_SHARE_EXTENSION_ITEM_RECEIVER_H_
+#ifndef IOS_CHROME_BROWSER_SHARE_EXTENSION_SHARE_EXTENSION_ITEM_RECEIVER_H_
+#define IOS_CHROME_BROWSER_SHARE_EXTENSION_SHARE_EXTENSION_ITEM_RECEIVER_H_
 
 #import <Foundation/Foundation.h>
 
@@ -32,4 +32,4 @@
 
 @end
 
-#endif  // IOS_CHROME_BROWSER_UI_SHARE_EXTENSION_SHARE_EXTENSION_ITEM_RECEIVER_H_
+#endif  // IOS_CHROME_BROWSER_SHARE_EXTENSION_SHARE_EXTENSION_ITEM_RECEIVER_H_
diff --git a/ios/chrome/browser/share_extension/share_extension_service.h b/ios/chrome/browser/share_extension/share_extension_service.h
index f747621..1988966 100644
--- a/ios/chrome/browser/share_extension/share_extension_service.h
+++ b/ios/chrome/browser/share_extension/share_extension_service.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 IOS_INTERNAL_CHROME_BROWSER_SHARE_EXTENSION_SHARE_EXTENSION_SERVICE_H_
-#define IOS_INTERNAL_CHROME_BROWSER_SHARE_EXTENSION_SHARE_EXTENSION_SERVICE_H_
+#ifndef IOS_CHROME_BROWSER_SHARE_EXTENSION_SHARE_EXTENSION_SERVICE_H_
+#define IOS_CHROME_BROWSER_SHARE_EXTENSION_SHARE_EXTENSION_SERVICE_H_
 
 #include "components/bookmarks/browser/base_bookmark_model_observer.h"
 #include "components/keyed_service/core/keyed_service.h"
@@ -44,4 +44,4 @@
   DISALLOW_COPY_AND_ASSIGN(ShareExtensionService);
 };
 
-#endif  // IOS_INTERNAL_CHROME_BROWSER_SHARE_EXTENSION_SHARE_EXTENSION_SERVICE_H_
+#endif  // IOS_CHROME_BROWSER_SHARE_EXTENSION_SHARE_EXTENSION_SERVICE_H_
diff --git a/ios/chrome/browser/signin/fake_signin_manager_builder.h b/ios/chrome/browser/signin/fake_signin_manager_builder.h
index 1d06ad4..f10af9d 100644
--- a/ios/chrome/browser/signin/fake_signin_manager_builder.h
+++ b/ios/chrome/browser/signin/fake_signin_manager_builder.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 IOS_CHROME_BROWSER_SIGNIN_FAKE_SIGNIN_MANAGER_H_
-#define IOS_CHROME_BROWSER_SIGNIN_FAKE_SIGNIN_MANAGER_H_
+#ifndef IOS_CHROME_BROWSER_SIGNIN_FAKE_SIGNIN_MANAGER_BUILDER_H_
+#define IOS_CHROME_BROWSER_SIGNIN_FAKE_SIGNIN_MANAGER_BUILDER_H_
 
 #include <memory>
 
@@ -22,4 +22,4 @@
 
 }  // namespace ios
 
-#endif  // IOS_CHROME_BROWSER_SIGNIN_FAKE_SIGNIN_MANAGER_H_
+#endif  // IOS_CHROME_BROWSER_SIGNIN_FAKE_SIGNIN_MANAGER_BUILDER_H_
diff --git a/ios/chrome/browser/ui/UIView+SizeClassSupport.h b/ios/chrome/browser/ui/UIView+SizeClassSupport.h
index 18b52428..af53dd0e 100644
--- a/ios/chrome/browser/ui/UIView+SizeClassSupport.h
+++ b/ios/chrome/browser/ui/UIView+SizeClassSupport.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 IOS_CHROME_BROWSER_UI_UIVIEW_SIZE_CLASS_SUPPORT_H_
-#define IOS_CHROME_BROWSER_UI_UIVIEW_SIZE_CLASS_SUPPORT_H_
+#ifndef IOS_CHROME_BROWSER_UI_UIVIEW_SIZECLASSSUPPORT_H_
+#define IOS_CHROME_BROWSER_UI_UIVIEW_SIZECLASSSUPPORT_H_
 
 #import <UIKit/UIKit.h>
 
@@ -26,4 +26,4 @@
 
 @end
 
-#endif  // IOS_CHROME_BROWSER_UI_UIVIEW_SIZE_CLASS_SUPPORT_H_
+#endif  // IOS_CHROME_BROWSER_UI_UIVIEW_SIZECLASSSUPPORT_H_
diff --git a/ios/chrome/browser/ui/commands/UIKit+ChromeExecuteCommand.h b/ios/chrome/browser/ui/commands/UIKit+ChromeExecuteCommand.h
index eed6920..50c31f2 100644
--- a/ios/chrome/browser/ui/commands/UIKit+ChromeExecuteCommand.h
+++ b/ios/chrome/browser/ui/commands/UIKit+ChromeExecuteCommand.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 IOS_CHROME_BROWSER_UI_UIKIT_CHROME_EXECUTE_COMMAND_H_
-#define IOS_CHROME_BROWSER_UI_UIKIT_CHROME_EXECUTE_COMMAND_H_
+#ifndef IOS_CHROME_BROWSER_UI_COMMANDS_UIKIT_CHROMEEXECUTECOMMAND_H_
+#define IOS_CHROME_BROWSER_UI_COMMANDS_UIKIT_CHROMEEXECUTECOMMAND_H_
 
 #import <UIKit/UIKit.h>
 
@@ -20,4 +20,4 @@
 - (void)chromeExecuteCommand:(id)sender;
 @end
 
-#endif  // IOS_CHROME_BROWSER_UI_UIKIT_CHROME_EXECUTE_COMMAND_H_
+#endif  // IOS_CHROME_BROWSER_UI_COMMANDS_UIKIT_CHROMEEXECUTECOMMAND_H_
diff --git a/ios/chrome/browser/ui/rtl_geometry.h b/ios/chrome/browser/ui/rtl_geometry.h
index f883c64..87cfbad 100644
--- a/ios/chrome/browser/ui/rtl_geometry.h
+++ b/ios/chrome/browser/ui/rtl_geometry.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 RTL_GEOMETRY_H_
-#define RTL_GEOMETRY_H_
+#ifndef IOS_CHROME_BROWSER_UI_RTL_GEOMETRY_H_
+#define IOS_CHROME_BROWSER_UI_RTL_GEOMETRY_H_
 
 #include <CoreGraphics/CoreGraphics.h>
 #import <UIKit/UIKit.h>
@@ -203,4 +203,4 @@
 // smaller sections of views should be determined case by case.
 NSLayoutFormatOptions LayoutOptionForRTLSupport();
 
-#endif  // RTL_GEOMETRY_H_
+#endif  // IOS_CHROME_BROWSER_UI_RTL_GEOMETRY_H_
diff --git a/ios/chrome/browser/ui/webui/crashes_ui.h b/ios/chrome/browser/ui/webui/crashes_ui.h
index 69ac0a93..3eae058 100644
--- a/ios/chrome/browser/ui/webui/crashes_ui.h
+++ b/ios/chrome/browser/ui/webui/crashes_ui.h
@@ -28,4 +28,4 @@
   DISALLOW_COPY_AND_ASSIGN(CrashesUI);
 };
 
-#endif  // CHROME_BROWSER_UI_WEBUI_CRASHES_UI_H_
+#endif  // IOS_CHROME_BROWSER_UI_WEBUI_CRASHES_UI_H_
diff --git a/ios/chrome/browser/web/web_controller_provider_impl.h b/ios/chrome/browser/web/web_controller_provider_impl.h
index 697bd56..4da9e7b 100644
--- a/ios/chrome/browser/web/web_controller_provider_impl.h
+++ b/ios/chrome/browser/web/web_controller_provider_impl.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 IOS_INTERNAL_CHROME_BROWSER_WEB_WEB_CONTROLLER_PROVIDER_IMPL_H_
-#define IOS_INTERNAL_CHROME_BROWSER_WEB_WEB_CONTROLLER_PROVIDER_IMPL_H_
+#ifndef IOS_CHROME_BROWSER_WEB_WEB_CONTROLLER_PROVIDER_IMPL_H_
+#define IOS_CHROME_BROWSER_WEB_WEB_CONTROLLER_PROVIDER_IMPL_H_
 
 #include <memory>
 
@@ -33,4 +33,4 @@
   bool suppresses_dialogs_;
 };
 
-#endif  // IOS_INTERNAL_CHROME_BROWSER_WEB_WEB_CONTROLLER_PROVIDER_IMPL_H_
+#endif  // IOS_CHROME_BROWSER_WEB_WEB_CONTROLLER_PROVIDER_IMPL_H_
diff --git a/ios/crnet/CrNet.h b/ios/crnet/CrNet.h
index ce93886e..4b1d4dc 100644
--- a/ios/crnet/CrNet.h
+++ b/ios/crnet/CrNet.h
@@ -2,6 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#ifndef IOS_CRNET_CRNET_H_
+#define IOS_CRNET_CRNET_H_
+
 #import <Foundation/Foundation.h>
 
 // A block, that takes a request, and returns YES if the request should
@@ -132,3 +135,5 @@
 + (void)clearCacheWithCompletionCallback:(ClearCacheCallback)completionBlock;
 
 @end
+
+#endif  // IOS_CRNET_CRNET_H_
diff --git a/ios/crnet/crnet_consumer/crnet_consumer_app_delegate.h b/ios/crnet/crnet_consumer/crnet_consumer_app_delegate.h
index 7f819d0..cb18ce98 100644
--- a/ios/crnet/crnet_consumer/crnet_consumer_app_delegate.h
+++ b/ios/crnet/crnet_consumer/crnet_consumer_app_delegate.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 CRNET_CONSUMER_APP_DELEGATE_
-#define CRNET_CONSUMER_APP_DELEGATE_
+#ifndef IOS_CRNET_CRNET_CONSUMER_CRNET_CONSUMER_APP_DELEGATE_H_
+#define IOS_CRNET_CRNET_CONSUMER_CRNET_CONSUMER_APP_DELEGATE_H_
 
 #import <UIKit/UIKit.h>
 
@@ -17,4 +17,4 @@
 
 @end
 
-#endif  // CRNET_CONSUMER_APP_DELEGATE_
+#endif  // IOS_CRNET_CRNET_CONSUMER_CRNET_CONSUMER_APP_DELEGATE_H_
diff --git a/ios/crnet/crnet_consumer/crnet_consumer_view_controller.h b/ios/crnet/crnet_consumer/crnet_consumer_view_controller.h
index e8539e9..73f0a42a 100644
--- a/ios/crnet/crnet_consumer/crnet_consumer_view_controller.h
+++ b/ios/crnet/crnet_consumer/crnet_consumer_view_controller.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 CRNET_CONSUMER_VIEW_CONTROLLER_
-#define CRNET_CONSUMER_VIEW_CONTROLLER_
+#ifndef IOS_CRNET_CRNET_CONSUMER_CRNET_CONSUMER_VIEW_CONTROLLER_H_
+#define IOS_CRNET_CRNET_CONSUMER_CRNET_CONSUMER_VIEW_CONTROLLER_H_
 
 #import <Foundation/Foundation.h>
 #import <UIKit/UIKit.h>
@@ -11,4 +11,4 @@
 @interface CrNetConsumerViewController : UIViewController
 @end
 
-#endif  // CRNET_CONSUMER_VIEW_CONTROLLER_
+#endif  // IOS_CRNET_CRNET_CONSUMER_CRNET_CONSUMER_VIEW_CONTROLLER_H_
diff --git a/ios/public/provider/chrome/browser/geolocation_updater_provider.h b/ios/public/provider/chrome/browser/geolocation_updater_provider.h
index eb037ba..9f01d280 100644
--- a/ios/public/provider/chrome/browser/geolocation_updater_provider.h
+++ b/ios/public/provider/chrome/browser/geolocation_updater_provider.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 IOS_PUBLIC_PROVIDER_CHROME_BROWSER_GEOLOCATION_UPDATER_H
-#define IOS_PUBLIC_PROVIDER_CHROME_BROWSER_GEOLOCATION_UPDATER_H
+#ifndef IOS_PUBLIC_PROVIDER_CHROME_BROWSER_GEOLOCATION_UPDATER_PROVIDER_H_
+#define IOS_PUBLIC_PROVIDER_CHROME_BROWSER_GEOLOCATION_UPDATER_PROVIDER_H_
 
 #import <CoreLocation/CoreLocation.h>
 #import <Foundation/Foundation.h>
@@ -87,4 +87,4 @@
 
 }  // namespace ios
 
-#endif  // IOS_PUBLIC_PROVIDER_CHROME_BROWSER_GEOLOCATION_UPDATER_H
+#endif  // IOS_PUBLIC_PROVIDER_CHROME_BROWSER_GEOLOCATION_UPDATER_PROVIDER_H_
diff --git a/ios/public/provider/chrome/browser/spotlight/spotlight_provider.h b/ios/public/provider/chrome/browser/spotlight/spotlight_provider.h
index 9e9c5f20..78faeef 100644
--- a/ios/public/provider/chrome/browser/spotlight/spotlight_provider.h
+++ b/ios/public/provider/chrome/browser/spotlight/spotlight_provider.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 IOS_PUBLIC_PROVIDER_CHROME_BROWSER_SPOTLIGHT_SPOTLIGHT_PROVIDER_H
-#define IOS_PUBLIC_PROVIDER_CHROME_BROWSER_SPOTLIGHT_SPOTLIGHT_PROVIDER_H
+#ifndef IOS_PUBLIC_PROVIDER_CHROME_BROWSER_SPOTLIGHT_SPOTLIGHT_PROVIDER_H_
+#define IOS_PUBLIC_PROVIDER_CHROME_BROWSER_SPOTLIGHT_SPOTLIGHT_PROVIDER_H_
 
 #import <Foundation/Foundation.h>
 
@@ -36,4 +36,4 @@
   DISALLOW_COPY_AND_ASSIGN(SpotlightProvider);
 };
 
-#endif  // IOS_PUBLIC_PROVIDER_CHROME_BROWSER_SPOTLIGHT_SPOTLIGHT_PROVIDER_H
+#endif  // IOS_PUBLIC_PROVIDER_CHROME_BROWSER_SPOTLIGHT_SPOTLIGHT_PROVIDER_H_
diff --git a/ios/public/provider/chrome/browser/spotlight/test_spotlight_provider.h b/ios/public/provider/chrome/browser/spotlight/test_spotlight_provider.h
index 11eff13d..67f5589 100644
--- a/ios/public/provider/chrome/browser/spotlight/test_spotlight_provider.h
+++ b/ios/public/provider/chrome/browser/spotlight/test_spotlight_provider.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 IOS_PUBLIC_PROVIDER_CHROME_BROWSER_SPOTLIGHT_TEST_SPOTLIGHT_PROVIDER_H
-#define IOS_PUBLIC_PROVIDER_CHROME_BROWSER_SPOTLIGHT_TEST_SPOTLIGHT_PROVIDER_H
+#ifndef IOS_PUBLIC_PROVIDER_CHROME_BROWSER_SPOTLIGHT_TEST_SPOTLIGHT_PROVIDER_H_
+#define IOS_PUBLIC_PROVIDER_CHROME_BROWSER_SPOTLIGHT_TEST_SPOTLIGHT_PROVIDER_H_
 
 #import <Foundation/Foundation.h>
 
@@ -19,4 +19,4 @@
   NSArray* GetAdditionalKeywords() override;
 };
 
-#endif  // IOS_PUBLIC_PROVIDER_CHROME_BROWSER_SPOTLIGHT_TEST_SPOTLIGHT_PROVIDER_H
+#endif  // IOS_PUBLIC_PROVIDER_CHROME_BROWSER_SPOTLIGHT_TEST_SPOTLIGHT_PROVIDER_H_
diff --git a/ios/public/provider/chrome/browser/voice/voice_search_controller.h b/ios/public/provider/chrome/browser/voice/voice_search_controller.h
index e2dfb0b..578ec47ebb 100644
--- a/ios/public/provider/chrome/browser/voice/voice_search_controller.h
+++ b/ios/public/provider/chrome/browser/voice/voice_search_controller.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 IOS_PUBLIC_PROVIDER_CHROME_BROWSER_VOICE_VOICE_SEARCH_CONTROLLER_IMPL_H_
-#define IOS_PUBLIC_PROVIDER_CHROME_BROWSER_VOICE_VOICE_SEARCH_CONTROLLER_IMPL_H_
+#ifndef IOS_PUBLIC_PROVIDER_CHROME_BROWSER_VOICE_VOICE_SEARCH_CONTROLLER_H_
+#define IOS_PUBLIC_PROVIDER_CHROME_BROWSER_VOICE_VOICE_SEARCH_CONTROLLER_H_
 
 #include "base/memory/ref_counted.h"
 
@@ -57,4 +57,4 @@
   DISALLOW_COPY_AND_ASSIGN(VoiceSearchController);
 };
 
-#endif  // IOS_PUBLIC_PROVIDER_CHROME_BROWSER_VOICE_VOICE_SEARCH_CONTROLLER_IMPL_H_
+#endif  // IOS_PUBLIC_PROVIDER_CHROME_BROWSER_VOICE_VOICE_SEARCH_CONTROLLER_H_
diff --git a/ios/testing/BUILD.gn b/ios/testing/BUILD.gn
index 9772939..3ad58c9 100644
--- a/ios/testing/BUILD.gn
+++ b/ios/testing/BUILD.gn
@@ -67,6 +67,8 @@
     "data/http_server_files/fullscreen.html",
     "data/http_server_files/history.html",
     "data/http_server_files/history.js",
+    "data/http_server_files/history_go.html",
+    "data/http_server_files/history_go.js",
     "data/http_server_files/memory_usage.html",
     "data/http_server_files/multi_field_form.html",
     "data/http_server_files/pony.html",
diff --git a/ios/testing/data/http_server_files/history_go.html b/ios/testing/data/http_server_files/history_go.html
new file mode 100644
index 0000000..050a07dd1
--- /dev/null
+++ b/ios/testing/data/http_server_files/history_go.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+
+<!-- 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. -->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>History navigation</title>
+<script type="text/javascript" src="history_go.js"></script>
+</head>
+<body>
+<p></p>
+<div id='on-load-div'></div>
+<br>
+<div id='no-op-div'></div>
+<br>
+<div id='pop-state-received-div'></div>
+<br>
+<div id='state-object-div'></div>
+<br>
+<div id='hash-change-received-div'></div>
+</p>
+
+<input type="button" value="go-no-parameter" id="go-no-parameter"
+    onclick="goNoParameter()" /><br>
+<input type="button" value="go-zero" id="go-zero"
+    onclick="goZero()" /><br>
+<input type="button" value="go-2" id="go-2"
+    onclick="go2()" /><br>
+<input type="button" value="go-back-2" id="go-back-2"
+    onclick="goBack2()" /><br>
+
+</body>
+</html>
diff --git a/ios/testing/data/http_server_files/history_go.js b/ios/testing/data/http_server_files/history_go.js
new file mode 100644
index 0000000..543f186
--- /dev/null
+++ b/ios/testing/data/http_server_files/history_go.js
@@ -0,0 +1,75 @@
+// 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.
+
+// Adds event listeners and populates on-load-div.
+window.onload = function() {
+  window.addEventListener('popstate', onPopstate);
+  window.addEventListener('hashchange', onHashChange);
+  updateOnLoadText('OnLoadText');
+};
+
+// Populates pop-state-received-div and state-object-div upon a popstate event.
+var onPopstate = function(e) {
+  updatePopStateReceivedText(true);
+  updateStateObjectText(e.state);
+};
+
+// Populates hash-change-received-div upon receiving of a hashchange event.
+var onHashChange = function(e) {
+  updateHashChangeReceivedText(true);
+}
+
+var updateOnLoadText = function(text) {
+  document.getElementById('on-load-div').innerHTML = text;
+}
+
+var updateNoOpText = function(text) {
+  document.getElementById('no-op-div').innerHTML = text;
+}
+
+var updatePopStateReceivedText = function(received) {
+  var text = received ? 'PopStateReceived' : '';
+  document.getElementById('pop-state-received-div').innerHTML = text;
+}
+
+var updateStateObjectText = function(state) {
+  document.getElementById('state-object-div').innerHTML = state;
+}
+
+var updateHashChangeReceivedText = function(received) {
+  var text = received ? 'HashChangeReceived' : '';
+  document.getElementById('hash-change-received-div').innerHTML = text;
+}
+
+// Clears all div text an starts a timer that updates no-op-div with "NoOpText"
+// after 1s.  This allows tests to verify that no nagivations occur after a
+// no-op JavaScript call.
+var onButtonTapped = function() {
+  updateOnLoadText('');
+  updateNoOpText('');
+  updatePopStateReceivedText(false);
+  updateStateObjectText('');
+  updateHashChangeReceivedText(false);
+  setTimeout("updateNoOpText('NoOpText')", 1000);
+}
+
+var goNoParameter = function() {
+  onButtonTapped();
+  window.history.go();
+}
+
+var goZero = function() {
+  onButtonTapped();
+  window.history.go(0);
+}
+
+var go2 = function() {
+  onButtonTapped();
+  window.history.go(2);
+}
+
+var goBack2 = function() {
+  onButtonTapped();
+  window.history.go(-2);
+}
diff --git a/ios/web/ios_web_resources.grd b/ios/web/ios_web_resources.grd
index 8894fe3..f17ef25 100644
--- a/ios/web/ios_web_resources.grd
+++ b/ios/web/ios_web_resources.grd
@@ -14,6 +14,7 @@
       <include name="IDR_MOJO_CODEC_JS" file="../../mojo/public/js/codec.js" flattenhtml="true" type="BINDATA" />
       <include name="IDR_MOJO_CONNECTION_JS" file="../../mojo/public/js/connection.js" flattenhtml="true" type="BINDATA" />
       <include name="IDR_MOJO_CONNECTOR_JS" file="../../mojo/public/js/connector.js" flattenhtml="true" type="BINDATA" />
+      <include name="IDR_MOJO_INTERFACE_TYPES_JS" file="../../mojo/public/js/interface_types.js" flattenhtml="true" type="BINDATA" />
       <include name="IDR_MOJO_ROUTER_JS" file="../../mojo/public/js/router.js" flattenhtml="true" type="BINDATA" />
       <include name="IDR_MOJO_UNICODE_JS" file="../../mojo/public/js/unicode.js" flattenhtml="true" type="BINDATA" />
       <include name="IDR_MOJO_VALIDATOR_JS" file="../../mojo/public/js/validator.js" flattenhtml="true" type="BINDATA" />
diff --git a/ios/web/public/crw_browsing_data_store.h b/ios/web/public/crw_browsing_data_store.h
index 529d7e5..5dab276 100644
--- a/ios/web/public/crw_browsing_data_store.h
+++ b/ios/web/public/crw_browsing_data_store.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 IOS_WEB_CRW_BROWSING_DATA_STORE_H_
-#define IOS_WEB_CRW_BROWSING_DATA_STORE_H_
+#ifndef IOS_WEB_PUBLIC_CRW_BROWSING_DATA_STORE_H_
+#define IOS_WEB_PUBLIC_CRW_BROWSING_DATA_STORE_H_
 
 #import <Foundation/Foundation.h>
 
@@ -94,4 +94,4 @@
 
 @end
 
-#endif  // IOS_WEB_CRW_BROWSING_DATA_STORE_H_
+#endif  // IOS_WEB_PUBLIC_CRW_BROWSING_DATA_STORE_H_
diff --git a/ios/web/public/crw_browsing_data_store_delegate.h b/ios/web/public/crw_browsing_data_store_delegate.h
index 63fa9649..8686790 100644
--- a/ios/web/public/crw_browsing_data_store_delegate.h
+++ b/ios/web/public/crw_browsing_data_store_delegate.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 IOS_WEB_CRW_BROWSING_DATA_STORE_DELEGATE_H_
-#define IOS_WEB_CRW_BROWSING_DATA_STORE_DELEGATE_H_
+#ifndef IOS_WEB_PUBLIC_CRW_BROWSING_DATA_STORE_DELEGATE_H_
+#define IOS_WEB_PUBLIC_CRW_BROWSING_DATA_STORE_DELEGATE_H_
 
 #import <Foundation/Foundation.h>
 
@@ -50,4 +50,4 @@
 
 @end
 
-#endif  // IOS_WEB_CRW_BROWSING_DATA_STORE_DELEGATE_H_
+#endif  // IOS_WEB_PUBLIC_CRW_BROWSING_DATA_STORE_DELEGATE_H_
diff --git a/ios/web/public/favicon_url.h b/ios/web/public/favicon_url.h
index 765c292e..409f329 100644
--- a/ios/web/public/favicon_url.h
+++ b/ios/web/public/favicon_url.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 IOS_WEB_PUBLIC_FAVICON_URL_
-#define IOS_WEB_PUBLIC_FAVICON_URL_
+#ifndef IOS_WEB_PUBLIC_FAVICON_URL_H_
+#define IOS_WEB_PUBLIC_FAVICON_URL_H_
 
 #include <vector>
 
@@ -42,4 +42,4 @@
 
 } // namespace web
 
-#endif  // IOS_WEB_PUBLIC_FAVICON_URL_
+#endif  // IOS_WEB_PUBLIC_FAVICON_URL_H_
diff --git a/ios/web/public/load_committed_details.h b/ios/web/public/load_committed_details.h
index bb9a3c17..81dc914 100644
--- a/ios/web/public/load_committed_details.h
+++ b/ios/web/public/load_committed_details.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 IOS_WEB_PUBLIC_WEB_LOAD_COMMITTED_DETAILS_H_
-#define IOS_WEB_PUBLIC_WEB_LOAD_COMMITTED_DETAILS_H_
+#ifndef IOS_WEB_PUBLIC_LOAD_COMMITTED_DETAILS_H_
+#define IOS_WEB_PUBLIC_LOAD_COMMITTED_DETAILS_H_
 
 #include "url/gurl.h"
 
@@ -32,4 +32,4 @@
 
 }  // namespace web
 
-#endif  // IOS_WEB_PUBLIC_WEB_LOAD_COMMITTED_DETAILS_H_
+#endif  // IOS_WEB_PUBLIC_LOAD_COMMITTED_DETAILS_H_
diff --git a/ios/web/public/test/mock_image_data_fetcher.h b/ios/web/public/test/mock_image_data_fetcher.h
index 196b68f2..65e7b40 100644
--- a/ios/web/public/test/mock_image_data_fetcher.h
+++ b/ios/web/public/test/mock_image_data_fetcher.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 IOS_WEB_PUBLIC_IMAGE_FETCHER_MOCK_IMAGE_DATA_FETCHER_H_
-#define IOS_WEB_PUBLIC_IMAGE_FETCHER_MOCK_IMAGE_DATA_FETCHER_H_
+#ifndef IOS_WEB_PUBLIC_TEST_MOCK_IMAGE_DATA_FETCHER_H_
+#define IOS_WEB_PUBLIC_TEST_MOCK_IMAGE_DATA_FETCHER_H_
 
 #import "ios/web/public/image_fetcher/image_data_fetcher.h"
 
@@ -33,4 +33,4 @@
 
 }  // namespace web
 
-#endif  // IOS_WEB_PUBLIC_IMAGE_FETCHER_MOCK_IMAGE_DATA_FETCHER_H_
+#endif  // IOS_WEB_PUBLIC_TEST_MOCK_IMAGE_DATA_FETCHER_H_
diff --git a/ios/web/public/test/response_providers/string_response_provider.h b/ios/web/public/test/response_providers/string_response_provider.h
index c3e985c..e5a0f9e 100644
--- a/ios/web/public/test/response_providers/string_response_provider.h
+++ b/ios/web/public/test/response_providers/string_response_provider.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 IOS_WEB_PUBLIC_TEST_RESPONSE_PROVIDERS_STRING_RESPONSE_PROVIDER_
-#define IOS_WEB_PUBLIC_TEST_RESPONSE_PROVIDERS_STRING_RESPONSE_PROVIDER_
+#ifndef IOS_WEB_PUBLIC_TEST_RESPONSE_PROVIDERS_STRING_RESPONSE_PROVIDER_H_
+#define IOS_WEB_PUBLIC_TEST_RESPONSE_PROVIDERS_STRING_RESPONSE_PROVIDER_H_
 
 #include <string>
 
@@ -33,4 +33,4 @@
 
 }  // namespace web
 
-#endif  // IOS_WEB_PUBLIC_TEST_RESPONSE_PROVIDERS_STRING_RESPONSE_PROVIDER_
+#endif  // IOS_WEB_PUBLIC_TEST_RESPONSE_PROVIDERS_STRING_RESPONSE_PROVIDER_H_
diff --git a/ios/web/public/test/test_web_client.h b/ios/web/public/test/test_web_client.h
index 60d2a23..1514f112 100644
--- a/ios/web/public/test/test_web_client.h
+++ b/ios/web/public/test/test_web_client.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 WEB_TEST_WEB_PUBLIC_TEST_TEST_WEB_CLIENT_H_
-#define WEB_TEST_WEB_PUBLIC_TEST_TEST_WEB_CLIENT_H_
+#ifndef IOS_WEB_PUBLIC_TEST_TEST_WEB_CLIENT_H_
+#define IOS_WEB_PUBLIC_TEST_TEST_WEB_CLIENT_H_
 
 #import <Foundation/Foundation.h>
 
@@ -58,4 +58,4 @@
 
 }  // namespace web
 
-#endif // WEB_TEST_WEB_PUBLIC_TEST_TEST_WEB_CLIENT_H_
+#endif  // IOS_WEB_PUBLIC_TEST_TEST_WEB_CLIENT_H_
diff --git a/ios/web/public/test/web_js_test.h b/ios/web/public/test/web_js_test.h
index 9bdb0f0..f47ceb49 100644
--- a/ios/web/public/test/web_js_test.h
+++ b/ios/web/public/test/web_js_test.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 IOS_INTERNAL_CHROME_BROWSER_WEB_WEB_JS_TEST_H_
-#define IOS_INTERNAL_CHROME_BROWSER_WEB_WEB_JS_TEST_H_
+#ifndef IOS_WEB_PUBLIC_TEST_WEB_JS_TEST_H_
+#define IOS_WEB_PUBLIC_TEST_WEB_JS_TEST_H_
 
 #import <Foundation/Foundation.h>
 
@@ -112,4 +112,4 @@
 
 }  // namespace web
 
-#endif  // IOS_INTERNAL_CHROME_BROWSER_WEB_WEB_JS_TEST_H_
+#endif  // IOS_WEB_PUBLIC_TEST_WEB_JS_TEST_H_
diff --git a/ios/web/public/test/web_view_interaction_test_util.h b/ios/web/public/test/web_view_interaction_test_util.h
index 4edc117..a3c54d8 100644
--- a/ios/web/public/test/web_view_interaction_test_util.h
+++ b/ios/web/public/test/web_view_interaction_test_util.h
@@ -2,6 +2,9 @@
 // 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_WEB_VIEW_INTERACTION_TEST_UTIL_H_
+#define IOS_WEB_PUBLIC_TEST_WEB_VIEW_INTERACTION_TEST_UTIL_H_
+
 #import <UIKit/UIKit.h>
 
 #include <string>
@@ -43,3 +46,5 @@
                              const std::string& form_id);
 }  // namespace test
 }  // namespace web
+
+#endif  // IOS_WEB_PUBLIC_TEST_WEB_VIEW_INTERACTION_TEST_UTIL_H_
diff --git a/ios/web/test/data/mojo_test.js b/ios/web/test/data/mojo_test.js
index a41a743e..7b3a9e4 100644
--- a/ios/web/test/data/mojo_test.js
+++ b/ios/web/test/data/mojo_test.js
@@ -12,18 +12,19 @@
 function getBrowserProxy() {
   return new Promise(function(resolve, reject) {
     define([
+      'mojo/public/js/bindings',
       'mojo/public/js/connection',
       'ios/web/test/mojo_test.mojom',
       'content/public/renderer/frame_interfaces',
-    ], function(connection, mojom, frameInterfaces) {
+    ], function(bindings, connection, mojom, frameInterfaces) {
       var pageImpl, browserProxy;
 
       /** @constructor */
-      function TestPageImpl() {};
+      function TestPageImpl() {
+        this.binding = new bindings.Binding(mojom.TestPage, this);
+      }
 
       TestPageImpl.prototype = {
-        __proto__: mojom.TestPage.stubClass.prototype,
-
         /** @override */
         handleNativeMessage: function(result) {
           if (result.message == 'ack') {
@@ -39,7 +40,7 @@
           mojom.TestUIHandlerMojo);
       pageImpl = new TestPageImpl();
 
-      browserProxy.setClientPage(connection.bindStubDerivedImpl(pageImpl));
+      browserProxy.setClientPage(pageImpl.binding.createInterfacePtrAndBind());
       resolve(browserProxy);
     });
   });
diff --git a/ios/web/test/web_int_test.h b/ios/web/test/web_int_test.h
index cb6b7a2c..e2c10288 100644
--- a/ios/web/test/web_int_test.h
+++ b/ios/web/test/web_int_test.h
@@ -31,4 +31,4 @@
 
 }  // namespace web
 
-#endif  // IOS_WEB_TEST_WEB_TEST_H_
+#endif  // IOS_WEB_TEST_WEB_INT_TEST_H_
diff --git a/ios/web/web_state/js/resources/core.js b/ios/web/web_state/js/resources/core.js
index c08e6791..5562258 100644
--- a/ios/web/web_state/js/resources/core.js
+++ b/ios/web/web_state/js/resources/core.js
@@ -425,7 +425,7 @@
     invokeOnHost_({'command': 'window.history.forward'});
   };
   window.history.go = function(delta) {
-    invokeOnHost_({'command': 'window.history.go', 'value': delta});
+    invokeOnHost_({'command': 'window.history.go', 'value': delta | 0});
   };
   window.history.pushState = function(stateObject, pageTitle, pageUrl) {
     __gCrWeb.message.invokeOnHost(
diff --git a/ios/web/webui/crw_web_ui_manager.mm b/ios/web/webui/crw_web_ui_manager.mm
index 049f041..8100606 100644
--- a/ios/web/webui/crw_web_ui_manager.mm
+++ b/ios/web/webui/crw_web_ui_manager.mm
@@ -252,6 +252,7 @@
       {mojo::kCodecModuleName, IDR_MOJO_CODEC_JS},
       {mojo::kConnectionModuleName, IDR_MOJO_CONNECTION_JS},
       {mojo::kConnectorModuleName, IDR_MOJO_CONNECTOR_JS},
+      {mojo::kInterfaceTypesModuleName, IDR_MOJO_INTERFACE_TYPES_JS},
       {mojo::kRouterModuleName, IDR_MOJO_ROUTER_JS},
       {mojo::kUnicodeModuleName, IDR_MOJO_UNICODE_JS},
       {mojo::kValidatorModuleName, IDR_MOJO_VALIDATOR_JS},
diff --git a/ios/web/webui/url_data_manager_ios_backend.h b/ios/web/webui/url_data_manager_ios_backend.h
index e483c321..48878d6 100644
--- a/ios/web/webui/url_data_manager_ios_backend.h
+++ b/ios/web/webui/url_data_manager_ios_backend.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 IOS_INTERNAL_WEB_WEBUI_URL_DATA_MANAGER_BACKEND_IOS_H_
-#define IOS_INTERNAL_WEB_WEBUI_URL_DATA_MANAGER_BACKEND_IOS_H_
+#ifndef IOS_WEB_WEBUI_URL_DATA_MANAGER_IOS_BACKEND_H_
+#define IOS_WEB_WEBUI_URL_DATA_MANAGER_IOS_BACKEND_H_
 
 #include <map>
 #include <memory>
@@ -98,4 +98,4 @@
 
 }  // namespace web
 
-#endif  // IOS_INTERNAL_WEB_WEBUI_URL_DATA_MANAGER_BACKEND_IOS_H_
+#endif  // IOS_WEB_WEBUI_URL_DATA_MANAGER_IOS_BACKEND_H_
diff --git a/ios/web/webui/url_data_source_ios_impl.h b/ios/web/webui/url_data_source_ios_impl.h
index bb9b2b1..4420489 100644
--- a/ios/web/webui/url_data_source_ios_impl.h
+++ b/ios/web/webui/url_data_source_ios_impl.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 IOS_INTERNAL_WEB_WEBUI_URL_DATA_SOURCE_IMPL_IOS_H_
-#define IOS_INTERNAL_WEB_WEBUI_URL_DATA_SOURCE_IMPL_IOS_H_
+#ifndef IOS_WEB_WEBUI_URL_DATA_SOURCE_IOS_IMPL_H_
+#define IOS_WEB_WEBUI_URL_DATA_SOURCE_IOS_IMPL_H_
 
 #include <memory>
 
@@ -97,4 +97,4 @@
 
 }  // namespace web
 
-#endif  // IOS_INTERNAL_WEB_WEBUI_URL_DATA_SOURCE_IMPL_IOS_H_
+#endif  // IOS_WEB_WEBUI_URL_DATA_SOURCE_IOS_IMPL_H_
diff --git a/mash/simple_wm/simple_wm.cc b/mash/simple_wm/simple_wm.cc
index 1fad35b4..c77d4a7 100644
--- a/mash/simple_wm/simple_wm.cc
+++ b/mash/simple_wm/simple_wm.cc
@@ -4,11 +4,14 @@
 
 #include "mash/simple_wm/simple_wm.h"
 
+#include "base/observer_list.h"
 #include "base/strings/utf_string_conversions.h"
 #include "ui/aura/client/aura_constants.h"
+#include "ui/aura/layout_manager.h"
 #include "ui/display/screen_base.h"
 #include "ui/gfx/canvas.h"
 #include "ui/gfx/geometry/mojo/geometry.mojom.h"
+#include "ui/views/controls/button/md_text_button.h"
 #include "ui/views/controls/label.h"
 #include "ui/views/mus/aura_init.h"
 #include "ui/views/mus/mus_client.h"
@@ -26,6 +29,158 @@
 
 }  // namespace
 
+class SimpleWM::WindowListModelObserver {
+ public:
+  virtual void OnWindowAddedOrRemoved() = 0;
+  virtual void OnWindowTitleChanged(size_t index,
+                                    const base::string16& title) = 0;
+};
+
+class SimpleWM::WindowListModel : public aura::WindowObserver {
+ public:
+  explicit WindowListModel(aura::Window* window_container)
+      : window_container_(window_container) {
+    window_container_->AddObserver(this);
+  }
+  ~WindowListModel() override {
+    window_container_->RemoveObserver(this);
+    for (auto window : windows_)
+      window->RemoveObserver(this);
+  }
+
+  size_t GetSize() const {
+    return windows_.size();
+  }
+  base::string16 GetTitle(size_t index) const {
+    return windows_.at(index)->GetTitle();
+  }
+  aura::Window* GetWindow(size_t index) const {
+    return windows_.at(index);
+  }
+
+  void AddObserver(WindowListModelObserver* observer) {
+    observers_.AddObserver(observer);
+  }
+  void RemoveObserver(WindowListModelObserver* observer) {
+    observers_.RemoveObserver(observer);
+  }
+
+ private:
+  // aura::WindowObserver:
+  void OnWindowAdded(aura::Window* window) override {
+    if (window->parent() == window_container_)
+      AddWindow(window);
+    for (auto& observer : observers_)
+      observer.OnWindowAddedOrRemoved();
+  }
+  void OnWillRemoveWindow(aura::Window* window) override {
+    window->RemoveObserver(this);
+    for (auto& observer : observers_)
+      observer.OnWindowAddedOrRemoved();
+    auto it = std::find(windows_.begin(), windows_.end(), window);
+    DCHECK(it != windows_.end());
+    windows_.erase(it);
+  }
+  void OnWindowTitleChanged(aura::Window* window) override {
+    auto it = std::find(windows_.begin(), windows_.end(), window);
+    size_t index = it - windows_.begin();
+    for (auto& observer : observers_)
+      observer.OnWindowTitleChanged(index, window->GetTitle());
+  }
+
+  void AddWindow(aura::Window* window) {
+    window->AddObserver(this);
+    auto it = std::find(windows_.begin(), windows_.end(), window);
+    DCHECK(it == windows_.end());
+    windows_.push_back(window);
+  }
+
+  aura::Window* window_container_;
+  std::vector<aura::Window*> windows_;
+  base::ObserverList<WindowListModelObserver> observers_;
+
+  DISALLOW_COPY_AND_ASSIGN(WindowListModel);
+};
+
+class SimpleWM::WindowListView : public views::WidgetDelegateView,
+                                 public views::ButtonListener,
+                                 public SimpleWM::WindowListModelObserver {
+ public:
+  using ActivateCallback = base::Callback<void(aura::Window*)>;
+
+  WindowListView(WindowListModel* model, ActivateCallback activate_callback)
+      : model_(model), activate_callback_(activate_callback) {
+    model_->AddObserver(this);
+    Rebuild();
+  }
+  ~WindowListView() override {
+    model_->RemoveObserver(this);
+  }
+
+  static const int kButtonSpacing = 5;
+
+  // views::View
+  void Layout() override {
+    int x_offset = kButtonSpacing;
+    for (int i = 0; i < child_count(); ++i) {
+      View* v = child_at(i);
+      gfx::Size ps = v->GetPreferredSize();
+      gfx::Rect bounds(x_offset, kButtonSpacing, ps.width(), ps.height());
+      v->SetBoundsRect(bounds);
+      x_offset = bounds.right() + kButtonSpacing;
+    }
+  }
+  void OnPaint(gfx::Canvas* canvas) override {
+    canvas->DrawColor(SK_ColorLTGRAY);
+  }
+  gfx::Size GetPreferredSize() const override {
+    std::unique_ptr<views::MdTextButton> measure_button(
+        views::MdTextButton::Create(nullptr, base::UTF8ToUTF16("Sample")));
+    int height =
+        measure_button->GetPreferredSize().height() + 2 * kButtonSpacing;
+    return gfx::Size(0, height);
+  }
+
+ private:
+  // views::ButtonListener:
+  void ButtonPressed(views::Button* sender, const ui::Event& event) override {
+    activate_callback_.Run(
+        model_->GetWindow(static_cast<size_t>(sender->tag())));
+  }
+
+  // WindowListModelObserver:
+  void OnWindowAddedOrRemoved() override {
+    Rebuild();
+  }
+  void OnWindowTitleChanged(size_t index,
+                            const base::string16& new_title) override {
+    views::MdTextButton* label =
+        static_cast<views::MdTextButton*>(child_at(static_cast<int>(index)));
+    label->SetText(new_title);
+    Layout();
+  }
+
+  void Rebuild() {
+    RemoveAllChildViews(true);
+
+    size_t size = model_->GetSize();
+    for (size_t i = 0; i < size; ++i) {
+      base::string16 title = model_->GetTitle(i);
+      if (title.empty())
+        title = base::UTF8ToUTF16("Untitled");
+      views::MdTextButton* button = views::MdTextButton::Create(this, title);
+      button->set_tag(static_cast<int>(i));
+      AddChildView(button);
+    }
+    Layout();
+  }
+
+  WindowListModel* model_;
+  ActivateCallback activate_callback_;
+
+  DISALLOW_COPY_AND_ASSIGN(WindowListView);
+};
+
 class SimpleWM::FrameView : public views::WidgetDelegateView,
                             public aura::WindowObserver {
  public:
@@ -38,11 +193,14 @@
  private:
   // views::WidgetDelegateView:
   base::string16 GetWindowTitle() const override {
-    base::string16* title =
+    base::string16* title_from_property =
         client_window_->GetProperty(aura::client::kTitleKey);
-    if (!title)
-      return base::UTF8ToUTF16("(Window)");
-    return *title;
+    base::string16 title = title_from_property ? *title_from_property
+                                               : base::UTF8ToUTF16("(Window)");
+    // TODO(beng): quick hack to cause WindowObserver::OnWindowTitleChanged to
+    //             fire.
+    GetWidget()->GetNativeWindow()->SetTitle(title);
+    return title;
   }
   void Layout() override {
     // Client offsets are applied automatically by the window service.
@@ -63,6 +221,50 @@
   DISALLOW_COPY_AND_ASSIGN(FrameView);
 };
 
+class SimpleWM::DisplayLayoutManager : public aura::LayoutManager {
+ public:
+  DisplayLayoutManager(aura::Window* display_root,
+                       aura::Window* window_root,
+                       SimpleWM::WindowListView* window_list_view)
+      : display_root_(display_root),
+        window_root_(window_root),
+        window_list_view_(window_list_view) {}
+  ~DisplayLayoutManager() override {}
+
+ private:
+  // aura::LayoutManager:
+  void OnWindowResized() override {}
+  void OnWindowAddedToLayout(aura::Window* child) override {
+    Layout();
+  }
+  void OnWillRemoveWindowFromLayout(aura::Window* child) override {}
+  void OnWindowRemovedFromLayout(aura::Window* child) override {}
+  void OnChildWindowVisibilityChanged(aura::Window* child,
+                                      bool visible) override {}
+  void SetChildBounds(aura::Window* child,
+                      const gfx::Rect& requested_bounds) override {
+    SetChildBoundsDirect(child, requested_bounds);
+  }
+
+  void Layout() {
+    gfx::Size ps = window_list_view_->GetPreferredSize();
+    gfx::Rect bounds = display_root_->bounds();
+    gfx::Rect window_root_bounds = bounds;
+    window_root_bounds.set_height(window_root_bounds.height() - ps.height());
+    window_root_->SetBounds(window_root_bounds);
+    gfx::Rect window_list_view_bounds = bounds;
+    window_list_view_bounds.set_height(ps.height());
+    window_list_view_bounds.set_y(window_root_bounds.bottom());
+    window_list_view_->GetWidget()->SetBounds(window_list_view_bounds);
+  }
+
+  aura::Window* display_root_;
+  aura::Window* window_root_;
+  SimpleWM::WindowListView* window_list_view_;
+
+  DISALLOW_COPY_AND_ASSIGN(DisplayLayoutManager);
+};
+
 SimpleWM::SimpleWM() {}
 
 SimpleWM::~SimpleWM() {
@@ -165,7 +367,7 @@
   FrameView* frame_view = new FrameView(client_window);
   params.delegate = frame_view;
   params.native_widget = frame_native_widget;
-  params.parent = root_;
+  params.parent = window_root_;
   params.bounds = gfx::Rect(10, 10, 500, 500);
   frame_widget->Init(params);
   frame_widget->Show();
@@ -194,11 +396,36 @@
     std::unique_ptr<aura::WindowTreeHostMus> window_tree_host,
     const display::Display& display) {
   // Only handles a single root.
-  DCHECK(!root_);
+  DCHECK(!window_root_);
   window_tree_host_ = std::move(window_tree_host);
-  root_ = window_tree_host_->window();
+  window_tree_host_->InitHost();
+  display_root_ = window_tree_host_->window();
+  window_root_ = new aura::Window(nullptr);
+  window_root_->Init(ui::LAYER_NOT_DRAWN);
+  display_root_->AddChild(window_root_);
+  window_root_->Show();
+
+  window_list_model_ = base::MakeUnique<WindowListModel>(window_root_);
+
+  views::Widget* window_list_widget = new views::Widget;
+  views::NativeWidgetAura* window_list_widget_native_widget =
+      new views::NativeWidgetAura(window_list_widget, true);
+  views::Widget::InitParams params(views::Widget::InitParams::TYPE_CONTROL);
+  WindowListView* window_list_view =
+      new WindowListView(window_list_model_.get(),
+                         base::Bind(&SimpleWM::OnWindowListViewItemActivated,
+                                    base::Unretained(this)));
+  params.delegate = window_list_view;
+  params.native_widget = window_list_widget_native_widget;
+  params.parent = display_root_;
+  window_list_widget->Init(params);
+  window_list_widget->Show();
+
+  display_root_->SetLayoutManager(new DisplayLayoutManager(
+      display_root_, window_root_, window_list_view));
+
   DCHECK(window_manager_client_);
-  window_manager_client_->AddActivationParent(root_);
+  window_manager_client_->AddActivationParent(window_root_);
   ui::mojom::FrameDecorationValuesPtr frame_decoration_values =
       ui::mojom::FrameDecorationValues::New();
   frame_decoration_values->normal_client_area_insets.Set(
@@ -206,14 +433,14 @@
   frame_decoration_values->max_title_bar_button_width = 0;
   window_manager_client_->SetFrameDecorationValues(
       std::move(frame_decoration_values));
-  new wm::DefaultActivationClient(root_);
-  aura::client::SetFocusClient(root_, &focus_client_);
+  new wm::DefaultActivationClient(display_root_);
+  aura::client::SetFocusClient(display_root_, &focus_client_);
 }
 
 void SimpleWM::OnWmDisplayRemoved(
     aura::WindowTreeHostMus* window_tree_host) {
   DCHECK_EQ(window_tree_host, window_tree_host_.get());
-  root_ = nullptr;
+  window_root_ = nullptr;
   window_tree_host_.reset();
 }
 
@@ -240,5 +467,10 @@
   return it != client_window_to_frame_view_.end() ? it->second : nullptr;
 }
 
-}  // namespace simple_wm
+void SimpleWM::OnWindowListViewItemActivated(aura::Window* window) {
+  aura::client::ActivationClient* activation_client =
+      aura::client::GetActivationClient(window->GetRootWindow());
+  activation_client->ActivateWindow(window);
+}
 
+}  // namespace simple_wm
diff --git a/mash/simple_wm/simple_wm.h b/mash/simple_wm/simple_wm.h
index f677cc8..d0dc5a0 100644
--- a/mash/simple_wm/simple_wm.h
+++ b/mash/simple_wm/simple_wm.h
@@ -47,7 +47,11 @@
   ~SimpleWM() override;
 
  private:
+  class DisplayLayoutManager;
   class FrameView;
+  class WindowListModel;
+  class WindowListModelObserver;
+  class WindowListView;
 
   // service_manager::Service:
   void OnStart() override;
@@ -93,18 +97,22 @@
 
   FrameView* GetFrameViewForClientWindow(aura::Window* client_window);
 
+  void OnWindowListViewItemActivated(aura::Window* index);
+
   std::unique_ptr<views::AuraInit> aura_init_;
   ::wm::WMState wm_state_;
   std::unique_ptr<display::ScreenBase> screen_;
   aura::PropertyConverter property_converter_;
   aura::test::TestFocusClient focus_client_;
   std::unique_ptr<aura::WindowTreeHostMus> window_tree_host_;
-  aura::Window* root_ = nullptr;
+  aura::Window* display_root_ = nullptr;
+  aura::Window* window_root_ = nullptr;
   aura::WindowManagerClient* window_manager_client_ = nullptr;
   std::unique_ptr<aura::WindowTreeClient> window_tree_client_;
   std::unique_ptr<ui::Gpu> gpu_;
   std::unique_ptr<aura::MusContextFactory> compositor_context_factory_;
   std::map<aura::Window*, FrameView*> client_window_to_frame_view_;
+  std::unique_ptr<WindowListModel> window_list_model_;
 
   bool started_ = false;
 
diff --git a/media/base/demuxer_stream_provider.h b/media/base/demuxer_stream_provider.h
index dba6a6ce..3534550 100644
--- a/media/base/demuxer_stream_provider.h
+++ b/media/base/demuxer_stream_provider.h
@@ -39,6 +39,13 @@
   //   Returns the first stream of the given stream type (which is not allowed
   //   to be DemuxerStream::TEXT), or NULL if that type of stream is not
   //   present.
+  //   NOTE: Once a DemuxerStream pointer is returned from GetStream it is
+  //   guaranteed to stay valid for as long as the Demuxer/DemuxerStreamProvider
+  //   is alive. But make no assumption that once GetStream returned a non-null
+  //   pointer for some stream type then all subsequent calls will also return
+  //   non-null pointer for the same stream type. In MSE Javascript code can
+  //   remove SourceBuffer from a MediaSource at any point and this will make
+  //   some previously existing streams inaccessible/unavailable.
   // Other types:
   //   Should not be called.
   virtual DemuxerStream* GetStream(DemuxerStream::Type type) = 0;
diff --git a/media/remoting/remote_demuxer_stream_adapter.cc b/media/remoting/remote_demuxer_stream_adapter.cc
index cc66c185..d04b194 100644
--- a/media/remoting/remote_demuxer_stream_adapter.cc
+++ b/media/remoting/remote_demuxer_stream_adapter.cc
@@ -116,6 +116,9 @@
     case remoting::pb::RpcMessage::RPC_DS_INITIALIZE:
       Initialize(message->integer_value());
       break;
+    case remoting::pb::RpcMessage::RPC_DS_ENABLEBITSTREAMCONVERTER:
+      EnableBitstreamConverter();
+      break;
     case remoting::pb::RpcMessage::RPC_DS_READUNTIL:
       ReadUntil(std::move(message));
       break;
@@ -175,6 +178,11 @@
                             rpc_broker_, base::Passed(&rpc)));
 }
 
+void RemoteDemuxerStreamAdapter::EnableBitstreamConverter() {
+  DCHECK(media_task_runner_->BelongsToCurrentThread());
+  demuxer_stream_->EnableBitstreamConverter();
+}
+
 void RemoteDemuxerStreamAdapter::ReadUntil(
     std::unique_ptr<remoting::pb::RpcMessage> message) {
   DCHECK(media_task_runner_->BelongsToCurrentThread());
diff --git a/media/remoting/remote_demuxer_stream_adapter.h b/media/remoting/remote_demuxer_stream_adapter.h
index d610cacf..76ad475 100644
--- a/media/remoting/remote_demuxer_stream_adapter.h
+++ b/media/remoting/remote_demuxer_stream_adapter.h
@@ -74,6 +74,7 @@
 
   // RPC message tasks.
   void Initialize(int remote_callback_handle);
+  void EnableBitstreamConverter();
   void ReadUntil(std::unique_ptr<remoting::pb::RpcMessage> message);
   void RequestBuffer(int callback_handle);
   void SendReadAck(int callback_handle);
diff --git a/media/renderers/renderer_impl.cc b/media/renderers/renderer_impl.cc
index 87212d8..210e5cc 100644
--- a/media/renderers/renderer_impl.cc
+++ b/media/renderers/renderer_impl.cc
@@ -131,24 +131,11 @@
   DCHECK_EQ(state_, STATE_UNINITIALIZED);
   DCHECK(!init_cb.is_null());
   DCHECK(client);
-  DCHECK(demuxer_stream_provider->GetStream(DemuxerStream::AUDIO) ||
-         demuxer_stream_provider->GetStream(DemuxerStream::VIDEO));
 
   client_ = client;
   demuxer_stream_provider_ = demuxer_stream_provider;
   init_cb_ = init_cb;
 
-  DemuxerStream* audio_stream =
-      demuxer_stream_provider->GetStream(DemuxerStream::AUDIO);
-  if (audio_stream)
-    audio_stream->SetStreamStatusChangeCB(base::Bind(
-        &RendererImpl::RestartStreamPlayback, weak_this_, audio_stream));
-  DemuxerStream* video_stream =
-      demuxer_stream_provider->GetStream(DemuxerStream::VIDEO);
-  if (video_stream)
-    video_stream->SetStreamStatusChangeCB(base::Bind(
-        &RendererImpl::RestartStreamPlayback, weak_this_, video_stream));
-
   if (HasEncryptedStream() && !cdm_context_) {
     state_ = STATE_INIT_PENDING_CDM;
     return;
@@ -384,19 +371,23 @@
   PipelineStatusCB done_cb =
       base::Bind(&RendererImpl::OnAudioRendererInitializeDone, weak_this_);
 
-  if (!demuxer_stream_provider_->GetStream(DemuxerStream::AUDIO)) {
+  DemuxerStream* audio_stream =
+      demuxer_stream_provider_->GetStream(DemuxerStream::AUDIO);
+  if (!audio_stream) {
     audio_renderer_.reset();
     task_runner_->PostTask(FROM_HERE, base::Bind(done_cb, PIPELINE_OK));
     return;
   }
 
+  audio_stream->SetStreamStatusChangeCB(base::Bind(
+      &RendererImpl::RestartStreamPlayback, weak_this_, audio_stream));
+
   audio_renderer_client_.reset(
       new RendererClientInternal(DemuxerStream::AUDIO, this));
   // Note: After the initialization of a renderer, error events from it may
   // happen at any time and all future calls must guard against STATE_ERROR.
-  audio_renderer_->Initialize(
-      demuxer_stream_provider_->GetStream(DemuxerStream::AUDIO), cdm_context_,
-      audio_renderer_client_.get(), done_cb);
+  audio_renderer_->Initialize(audio_stream, cdm_context_,
+                              audio_renderer_client_.get(), done_cb);
 }
 
 void RendererImpl::OnAudioRendererInitializeDone(PipelineStatus status) {
@@ -429,17 +420,21 @@
   PipelineStatusCB done_cb =
       base::Bind(&RendererImpl::OnVideoRendererInitializeDone, weak_this_);
 
-  if (!demuxer_stream_provider_->GetStream(DemuxerStream::VIDEO)) {
+  DemuxerStream* video_stream =
+      demuxer_stream_provider_->GetStream(DemuxerStream::VIDEO);
+  if (!video_stream) {
     video_renderer_.reset();
     task_runner_->PostTask(FROM_HERE, base::Bind(done_cb, PIPELINE_OK));
     return;
   }
 
+  video_stream->SetStreamStatusChangeCB(base::Bind(
+      &RendererImpl::RestartStreamPlayback, weak_this_, video_stream));
+
   video_renderer_client_.reset(
       new RendererClientInternal(DemuxerStream::VIDEO, this));
   video_renderer_->Initialize(
-      demuxer_stream_provider_->GetStream(DemuxerStream::VIDEO), cdm_context_,
-      video_renderer_client_.get(),
+      video_stream, cdm_context_, video_renderer_client_.get(),
       base::Bind(&RendererImpl::GetWallClockTimes, base::Unretained(this)),
       done_cb);
 }
diff --git a/media/renderers/renderer_impl_unittest.cc b/media/renderers/renderer_impl_unittest.cc
index 1e3e706..9f9fbad 100644
--- a/media/renderers/renderer_impl_unittest.cc
+++ b/media/renderers/renderer_impl_unittest.cc
@@ -150,12 +150,34 @@
   void InitializeWithAudio() {
     CreateAudioStream();
     SetAudioRendererInitializeExpectations(PIPELINE_OK);
+    // There is a potential race between HTMLMediaElement/WMPI shutdown and
+    // renderers being initialized which might result in DemuxerStreamProvider
+    // GetStream suddenly returning NULL (see crbug.com/668604). So we are going
+    // to check here that GetStream will be invoked exactly 3 times during
+    // RendererImpl initialization to help catch potential issues. Currently the
+    // GetStream is invoked once directly from RendererImpl::Initialize, once
+    // indirectly from RendererImpl::Initialize via HasEncryptedStream and once
+    // from RendererImpl::InitializeAudioRenderer.
+    EXPECT_CALL(*demuxer_, GetStream(DemuxerStream::AUDIO))
+        .Times(2)
+        .WillRepeatedly(Return(audio_stream_.get()));
     InitializeAndExpect(PIPELINE_OK);
   }
 
   void InitializeWithVideo() {
     CreateVideoStream();
     SetVideoRendererInitializeExpectations(PIPELINE_OK);
+    // There is a potential race between HTMLMediaElement/WMPI shutdown and
+    // renderers being initialized which might result in DemuxerStreamProvider
+    // GetStream suddenly returning NULL (see crbug.com/668604). So we are going
+    // to check here that GetStream will be invoked exactly 3 times during
+    // RendererImpl initialization to help catch potential issues. Currently the
+    // GetStream is invoked once directly from RendererImpl::Initialize, once
+    // indirectly from RendererImpl::Initialize via HasEncryptedStream and once
+    // from RendererImpl::InitializeVideoRenderer.
+    EXPECT_CALL(*demuxer_, GetStream(DemuxerStream::VIDEO))
+        .Times(2)
+        .WillRepeatedly(Return(video_stream_.get()));
     InitializeAndExpect(PIPELINE_OK);
   }
 
diff --git a/mojo/edk/js/tests/connection_tests.js b/mojo/edk/js/tests/connection_tests.js
index 0b4b2134..2e8fc97f 100644
--- a/mojo/edk/js/tests/connection_tests.js
+++ b/mojo/edk/js/tests/connection_tests.js
@@ -4,14 +4,14 @@
 
 define([
     "gin/test/expect",
-    "mojo/public/js/connection",
+    "mojo/public/js/bindings",
     "mojo/public/js/core",
     "mojo/public/interfaces/bindings/tests/sample_interfaces.mojom",
     "mojo/public/interfaces/bindings/tests/sample_service.mojom",
     "mojo/public/js/threading",
     "gc",
 ], function(expect,
-            connection,
+            bindings,
             core,
             sample_interfaces,
             sample_service,
@@ -35,37 +35,34 @@
     function ServiceImpl() {
     }
 
-    ServiceImpl.prototype = Object.create(
-        sample_service.Service.stubClass.prototype);
-
     ServiceImpl.prototype.frobinate = function(foo, baz, port) {
       expect(foo.name).toBe("Example name");
       expect(baz).toBe(sample_service.Service.BazOptions.REGULAR);
-      expect(core.close(port)).toBe(core.RESULT_OK);
+      expect(port.ptr.isBound()).toBeTruthy();
+      port.ptr.reset();
 
       return Promise.resolve({result: 42});
     };
 
-    var pipe = core.createMessagePipe();
-    var anotherPipe = core.createMessagePipe();
+    var service = new sample_service.ServicePtr();
+    var serviceBinding = new bindings.Binding(sample_service.Service,
+                                              new ServiceImpl(),
+                                              bindings.makeRequest(service));
     var sourcePipe = core.createMessagePipe();
-
-    var connection0 = new connection.Connection(pipe.handle0, ServiceImpl);
-
-    var connection1 = new connection.Connection(
-        pipe.handle1, undefined, sample_service.Service.proxyClass);
+    var port = new sample_service.PortPtr();
+    var portRequest = bindings.makeRequest(port);
 
     var foo = new sample_service.Foo();
     foo.bar = new sample_service.Bar();
     foo.name = "Example name";
     foo.source = sourcePipe.handle0;
-    var promise = connection1.remote.frobinate(
-        foo, sample_service.Service.BazOptions.REGULAR, anotherPipe.handle0)
+    var promise = service.frobinate(
+        foo, sample_service.Service.BazOptions.REGULAR, port)
             .then(function(response) {
       expect(response.result).toBe(42);
 
-      connection0.close();
-      connection1.close();
+      service.ptr.reset();
+      serviceBinding.close();
 
       return Promise.resolve();
     });
@@ -73,38 +70,26 @@
     // sourcePipe.handle1 hasn't been closed yet.
     expect(core.close(sourcePipe.handle1)).toBe(core.RESULT_OK);
 
-    // anotherPipe.handle1 hasn't been closed yet.
-    expect(core.close(anotherPipe.handle1)).toBe(core.RESULT_OK);
+    // portRequest.handle hasn't been closed yet.
+    expect(core.close(portRequest.handle)).toBe(core.RESULT_OK);
 
     return promise;
   }
 
   function testWriteToClosedPipe() {
-    var pipe = core.createMessagePipe();
-    var anotherPipe = core.createMessagePipe();
+    var service = new sample_service.ServicePtr();
+    // Discard the interface request.
+    bindings.makeRequest(service);
 
-    var connection1 = new connection.Connection(
-        pipe.handle1, function() {}, sample_service.Service.proxyClass);
-
-    // Close the other end of the pipe.
-    core.close(pipe.handle0);
-
-    // Not observed yet because we haven't pumped events yet.
-    expect(connection1.encounteredError()).toBeFalsy();
-
-    var promise = connection1.remote.frobinate(
-        null, sample_service.Service.BazOptions.REGULAR, anotherPipe.handle0)
+    var promise = service.frobinate(
+        null, sample_service.Service.BazOptions.REGULAR, null)
             .then(function(response) {
       return Promise.reject("Unexpected response");
     }).catch(function(e) {
       // We should observe the closed pipe.
-      expect(connection1.encounteredError()).toBeTruthy();
       return Promise.resolve();
     });
 
-    // Write failures are not reported.
-    expect(connection1.encounteredError()).toBeFalsy();
-
     return promise;
   }
 
@@ -114,9 +99,6 @@
     function ProviderImpl() {
     }
 
-    ProviderImpl.prototype =
-        Object.create(sample_interfaces.Provider.stubClass.prototype);
-
     ProviderImpl.prototype.echoString = function(a) {
       return Promise.resolve({a: a});
     };
@@ -125,17 +107,13 @@
       return Promise.resolve({a: a, b: b});
     };
 
-    var pipe = core.createMessagePipe();
-
-    var connection0 = new connection.Connection(pipe.handle0, ProviderImpl);
-
-    var connection1 = new connection.Connection(
-        pipe.handle1, undefined, sample_interfaces.Provider.proxyClass);
-
-    var promise = connection1.remote.echoString("hello")
-        .then(function(response) {
+    var provider = new sample_interfaces.ProviderPtr();
+    var providerBinding = new bindings.Binding(sample_interfaces.Provider,
+                                               new ProviderImpl(),
+                                               bindings.makeRequest(provider));
+    var promise = provider.echoString("hello").then(function(response) {
       expect(response.a).toBe("hello");
-      return connection1.remote.echoStrings("hello", "world");
+      return provider.echoStrings("hello", "world");
     }).then(function(response) {
       expect(response.a).toBe("hello");
       expect(response.b).toBe("world");
@@ -143,7 +121,7 @@
       core.readMessage = function() {
         return { result: core.RESULT_UNKNOWN };
       };
-      return connection1.remote.echoString("goodbye");
+      return provider.echoString("goodbye");
     }).then(function() {
       throw Error("Expected echoString to fail.");
     }, function(error) {
diff --git a/mojo/edk/js/tests/sample_service_tests.js b/mojo/edk/js/tests/sample_service_tests.js
index 71aa48c..b9a28458 100644
--- a/mojo/edk/js/tests/sample_service_tests.js
+++ b/mojo/edk/js/tests/sample_service_tests.js
@@ -73,7 +73,7 @@
     ServiceImpl.prototype.frobinate = function(foo, baz, port) {
       checkFoo(foo);
       expect(baz).toBe(sample.Service.BazOptions.EXTRA);
-      bindings.ProxyBindings(port).close();
+      expect(port.ptr.isBound()).toBeTruthy();
       return Promise.resolve({result: 1234});
     };
 
@@ -85,9 +85,10 @@
     var serviceBinding = new bindings.Binding(
         sample.Service, new ServiceImpl(), request);
 
-    var pipe = core.createMessagePipe();
+    var port = new sample.PortPtr();
+    bindings.makeRequest(port);
     var promise = service.frobinate(
-        foo, sample.Service.BazOptions.EXTRA, pipe.handle0)
+        foo, sample.Service.BazOptions.EXTRA, port)
             .then(function(response) {
       expect(response.result).toBe(1234);
 
diff --git a/mojo/public/js/BUILD.gn b/mojo/public/js/BUILD.gn
index eda7e04d..8b23be9 100644
--- a/mojo/public/js/BUILD.gn
+++ b/mojo/public/js/BUILD.gn
@@ -19,6 +19,7 @@
     "constants.cc",
     "constants.h",
     "core.js",
+    "interface_types.js",
     "router.js",
     "support.js",
     "threading.js",
diff --git a/mojo/public/js/bindings.js b/mojo/public/js/bindings.js
index 8d8565c..4ae23116 100644
--- a/mojo/public/js/bindings.js
+++ b/mojo/public/js/bindings.js
@@ -5,35 +5,15 @@
 define("mojo/public/js/bindings", [
   "mojo/public/js/connection",
   "mojo/public/js/core",
-], function(connection, core) {
-
-  // ---------------------------------------------------------------------------
-
-  function InterfacePtrInfo(handle, version) {
-    this.handle = handle;
-    this.version = version;
-  }
-
-  InterfacePtrInfo.prototype.isValid = function() {
-    return core.isHandle(this.handle);
-  }
-
-  // ---------------------------------------------------------------------------
-
-  function InterfaceRequest(handle) {
-    this.handle = handle;
-  }
-
-  InterfaceRequest.prototype.isValid = function() {
-    return core.isHandle(this.handle);
-  }
+  "mojo/public/js/interface_types",
+], function(connection, core, types) {
 
   // ---------------------------------------------------------------------------
 
   function makeRequest(interfacePtr) {
     var pipe = core.createMessagePipe();
-    interfacePtr.ptr.bind(new InterfacePtrInfo(pipe.handle0, 0));
-    return new InterfaceRequest(pipe.handle1);
+    interfacePtr.ptr.bind(new types.InterfacePtrInfo(pipe.handle0, 0));
+    return new types.InterfaceRequest(pipe.handle1);
   }
 
   // ---------------------------------------------------------------------------
@@ -42,50 +22,77 @@
   // |ptr| field of generated interface pointer classes.
   function InterfacePtrController(interfaceType) {
     this.version = 0;
-    this.connection = null;
 
     this.interfaceType_ = interfaceType;
+    this.connection_ = null;
+    // |connection_| is lazily initialized. |handle_| is valid between bind()
+    // and the initialization of |connection_|.
+    this.handle_ = null;
   }
 
   InterfacePtrController.prototype.bind = function(interfacePtrInfo) {
     this.reset();
+
     this.version = interfacePtrInfo.version;
-    this.connection = new connection.Connection(
-      interfacePtrInfo.handle, undefined, this.interfaceType_.proxyClass);
-  }
+    this.handle_ = interfacePtrInfo.handle;
+  };
 
   InterfacePtrController.prototype.isBound = function() {
-    return this.connection !== null;
-  }
+    return this.connection_ !== null || this.handle_ !== null;
+  };
 
   // Although users could just discard the object, reset() closes the pipe
   // immediately.
   InterfacePtrController.prototype.reset = function() {
-    if (!this.isBound())
-      return;
-
     this.version = 0;
-    this.connection.close();
-    this.connection = null;
-  }
+    if (this.connection_) {
+      this.connection_.close();
+      this.connection_ = null;
+    }
+    if (this.handle_) {
+      core.close(this.handle_);
+      this.handle_ = null;
+    }
+  };
 
   InterfacePtrController.prototype.setConnectionErrorHandler
       = function(callback) {
     if (!this.isBound())
       throw new Error("Cannot set connection error handler if not bound.");
-    this.connection.router_.setErrorHandler(callback);
-  }
+
+    this.configureProxyIfNecessary_();
+    this.connection_.router_.setErrorHandler(callback);
+  };
 
   InterfacePtrController.prototype.passInterface = function() {
-    if (!this.isBound())
-      return new InterfacePtrInfo(null, 0);
+    var result;
+    if (this.connection_) {
+      result = new types.InterfacePtrInfo(
+          this.connection_.router_.connector_.handle_, this.version);
+      this.connection_.router_.connector_.handle_ = null;
+    } else {
+      // This also handles the case when this object is not bound.
+      result = new types.InterfacePtrInfo(this.handle_, this.version);
+      this.handle_ = null;
+    }
 
-    var result = new InterfacePtrInfo(
-        this.connection.router_.connector_.handle_, this.version);
-    this.connection.router_.connector_.handle_ = null;
     this.reset();
     return result;
-  }
+  };
+
+  InterfacePtrController.prototype.getProxy = function() {
+    this.configureProxyIfNecessary_();
+    return this.connection_.remote;
+  };
+
+  InterfacePtrController.prototype.configureProxyIfNecessary_ = function() {
+    if (!this.handle_)
+      return;
+
+    this.connection_ = new connection.Connection(
+        this.handle_, undefined, this.interfaceType_.proxyClass);
+    this.handle_ = null;
+  };
 
   // TODO(yzshen): Implement the following methods.
   //   InterfacePtrController.prototype.queryVersion
@@ -119,21 +126,30 @@
 
   Binding.prototype.isBound = function() {
     return this.stub_ !== null;
+  };
+
+  Binding.prototype.createInterfacePtrAndBind = function() {
+    var ptr = new this.interfaceType_.ptrClass();
+    // TODO(yzshen): Set the version of the interface pointer.
+    this.bind(makeRequest(ptr));
+    return ptr;
   }
 
   Binding.prototype.bind = function(request) {
     this.close();
-    this.stub_ = connection.bindHandleToStub(request.handle,
-                                             this.interfaceType_);
-    connection.StubBindings(this.stub_).delegate = this.impl_;
-  }
+    if (request.isValid()) {
+      this.stub_ = connection.bindHandleToStub(request.handle,
+                                               this.interfaceType_);
+      connection.StubBindings(this.stub_).delegate = this.impl_;
+    }
+  };
 
   Binding.prototype.close = function() {
     if (!this.isBound())
       return;
     connection.StubBindings(this.stub_).close();
     this.stub_ = null;
-  }
+  };
 
   Binding.prototype.setConnectionErrorHandler
       = function(callback) {
@@ -141,24 +157,24 @@
       throw new Error("Cannot set connection error handler if not bound.");
     connection.StubBindings(this.stub_).connection.router_.setErrorHandler(
         callback);
-  }
+  };
 
   Binding.prototype.unbind = function() {
     if (!this.isBound())
-      return new InterfaceRequest(null);
+      return new types.InterfaceRequest(null);
 
-    var result = new InterfaceRequest(
+    var result = new types.InterfaceRequest(
         connection.StubBindings(this.stub_).connection.router_.connector_
             .handle_);
     connection.StubBindings(this.stub_).connection.router_.connector_.handle_ =
         null;
     this.close();
     return result;
-  }
+  };
 
   var exports = {};
-  exports.InterfacePtrInfo = InterfacePtrInfo;
-  exports.InterfaceRequest = InterfaceRequest;
+  exports.InterfacePtrInfo = types.InterfacePtrInfo;
+  exports.InterfaceRequest = types.InterfaceRequest;
   exports.makeRequest = makeRequest;
   exports.InterfacePtrController = InterfacePtrController;
   exports.Binding = Binding;
diff --git a/mojo/public/js/codec.js b/mojo/public/js/codec.js
index 70df758..3ee2274 100644
--- a/mojo/public/js/codec.js
+++ b/mojo/public/js/codec.js
@@ -3,9 +3,10 @@
 // found in the LICENSE file.
 
 define("mojo/public/js/codec", [
-  "mojo/public/js/unicode",
   "mojo/public/js/buffer",
-], function(unicode, buffer) {
+  "mojo/public/js/interface_types",
+  "mojo/public/js/unicode",
+], function(buffer, types, unicode) {
 
   var kErrorUnsigned = "Passing negative value to unsigned";
   var kErrorArray = "Passing non Array for array type";
@@ -802,33 +803,54 @@
 
   NullableHandle.encode = Handle.encode;
 
-  function Interface() {
+  function Interface(cls) {
+    this.cls = cls;
   }
 
-  Interface.encodedSize = 8;
+  Interface.prototype.encodedSize = 8;
 
-  Interface.decode = function(decoder) {
-    var handle = decoder.decodeHandle();
-    // Ignore the version field for now.
-    decoder.readUint32();
-
-    return handle;
+  Interface.prototype.decode = function(decoder) {
+    var interfacePtrInfo = new types.InterfacePtrInfo(
+        decoder.decodeHandle(), decoder.readUint32());
+    var interfacePtr = new this.cls();
+    interfacePtr.ptr.bind(interfacePtrInfo);
+    return interfacePtr;
   };
 
-  Interface.encode = function(encoder, val) {
-    encoder.encodeHandle(val);
-    // Set the version field to 0 for now.
-    encoder.writeUint32(0);
+  Interface.prototype.encode = function(encoder, val) {
+    var interfacePtrInfo =
+        val ? val.ptr.passInterface() : new InterfacePtrInfo(null, 0);
+    encoder.encodeHandle(interfacePtrInfo.handle);
+    encoder.writeUint32(interfacePtrInfo.version);
   };
 
-  function NullableInterface() {
+  function NullableInterface(cls) {
+    Interface.call(this, cls);
   }
 
-  NullableInterface.encodedSize = Interface.encodedSize;
+  NullableInterface.prototype = Object.create(Interface.prototype);
 
-  NullableInterface.decode = Interface.decode;
+  function InterfaceRequest() {
+  }
 
-  NullableInterface.encode = Interface.encode;
+  InterfaceRequest.encodedSize = 4;
+
+  InterfaceRequest.decode = function(decoder) {
+    return new types.InterfaceRequest(decoder.decodeHandle());
+  };
+
+  InterfaceRequest.encode = function(encoder, val) {
+    encoder.encodeHandle(val ? val.handle : null);
+  };
+
+  function NullableInterfaceRequest() {
+  }
+
+  NullableInterfaceRequest.encodedSize = InterfaceRequest.encodedSize;
+
+  NullableInterfaceRequest.decode = InterfaceRequest.decode;
+
+  NullableInterfaceRequest.encode = InterfaceRequest.encode;
 
   function MapOf(keyClass, valueClass) {
     this.keyClass = keyClass;
@@ -888,6 +910,8 @@
   exports.NullableHandle = NullableHandle;
   exports.Interface = Interface;
   exports.NullableInterface = NullableInterface;
+  exports.InterfaceRequest = InterfaceRequest;
+  exports.NullableInterfaceRequest = NullableInterfaceRequest;
   exports.MapOf = MapOf;
   exports.NullableMapOf = NullableMapOf;
   return exports;
diff --git a/mojo/public/js/constants.cc b/mojo/public/js/constants.cc
index d29f5cb..2c9b9802 100644
--- a/mojo/public/js/constants.cc
+++ b/mojo/public/js/constants.cc
@@ -11,8 +11,9 @@
 const char kCodecModuleName[] = "mojo/public/js/codec";
 const char kConnectionModuleName[] = "mojo/public/js/connection";
 const char kConnectorModuleName[] = "mojo/public/js/connector";
-const char kUnicodeModuleName[] = "mojo/public/js/unicode";
+const char kInterfaceTypesModuleName[] = "mojo/public/js/interface_types";
 const char kRouterModuleName[] = "mojo/public/js/router";
+const char kUnicodeModuleName[] = "mojo/public/js/unicode";
 const char kValidatorModuleName[] = "mojo/public/js/validator";
 
 }  // namespace mojo
diff --git a/mojo/public/js/constants.h b/mojo/public/js/constants.h
index de75a90..c7cd9911 100644
--- a/mojo/public/js/constants.h
+++ b/mojo/public/js/constants.h
@@ -13,8 +13,9 @@
 extern const char kCodecModuleName[];
 extern const char kConnectionModuleName[];
 extern const char kConnectorModuleName[];
-extern const char kUnicodeModuleName[];
+extern const char kInterfaceTypesModuleName[];
 extern const char kRouterModuleName[];
+extern const char kUnicodeModuleName[];
 extern const char kValidatorModuleName[];
 
 }  // namespace mojo
diff --git a/mojo/public/js/interface_types.js b/mojo/public/js/interface_types.js
new file mode 100644
index 0000000..01ea2d1
--- /dev/null
+++ b/mojo/public/js/interface_types.js
@@ -0,0 +1,52 @@
+// 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.
+
+define("mojo/public/js/interface_types", [
+  "mojo/public/js/core",
+], function(core) {
+
+  // ---------------------------------------------------------------------------
+
+  function InterfacePtrInfo(handle, version) {
+    this.handle = handle;
+    this.version = version;
+  }
+
+  InterfacePtrInfo.prototype.isValid = function() {
+    return core.isHandle(this.handle);
+  };
+
+  InterfacePtrInfo.prototype.close = function() {
+    if (!this.isValid())
+      return;
+
+    core.close(this.handle);
+    this.handle = null;
+    this.version = 0;
+  };
+
+  // ---------------------------------------------------------------------------
+
+  function InterfaceRequest(handle) {
+    this.handle = handle;
+  }
+
+  InterfaceRequest.prototype.isValid = function() {
+    return core.isHandle(this.handle);
+  };
+
+  InterfaceRequest.prototype.close = function() {
+    if (!this.isValid())
+      return;
+
+    core.close(this.handle);
+    this.handle = null;
+  };
+
+  var exports = {};
+  exports.InterfacePtrInfo = InterfacePtrInfo;
+  exports.InterfaceRequest = InterfaceRequest;
+
+  return exports;
+});
diff --git a/mojo/public/js/validator.js b/mojo/public/js/validator.js
index a3f4f00..1328c33 100644
--- a/mojo/public/js/validator.js
+++ b/mojo/public/js/validator.js
@@ -42,12 +42,18 @@
   }
 
   function isInterfaceClass(cls) {
-    return cls === codec.Interface || cls === codec.NullableInterface;
+    return cls instanceof codec.Interface;
+  }
+
+  function isInterfaceRequestClass(cls) {
+    return cls === codec.InterfaceRequest ||
+        cls === codec.NullableInterfaceRequest;
   }
 
   function isNullable(type) {
     return type === codec.NullableString || type === codec.NullableHandle ||
         type === codec.NullableInterface ||
+        type === codec.NullableInterfaceRequest ||
         type instanceof codec.NullableArrayOf ||
         type instanceof codec.NullablePointerTo;
   }
@@ -119,6 +125,7 @@
 
     if (!this.claimHandle(index))
       return validationError.ILLEGAL_HANDLE;
+
     return validationError.NONE;
   };
 
@@ -126,6 +133,10 @@
     return this.validateHandle(offset, nullable);
   };
 
+  Validator.prototype.validateInterfaceRequest = function(offset, nullable) {
+    return this.validateHandle(offset, nullable);
+  };
+
   Validator.prototype.validateStructHeader = function(offset, minNumBytes) {
     if (!codec.isAligned(offset))
       return validationError.MISALIGNED_OBJECT;
@@ -372,6 +383,9 @@
     if (isInterfaceClass(elementType))
       return this.validateInterfaceElements(
           elementsOffset, numElements, nullable);
+    if (isInterfaceRequestClass(elementType))
+      return this.validateInterfaceRequestElements(
+          elementsOffset, numElements, nullable);
     if (isStringClass(elementType))
       return this.validateArrayElements(
           elementsOffset, numElements, codec.Uint8, nullable, [0], 0);
@@ -406,7 +420,7 @@
 
   Validator.prototype.validateInterfaceElements =
       function(offset, numElements, nullable) {
-    var elementSize = codec.Interface.encodedSize;
+    var elementSize = codec.Interface.prototype.encodedSize;
     for (var i = 0; i < numElements; i++) {
       var elementOffset = offset + i * elementSize;
       var err = this.validateInterface(elementOffset, nullable);
@@ -416,6 +430,18 @@
     return validationError.NONE;
   };
 
+  Validator.prototype.validateInterfaceRequestElements =
+      function(offset, numElements, nullable) {
+    var elementSize = codec.InterfaceRequest.encodedSize;
+    for (var i = 0; i < numElements; i++) {
+      var elementOffset = offset + i * elementSize;
+      var err = this.validateInterfaceRequest(elementOffset, nullable);
+      if (err != validationError.NONE)
+        return err;
+    }
+    return validationError.NONE;
+  };
+
   // The elementClass parameter is the element type of the element arrays.
   Validator.prototype.validateArrayElements =
       function(offset, numElements, elementClass, nullable,
diff --git a/mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl b/mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl
index c479a8b..9441589 100644
--- a/mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl
+++ b/mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl
@@ -14,7 +14,7 @@
 {%- for method in interface.methods %}
   {{interface.name}}Ptr.prototype.{{method.name|stylize_method}} = function() {
     return {{interface.name}}Proxy.prototype.{{method.name|stylize_method}}
-        .apply(this.ptr.connection.remote, arguments);
+        .apply(this.ptr.getProxy(), arguments);
   };
 
   {{interface.name}}Proxy.prototype.{{method.name|stylize_method}} = function(
@@ -24,7 +24,7 @@
 ) {
     var params = new {{interface.name}}_{{method.name}}_Params();
 {%- for parameter in method.parameters %}
-    params.{{parameter.name}} = {{parameter|js_proxy_method_parameter_value}};
+    params.{{parameter.name}} = {{parameter.name}};
 {%- endfor %}
 
 {%- if method.response_parameters == None %}
@@ -64,7 +64,7 @@
 {%-   set js_method_name = method.name|stylize_method %}
 {%-   set delegate_expr =  "bindings.StubBindings(this).delegate" %}
   {{interface.name}}Stub.prototype.{{js_method_name}} = function({{method.parameters|map(attribute='name')|join(', ')}}) {
-    return {{delegate_expr}} && {{delegate_expr}}.{{js_method_name}} && {{delegate_expr}}.{{js_method_name}}({{method.parameters|map('js_stub_method_parameter_value')|join(', ')}});
+    return {{delegate_expr}} && {{delegate_expr}}.{{js_method_name}} && {{delegate_expr}}.{{js_method_name}}({{method.parameters|map(attribute='name')|join(', ')}});
   }
 {%- endfor %}
 
@@ -171,6 +171,7 @@
 
   var {{interface.name}} = {
     name: '{{namespace|replace(".","::")}}::{{interface.name}}',
+    ptrClass: {{interface.name}}Ptr,
     proxyClass: {{interface.name}}Proxy,
     stubClass: {{interface.name}}Stub,
     validateRequest: validate{{interface.name}}Request,
diff --git a/mojo/public/tools/bindings/generators/js_templates/validation_macros.tmpl b/mojo/public/tools/bindings/generators/js_templates/validation_macros.tmpl
index 3d0be6e..d4e15a7 100644
--- a/mojo/public/tools/bindings/generators/js_templates/validation_macros.tmpl
+++ b/mojo/public/tools/bindings/generators/js_templates/validation_macros.tmpl
@@ -6,7 +6,7 @@
 {%- macro _validate_field(field, offset, name) %}
 {%-   if field|is_string_pointer_field %}
 // validate {{name}}
-err = messageValidator.validateStringPointer({{offset}}, {{field|validate_string_params}})
+err = messageValidator.validateStringPointer({{offset}}, {{field|validate_nullable_params}})
 {{_check_err()}}
 {%-   elif field|is_array_pointer_field %}
 // validate {{name}}
@@ -22,11 +22,15 @@
 {{_check_err()}}
 {%-   elif field|is_interface_field %}
 // validate {{name}}
-err = messageValidator.validateInterface({{offset}}, {{field|validate_interface_params}});
+err = messageValidator.validateInterface({{offset}}, {{field|validate_nullable_params}});
 {{_check_err()}}
-{%-   elif field|is_handle_field or field|is_interface_request_field %}
+{%-   elif field|is_interface_request_field %}
 // validate {{name}}
-err = messageValidator.validateHandle({{offset}}, {{field|validate_handle_params}})
+err = messageValidator.validateInterfaceRequest({{offset}}, {{field|validate_nullable_params}})
+{{_check_err()}}
+{%-   elif field|is_handle_field %}
+// validate {{name}}
+err = messageValidator.validateHandle({{offset}}, {{field|validate_nullable_params}})
 {{_check_err()}}
 {%-   elif field|is_enum_field %}
 // validate {{name}}
diff --git a/mojo/public/tools/bindings/generators/mojom_js_generator.py b/mojo/public/tools/bindings/generators/mojom_js_generator.py
index e57f330..0d774a5 100644
--- a/mojo/public/tools/bindings/generators/mojom_js_generator.py
+++ b/mojo/public/tools/bindings/generators/mojom_js_generator.py
@@ -62,9 +62,10 @@
     return "null"
   if mojom.IsMapKind(field.kind):
     return "null"
-  if mojom.IsInterfaceKind(field.kind) or \
-     mojom.IsInterfaceRequestKind(field.kind):
-    return _kind_to_javascript_default_value[mojom.MSGPIPE]
+  if mojom.IsInterfaceKind(field.kind):
+    return "new %sPtr()" % JavaScriptType(field.kind)
+  if mojom.IsInterfaceRequestKind(field.kind):
+    return "new bindings.InterfaceRequest()"
   if mojom.IsAssociatedKind(field.kind):
     return "null"
   if mojom.IsEnumKind(field.kind):
@@ -124,10 +125,13 @@
     element_type = ElementCodecType(kind.kind)
     return "new codec.%s(%s%s)" % (array_type, element_type, array_length)
   if mojom.IsInterfaceKind(kind):
-    return "codec.%s" % ("NullableInterface" if mojom.IsNullableKind(kind)
-        else "Interface")
+    return "new codec.%s(%sPtr)" % (
+        "NullableInterface" if mojom.IsNullableKind(kind) else "Interface",
+        JavaScriptType(kind))
   if mojom.IsInterfaceRequestKind(kind):
-    return CodecType(mojom.MSGPIPE)
+    return "codec.%s" % (
+        "NullableInterfaceRequest" if mojom.IsNullableKind(kind)
+                                   else "InterfaceRequest")
   if mojom.IsAssociatedInterfaceKind(kind):
     return "codec.AssociatedInterfaceNotSupported"
   if mojom.IsAssociatedInterfaceRequestKind(kind):
@@ -148,7 +152,7 @@
 
 def JavaScriptDecodeSnippet(kind):
   if (kind in mojom.PRIMITIVES or mojom.IsUnionKind(kind) or
-      mojom.IsInterfaceKind(kind) or mojom.IsAssociatedKind(kind)):
+      mojom.IsAnyInterfaceKind(kind)):
     return "decodeStruct(%s)" % CodecType(kind)
   if mojom.IsStructKind(kind):
     return "decodeStructPointer(%s)" % JavaScriptType(kind)
@@ -161,8 +165,6 @@
     return "decodeArrayPointer(%s)" % CodecType(kind.kind)
   if mojom.IsUnionKind(kind):
     return "decodeUnion(%s)" % CodecType(kind)
-  if mojom.IsInterfaceRequestKind(kind):
-    return JavaScriptDecodeSnippet(mojom.MSGPIPE)
   if mojom.IsEnumKind(kind):
     return JavaScriptDecodeSnippet(mojom.INT32)
   raise Exception("No decode snippet for %s" % kind)
@@ -170,7 +172,7 @@
 
 def JavaScriptEncodeSnippet(kind):
   if (kind in mojom.PRIMITIVES or mojom.IsUnionKind(kind) or
-      mojom.IsInterfaceKind(kind) or mojom.IsAssociatedKind(kind)):
+      mojom.IsAnyInterfaceKind(kind)):
     return "encodeStruct(%s, " % CodecType(kind)
   if mojom.IsUnionKind(kind):
     return "encodeStruct(%s, " % JavaScriptType(kind)
@@ -183,8 +185,6 @@
     return "encodeArrayPointer(codec.PackedBool, ";
   if mojom.IsArrayKind(kind):
     return "encodeArrayPointer(%s, " % CodecType(kind.kind)
-  if mojom.IsInterfaceRequestKind(kind):
-    return JavaScriptEncodeSnippet(mojom.MSGPIPE)
   if mojom.IsEnumKind(kind):
     return JavaScriptEncodeSnippet(mojom.INT32)
   raise Exception("No encode snippet for %s" % kind)
@@ -258,42 +258,6 @@
       (nullable, keys_type, values_type, values_nullable)
 
 
-def JavaScriptValidateStringParams(field):
-  nullable = JavaScriptNullableParam(field)
-  return "%s" % (nullable)
-
-
-def JavaScriptValidateHandleParams(field):
-  nullable = JavaScriptNullableParam(field)
-  return "%s" % (nullable)
-
-def JavaScriptValidateInterfaceParams(field):
-  return JavaScriptValidateHandleParams(field)
-
-def JavaScriptProxyMethodParameterValue(parameter):
-  name = parameter.name;
-  if (mojom.IsInterfaceKind(parameter.kind)):
-   type = JavaScriptType(parameter.kind)
-   return "core.isHandle(%s) ? %s : connection.bindImpl" \
-       "(%s, %s)" % (name, name, name, type)
-  if (mojom.IsInterfaceRequestKind(parameter.kind)):
-   type = JavaScriptType(parameter.kind.kind)
-   return "core.isHandle(%s) ? %s : connection.bindProxy" \
-       "(%s, %s)" % (name, name, name, type)
-  return name;
-
-
-def JavaScriptStubMethodParameterValue(parameter):
-  name = parameter.name;
-  if (mojom.IsInterfaceKind(parameter.kind)):
-   type = JavaScriptType(parameter.kind)
-   return "connection.bindHandleToProxy(%s, %s)" % (name, type)
-  if (mojom.IsInterfaceRequestKind(parameter.kind)):
-   type = JavaScriptType(parameter.kind.kind)
-   return "connection.bindHandleToStub(%s, %s)" % (name, type)
-  return name;
-
-
 def TranslateConstants(token):
   if isinstance(token, (mojom.EnumValue, mojom.NamedValue)):
     # Both variable and enum constants are constructed like:
@@ -384,8 +348,6 @@
     "is_string_pointer_field": IsStringPointerField,
     "is_struct_pointer_field": IsStructPointerField,
     "is_union_field": IsUnionField,
-    "js_proxy_method_parameter_value": JavaScriptProxyMethodParameterValue,
-    "js_stub_method_parameter_value": JavaScriptStubMethodParameterValue,
     "js_type": JavaScriptType,
     "payload_size": JavaScriptPayloadSize,
     "stylize_method": generator.StudlyCapsToCamel,
@@ -393,10 +355,8 @@
     "union_encode_snippet": JavaScriptUnionEncodeSnippet,
     "validate_array_params": JavaScriptValidateArrayParams,
     "validate_enum_params": JavaScriptValidateEnumParams,
-    "validate_handle_params": JavaScriptValidateHandleParams,
-    "validate_interface_params": JavaScriptValidateInterfaceParams,
     "validate_map_params": JavaScriptValidateMapParams,
-    "validate_string_params": JavaScriptValidateStringParams,
+    "validate_nullable_params": JavaScriptNullableParam,
     "validate_struct_params": JavaScriptValidateStructParams,
     "validate_union_params": JavaScriptValidateUnionParams,
   }
diff --git a/net/cert/cert_verify_proc_blacklist.inc b/net/cert/cert_verify_proc_blacklist.inc
index b2bb554..3ca92f14 100644
--- a/net/cert/cert_verify_proc_blacklist.inc
+++ b/net/cert/cert_verify_proc_blacklist.inc
@@ -5,7 +5,7 @@
 // The certificate(s) that were misissued, and which represent these SPKIs,
 // are stored within net/data/ssl/blacklist. Further details about the
 // rationale is documented in net/data/ssl/blacklist/README.md
-static const size_t kNumBlacklistedSPKIs = 34u;
+static const size_t kNumBlacklistedSPKIs = 36u;
 static const uint8_t
     kBlacklistedSPKIs[kNumBlacklistedSPKIs][crypto::kSHA256Length] = {
         // ead610e6e90b439f2ecb51628b0932620f6ef340bd843fca38d3181b8f4ba197.pem
@@ -24,6 +24,10 @@
         {0x1a, 0xf5, 0x6c, 0x98, 0xff, 0x04, 0x3e, 0xf9, 0x2b, 0xeb, 0xff,
          0x54, 0xce, 0xbb, 0x4d, 0xd6, 0x7a, 0x25, 0xba, 0x95, 0x6c, 0x81,
          0x7f, 0x3e, 0x6d, 0xd3, 0xc1, 0xe5, 0x2e, 0xb5, 0x84, 0xc1},
+        // e28393773da845a679f2080cc7fb44a3b7a1c3792cb7eb7729fdcb6a8d99aea7.pem
+        {0x1f, 0x42, 0x24, 0xce, 0xc8, 0x4f, 0xc9, 0x9c, 0xed, 0x88, 0x1f,
+         0xf6, 0xfc, 0xfd, 0x3e, 0x21, 0xf8, 0xc5, 0x19, 0xc5, 0x47, 0xaa,
+         0x6a, 0x5d, 0xd3, 0xde, 0x24, 0x73, 0x02, 0xce, 0x50, 0xd1},
         // 2c998e761160c3b06d82faa9fdc7545d9bda9eb60310f992aa510a6280b74245.pem
         {0x2c, 0x99, 0x8e, 0x76, 0x11, 0x60, 0xc3, 0xb0, 0x6d, 0x82, 0xfa,
          0xa9, 0xfd, 0xc7, 0x54, 0x5d, 0x9b, 0xda, 0x9e, 0xb6, 0x03, 0x10,
@@ -78,6 +82,10 @@
         {0x9b, 0x8a, 0x93, 0xde, 0xcc, 0xcf, 0xba, 0xfc, 0xf4, 0xd0, 0x4d,
          0x34, 0x42, 0x12, 0x8f, 0xb3, 0x52, 0x18, 0xcf, 0xe4, 0x37, 0xa3,
          0xd8, 0xd0, 0x32, 0x8c, 0x99, 0xf8, 0x90, 0x89, 0xe4, 0x50},
+        // 1c01c6f4dbb2fefc22558b2bca32563f49844acfc32b7be4b0ff599f9e8c7af7.pem
+        {0x9d, 0xd5, 0x5f, 0xc5, 0x73, 0xf5, 0x46, 0xcb, 0x6a, 0x38, 0x31,
+         0xd1, 0x11, 0x2d, 0x87, 0x10, 0xa6, 0xf4, 0xf8, 0x2d, 0xc8, 0x7f,
+         0x5f, 0xae, 0x9d, 0x3a, 0x1a, 0x02, 0x8d, 0xd3, 0x6e, 0x4b},
         // 0d136e439f0ab6e97f3a02a540da9f0641aa554e1d66ea51ae2920d51b2f7217.pem
         // 4fee0163686ecbd65db968e7494f55d84b25486d438e9de558d629d28cd4d176.pem
         // 8a1bd21661c60015065212cc98b1abb50dfd14c872a208e66bae890f25c448af.pem
diff --git a/net/cert/cert_verify_proc_unittest.cc b/net/cert/cert_verify_proc_unittest.cc
index 96ce38c..186854c 100644
--- a/net/cert/cert_verify_proc_unittest.cc
+++ b/net/cert/cert_verify_proc_unittest.cc
@@ -1806,7 +1806,8 @@
 // Disabled on NSS - NSS caches chains/signatures in such a way that cannot
 // be cleared until NSS is cleanly shutdown, which is not presently supported
 // in Chromium.
-#if defined(USE_NSS_CERTS) || defined(OS_IOS)
+// OSX 10.12+ stops building the chain at the first weak digest.
+#if defined(USE_NSS_CERTS) || defined(OS_IOS) || defined(OS_MACOSX)
 #define MAYBE_VerifyEndEntity DISABLED_VerifyEndEntity
 #else
 #define MAYBE_VerifyEndEntity VerifyEndEntity
@@ -1854,7 +1855,8 @@
 };
 // Disabled on NSS - libpkix does not return constructed chains on error,
 // preventing us from detecting/inspecting the verified chain.
-#if defined(USE_NSS_CERTS) || defined(OS_IOS)
+// OSX 10.12+ stops building the chain at the first weak digest.
+#if defined(USE_NSS_CERTS) || defined(OS_IOS) || defined(OS_MACOSX)
 #define MAYBE_VerifyIncompleteEndEntity DISABLED_VerifyIncompleteEndEntity
 #else
 #define MAYBE_VerifyIncompleteEndEntity VerifyIncompleteEndEntity
@@ -1879,7 +1881,8 @@
 };
 // NSS does not support MD4 and does not enable MD2 by default, making all
 // permutations invalid.
-#if defined(USE_NSS_CERTS) || defined(OS_IOS)
+// OSX 10.12+ stops building the chain at the first weak digest.
+#if defined(USE_NSS_CERTS) || defined(OS_IOS) || defined(OS_MACOSX)
 #define MAYBE_VerifyMixed DISABLED_VerifyMixed
 #else
 #define MAYBE_VerifyMixed VerifyMixed
diff --git a/net/cert/cert_verify_proc_whitelist.cc b/net/cert/cert_verify_proc_whitelist.cc
index 5c53a77a..53489ff 100644
--- a/net/cert/cert_verify_proc_whitelist.cc
+++ b/net/cert/cert_verify_proc_whitelist.cc
@@ -46,1604 +46,7 @@
       0x21, 0x9f, 0xe0, 0xe9, 0xe3, 0xa3, 0x82, 0xa1,
       0xb3, 0xcb, 0x66, 0xc9, 0x39, 0x55, 0xde, 0x75 },
 };
-
-// SHA-256 hashes of the leaf certificates whitelisted as issued by CNNIC's
-// DV root.
-const uint8_t kCNNICDVWhitelist[][crypto::kSHA256Length] = {
-    { 0x00, 0xc5, 0x9f, 0x5e, 0xf3, 0xb4, 0x6d, 0xbc,
-      0xa0, 0xa8, 0xbb, 0xa5, 0x0a, 0x72, 0xd4, 0xe1,
-      0x83, 0x9a, 0x94, 0xfb, 0x1a, 0x58, 0x5a, 0xd7,
-      0x2a, 0x7a, 0xac, 0x3c, 0x72, 0x56, 0x1f, 0xc0 },
-    { 0x02, 0x01, 0x4e, 0x80, 0xf5, 0xc4, 0xf3, 0x8b,
-      0xa9, 0xd9, 0x04, 0x79, 0x1a, 0x63, 0xf6, 0x4d,
-      0x05, 0xf9, 0xe2, 0x03, 0xa1, 0xf1, 0x2b, 0x06,
-      0xd6, 0x55, 0x94, 0x01, 0x41, 0x0e, 0x73, 0x36 },
-    { 0x02, 0x35, 0x38, 0xe2, 0x48, 0x15, 0x28, 0x75,
-      0x29, 0x2f, 0x2c, 0x83, 0x9a, 0xb3, 0x2b, 0xc7,
-      0x35, 0x1e, 0x2b, 0x29, 0x99, 0x1d, 0x66, 0xae,
-      0xa6, 0x16, 0xcb, 0x0b, 0x26, 0xa5, 0xe3, 0x75 },
-    { 0x02, 0xec, 0x35, 0xf5, 0x83, 0x4c, 0xd2, 0xc3,
-      0x43, 0x33, 0x39, 0x9a, 0xea, 0x6b, 0xda, 0x84,
-      0x68, 0xab, 0x8d, 0x74, 0xef, 0x6c, 0xa5, 0x2d,
-      0x33, 0x7a, 0x30, 0x69, 0x4c, 0x3f, 0x95, 0xa4 },
-    { 0x03, 0xe0, 0x6e, 0x0b, 0x7a, 0x2c, 0xba, 0xe4,
-      0xb6, 0x8b, 0xce, 0x5f, 0x83, 0xe7, 0xa9, 0x31,
-      0x6e, 0xd7, 0x82, 0x3e, 0x8d, 0x94, 0x85, 0x38,
-      0xf1, 0x94, 0x3f, 0xa4, 0x27, 0xd7, 0x91, 0x0e },
-    { 0x04, 0x0f, 0x53, 0x7a, 0x51, 0x95, 0x95, 0xcc,
-      0xff, 0xde, 0x35, 0xe0, 0xd1, 0x28, 0xb7, 0x99,
-      0x92, 0x2b, 0xa9, 0x37, 0xa2, 0xe8, 0x65, 0x84,
-      0x36, 0x62, 0xf1, 0xf4, 0x50, 0x02, 0xb8, 0x2d },
-    { 0x07, 0x19, 0x4f, 0x47, 0xf4, 0xce, 0xd0, 0x96,
-      0xd1, 0x06, 0x8d, 0x34, 0x49, 0x3b, 0x67, 0x37,
-      0x14, 0x45, 0x16, 0x93, 0xa6, 0xa2, 0x71, 0x2f,
-      0x70, 0x8f, 0x59, 0x36, 0x12, 0x11, 0xc6, 0x21 },
-    { 0x07, 0x8f, 0xee, 0x58, 0x8a, 0x2c, 0x55, 0xc8,
-      0xe2, 0xc1, 0x78, 0x71, 0xaa, 0xb6, 0xe4, 0x00,
-      0xb3, 0xfd, 0xbc, 0xdc, 0xf3, 0x91, 0x46, 0xa0,
-      0x89, 0x37, 0xf9, 0xac, 0x06, 0xa1, 0xb8, 0xbd },
-    { 0x08, 0x21, 0x0a, 0xc3, 0xa2, 0x95, 0x56, 0xf6,
-      0x8d, 0x33, 0xb4, 0x40, 0x87, 0x9c, 0x54, 0x63,
-      0x64, 0x04, 0xe9, 0x7c, 0x4d, 0x9f, 0x97, 0x82,
-      0x23, 0xd2, 0x42, 0xab, 0xe5, 0x38, 0x5e, 0x4e },
-    { 0x08, 0xc2, 0xd3, 0x17, 0xa8, 0x4a, 0x3c, 0xbe,
-      0x38, 0xde, 0x64, 0xa2, 0x4d, 0xd4, 0x27, 0x91,
-      0x09, 0xe2, 0xbc, 0x02, 0x2b, 0x93, 0xb1, 0x05,
-      0xa8, 0x94, 0xa5, 0x1a, 0xdc, 0x3e, 0xe5, 0xcc },
-    { 0x09, 0x9f, 0x3e, 0x71, 0xb5, 0x00, 0xd1, 0x5b,
-      0x03, 0x7b, 0x93, 0xaa, 0x5f, 0xb4, 0x16, 0x19,
-      0x0a, 0xd1, 0xdf, 0x86, 0x73, 0xab, 0x31, 0xa8,
-      0xf6, 0xd9, 0x7f, 0x59, 0x5e, 0x8e, 0x16, 0xe9 },
-    { 0x09, 0xeb, 0xdd, 0x1b, 0x7f, 0xfa, 0x4e, 0xd7,
-      0x4b, 0xeb, 0xae, 0x96, 0xba, 0x10, 0x65, 0xdc,
-      0x7d, 0xa1, 0xc5, 0xd3, 0x18, 0x3c, 0xc5, 0x94,
-      0x19, 0xe9, 0x78, 0x36, 0xaf, 0x7f, 0x6d, 0x70 },
-    { 0x0a, 0x01, 0x88, 0x81, 0x2c, 0x9d, 0xe8, 0x8a,
-      0x2f, 0x0a, 0x5c, 0x4c, 0x57, 0xe6, 0xf9, 0xa8,
-      0x15, 0x69, 0xe9, 0xc7, 0x09, 0xc0, 0x95, 0x40,
-      0x80, 0xe5, 0xe4, 0xe6, 0x62, 0x85, 0x6d, 0xf8 },
-    { 0x0a, 0x42, 0x19, 0x7e, 0x48, 0x70, 0xb2, 0x34,
-      0x20, 0xf5, 0x51, 0x9f, 0xb8, 0x39, 0xb6, 0xcc,
-      0x83, 0x03, 0x52, 0x9a, 0xa9, 0x06, 0x9a, 0xd1,
-      0xa0, 0x90, 0x86, 0xcf, 0x6c, 0xba, 0x07, 0xc2 },
-    { 0x0b, 0x03, 0xe1, 0x27, 0xc2, 0xe3, 0x3e, 0xad,
-      0xbc, 0xb0, 0x99, 0x80, 0x46, 0xcc, 0x9b, 0xa7,
-      0x33, 0x46, 0x3e, 0x0c, 0xa6, 0x43, 0x52, 0x27,
-      0x81, 0xb0, 0x3d, 0x81, 0x53, 0x97, 0xeb, 0x4f },
-    { 0x0b, 0x1e, 0x1e, 0x73, 0x43, 0xa0, 0xe9, 0x1c,
-      0x2a, 0x27, 0xdd, 0x2a, 0x4d, 0x7e, 0x6b, 0xf1,
-      0xe8, 0x04, 0x4b, 0x58, 0xce, 0x1a, 0xe8, 0x1e,
-      0x27, 0xd8, 0x14, 0xfd, 0x2d, 0xc0, 0x18, 0x93 },
-    { 0x0b, 0x48, 0xd5, 0x5c, 0xac, 0x84, 0xfd, 0xee,
-      0x15, 0xd8, 0x1a, 0xff, 0x99, 0x07, 0xbb, 0x9a,
-      0x57, 0x11, 0xa9, 0x5c, 0xe2, 0x3a, 0x8d, 0x4d,
-      0x5e, 0x88, 0x62, 0xbf, 0x15, 0xa7, 0x6a, 0x75 },
-    { 0x0b, 0xfe, 0xa1, 0x38, 0x31, 0x67, 0x3e, 0xc9,
-      0x69, 0xd0, 0x5f, 0xd8, 0x67, 0xb6, 0x69, 0xf2,
-      0x71, 0x24, 0xaf, 0xeb, 0x7c, 0x60, 0x8c, 0xfe,
-      0x54, 0xcf, 0x46, 0x33, 0x06, 0xcc, 0x99, 0x2e },
-    { 0x0c, 0xb9, 0x31, 0x93, 0xf1, 0x65, 0x26, 0xe1,
-      0xd1, 0x65, 0x52, 0x11, 0x7b, 0xa2, 0x1a, 0xac,
-      0xb9, 0xf1, 0xd7, 0xa8, 0x93, 0x56, 0xa3, 0x5d,
-      0xe4, 0xf6, 0x65, 0xe9, 0x39, 0x90, 0x79, 0x38 },
-    { 0x0d, 0x16, 0x1b, 0xb9, 0xca, 0x0d, 0x20, 0xe4,
-      0x67, 0x35, 0x89, 0x67, 0x22, 0x78, 0xb0, 0xa3,
-      0xc5, 0xe2, 0x69, 0x30, 0xa4, 0xdc, 0x3a, 0x82,
-      0x16, 0x85, 0x43, 0x24, 0x27, 0xc7, 0x31, 0x5a },
-    { 0x0d, 0x71, 0xc8, 0xca, 0x16, 0x56, 0x59, 0xef,
-      0xaf, 0x69, 0x65, 0x29, 0x28, 0x9a, 0xae, 0x25,
-      0xd9, 0xc4, 0x2a, 0x1b, 0xbb, 0x03, 0x5a, 0x2b,
-      0x8c, 0x61, 0x14, 0x7e, 0x1b, 0x8b, 0x90, 0x52 },
-    { 0x0e, 0xfd, 0x68, 0x73, 0xd6, 0x0e, 0x77, 0x96,
-      0x2d, 0xf6, 0x00, 0x16, 0xdc, 0x3b, 0xaf, 0x9c,
-      0xa7, 0x1e, 0x7d, 0x86, 0x19, 0xe7, 0xeb, 0xaa,
-      0x3a, 0xf2, 0xdc, 0xb5, 0xba, 0x24, 0xde, 0xc2 },
-    { 0x0e, 0xff, 0x3c, 0xff, 0xda, 0x4a, 0x3e, 0x87,
-      0x23, 0x4a, 0x86, 0xc7, 0x0d, 0x49, 0x8c, 0x62,
-      0x60, 0x7f, 0x37, 0x44, 0xea, 0x71, 0xf1, 0x83,
-      0x1d, 0xcf, 0xca, 0xf3, 0xaf, 0x15, 0x56, 0x9c },
-    { 0x10, 0x83, 0x6d, 0xa0, 0xcd, 0x6a, 0xc0, 0x95,
-      0xdd, 0x7a, 0xc3, 0x4d, 0x99, 0x01, 0x90, 0x9a,
-      0x8e, 0xf8, 0x4d, 0x6e, 0xe0, 0x5b, 0x83, 0x43,
-      0x03, 0xd4, 0x7f, 0xc0, 0xa5, 0xf9, 0x14, 0xfa },
-    { 0x11, 0xa4, 0x02, 0x7b, 0x45, 0xfc, 0x9a, 0x6f,
-      0x40, 0x21, 0x25, 0xc3, 0xca, 0x22, 0x68, 0xe0,
-      0x15, 0xa3, 0x1b, 0xa4, 0xfd, 0xb0, 0x05, 0x9d,
-      0x66, 0x6b, 0x73, 0xc8, 0x51, 0xd5, 0x35, 0x92 },
-    { 0x12, 0x6b, 0x1b, 0xa6, 0x38, 0xc7, 0xe6, 0x99,
-      0xbc, 0xbc, 0x54, 0xf5, 0x79, 0xac, 0xd3, 0x9f,
-      0xe6, 0x1d, 0x08, 0x22, 0x5f, 0xe5, 0xb1, 0xf9,
-      0x01, 0x88, 0xb2, 0x3f, 0xd8, 0x43, 0x3e, 0x8e },
-    { 0x13, 0x5d, 0x3e, 0xda, 0x6e, 0x55, 0x9b, 0xf5,
-      0xee, 0x23, 0x0a, 0xa5, 0xba, 0x59, 0xbb, 0x6a,
-      0x2a, 0x0f, 0x07, 0x82, 0x2f, 0xed, 0x38, 0x44,
-      0x7e, 0x6a, 0xbc, 0x5c, 0x23, 0xaa, 0xd0, 0x27 },
-    { 0x13, 0x6a, 0x40, 0x09, 0x81, 0xb1, 0xa3, 0xe0,
-      0x5f, 0xdc, 0xac, 0x20, 0xa2, 0x36, 0xf8, 0x6e,
-      0x94, 0xe5, 0xee, 0x58, 0x59, 0xd8, 0xfd, 0x45,
-      0xe9, 0xe9, 0xc5, 0xa6, 0xc5, 0xc0, 0xa4, 0x13 },
-    { 0x14, 0x21, 0x28, 0xa6, 0x65, 0x1c, 0xdc, 0x18,
-      0x70, 0xc2, 0x67, 0x5e, 0xc0, 0xb0, 0xef, 0x32,
-      0xb5, 0xd4, 0xc1, 0x55, 0x35, 0x8e, 0x7e, 0xd9,
-      0x5a, 0x98, 0xe8, 0x3b, 0x1a, 0xd8, 0xbe, 0x4d },
-    { 0x14, 0x47, 0x25, 0xa6, 0x79, 0x1c, 0x60, 0x0c,
-      0x4c, 0x2c, 0xf3, 0x94, 0x3f, 0x3e, 0xcf, 0x40,
-      0xd6, 0x31, 0xd7, 0x60, 0xe4, 0x51, 0xef, 0x28,
-      0x29, 0xaf, 0xfb, 0xee, 0x74, 0x80, 0xad, 0x17 },
-    { 0x15, 0x27, 0x2a, 0xbc, 0x1f, 0x0c, 0x4d, 0x1d,
-      0x1a, 0x92, 0x08, 0x73, 0x55, 0xa1, 0xe0, 0x42,
-      0x6c, 0x2b, 0xb5, 0xb4, 0x37, 0x30, 0x00, 0xb8,
-      0x2c, 0x2c, 0xca, 0xb7, 0xfa, 0xd6, 0xfa, 0x20 },
-    { 0x15, 0x48, 0x1f, 0xde, 0x4e, 0x3f, 0x72, 0x49,
-      0x66, 0x87, 0xdf, 0x57, 0x5f, 0xb5, 0xb1, 0x27,
-      0xbd, 0x6d, 0xeb, 0x66, 0x1d, 0xd9, 0x07, 0x71,
-      0x8b, 0xa0, 0x65, 0xc7, 0xda, 0x66, 0x76, 0xd1 },
-    { 0x15, 0x5a, 0x88, 0x39, 0x60, 0x8b, 0x77, 0x25,
-      0x34, 0x6a, 0x72, 0x40, 0xe4, 0xe2, 0x50, 0x3a,
-      0xcc, 0x7b, 0x8b, 0xef, 0x0b, 0x1b, 0xe6, 0x15,
-      0xb9, 0x02, 0x4a, 0x88, 0xe6, 0x52, 0x11, 0xf9 },
-    { 0x15, 0x5d, 0x88, 0x6e, 0x99, 0x1d, 0x40, 0x0a,
-      0xbf, 0x2f, 0x83, 0xc2, 0x80, 0xd1, 0x24, 0x6d,
-      0xce, 0x02, 0xa6, 0x28, 0x31, 0x26, 0xc6, 0x17,
-      0xe4, 0x17, 0xd2, 0xb7, 0xea, 0xc1, 0x19, 0x24 },
-    { 0x17, 0x3d, 0xe2, 0x60, 0xe2, 0x2d, 0x76, 0x9d,
-      0x2d, 0x54, 0x99, 0xc8, 0x22, 0x0d, 0x86, 0xed,
-      0xe3, 0x48, 0xda, 0x1e, 0x57, 0xc1, 0xe7, 0xc8,
-      0x15, 0x07, 0xfb, 0x3e, 0x6b, 0xd7, 0x3b, 0x7f },
-    { 0x18, 0x1e, 0xbb, 0x29, 0x8d, 0x20, 0x68, 0x5c,
-      0x48, 0xf7, 0x53, 0x89, 0x80, 0xc5, 0x63, 0xc8,
-      0xf7, 0x48, 0x95, 0x4c, 0xf2, 0x64, 0x41, 0x9a,
-      0x72, 0xfc, 0xc6, 0x34, 0x0a, 0x10, 0x23, 0x80 },
-    { 0x19, 0xff, 0xe6, 0xc6, 0x7a, 0x35, 0x86, 0xfc,
-      0x48, 0x6c, 0xe2, 0x07, 0xfa, 0x2a, 0xf6, 0x62,
-      0xf5, 0x50, 0xfc, 0x51, 0x2f, 0xdd, 0x78, 0x17,
-      0xe3, 0x86, 0xc9, 0x4a, 0x7b, 0xde, 0x37, 0xa9 },
-    { 0x1a, 0x9e, 0xc6, 0x8c, 0xed, 0xb6, 0xbd, 0x94,
-      0x0c, 0x95, 0x34, 0xe6, 0x84, 0xbb, 0x04, 0x9f,
-      0xf1, 0xe2, 0x3b, 0x66, 0xa1, 0x33, 0x01, 0x2f,
-      0xc3, 0x99, 0xeb, 0x4f, 0xb5, 0xd3, 0xaa, 0x35 },
-    { 0x1b, 0x7b, 0xf8, 0xd9, 0xe8, 0x29, 0x3c, 0x53,
-      0xdd, 0x59, 0xec, 0x97, 0xfe, 0x16, 0xf0, 0xea,
-      0xb4, 0x68, 0x5b, 0x95, 0xce, 0x14, 0xd2, 0x62,
-      0x3e, 0x70, 0x94, 0x2c, 0xff, 0x25, 0xe7, 0x30 },
-    { 0x1b, 0xd7, 0xb3, 0x62, 0xbc, 0x14, 0x66, 0xfa,
-      0xc0, 0x5e, 0xc5, 0x9e, 0x12, 0xe8, 0x1b, 0xe7,
-      0x35, 0x38, 0xc4, 0x97, 0x28, 0xf5, 0xad, 0xba,
-      0x2d, 0x81, 0xfc, 0xdb, 0xc4, 0x65, 0x7c, 0x1b },
-    { 0x1b, 0xec, 0xfe, 0x78, 0xce, 0x5e, 0x77, 0xa9,
-      0x77, 0xbb, 0x5f, 0xe3, 0x49, 0x91, 0x06, 0xc6,
-      0x4c, 0xf2, 0xb0, 0x76, 0x16, 0x59, 0x49, 0x04,
-      0x11, 0x17, 0xcd, 0x8a, 0xbc, 0xd9, 0x05, 0xd4 },
-    { 0x1b, 0xf4, 0x8a, 0x83, 0x3c, 0xe4, 0x05, 0x64,
-      0x8c, 0xc0, 0xbd, 0xd3, 0xb5, 0xb8, 0xc1, 0x8e,
-      0xb5, 0x13, 0x15, 0x34, 0x29, 0x3a, 0xb2, 0x63,
-      0x44, 0xb5, 0x00, 0x76, 0x48, 0x11, 0x41, 0xed },
-    { 0x1c, 0x04, 0x82, 0x0f, 0x7b, 0x4a, 0x2f, 0x1e,
-      0x38, 0x5d, 0xe1, 0xde, 0x16, 0xb2, 0x22, 0x6e,
-      0x88, 0x3d, 0x9c, 0x34, 0x66, 0x3e, 0x1b, 0x64,
-      0xe8, 0x5b, 0x98, 0x0e, 0xaf, 0xf0, 0xb9, 0xd3 },
-    { 0x1d, 0x9e, 0xc0, 0x06, 0xa5, 0x26, 0xfa, 0xb5,
-      0xce, 0x2e, 0x71, 0xfd, 0xfc, 0x07, 0xc0, 0x11,
-      0xf7, 0x65, 0x7b, 0xf8, 0x5f, 0x5d, 0x03, 0x52,
-      0xb8, 0xcb, 0x21, 0x8d, 0x4f, 0xcb, 0xc4, 0x43 },
-    { 0x1e, 0x78, 0xf8, 0x08, 0x84, 0xe3, 0x2a, 0x2e,
-      0xa5, 0xad, 0x1e, 0xe8, 0x35, 0x88, 0xac, 0xdb,
-      0x18, 0x4a, 0x4a, 0x6e, 0x87, 0x56, 0x5b, 0xf5,
-      0x03, 0xb5, 0x69, 0x7a, 0xbf, 0xae, 0x64, 0xa4 },
-    { 0x1f, 0x11, 0x85, 0xa5, 0x21, 0xe2, 0x8e, 0x95,
-      0x17, 0x1c, 0xf3, 0x86, 0x07, 0x8a, 0x76, 0x4a,
-      0x9a, 0x3e, 0x71, 0xc2, 0x59, 0xbc, 0xdc, 0x5f,
-      0x8e, 0x66, 0xe1, 0xb5, 0x20, 0x55, 0xa2, 0x6d },
-    { 0x1f, 0x23, 0xd7, 0xa6, 0x38, 0x17, 0x1f, 0x6d,
-      0x09, 0x99, 0x64, 0xe0, 0xfa, 0x01, 0x72, 0x1c,
-      0x06, 0xcc, 0xeb, 0x8e, 0xa2, 0x98, 0xbf, 0xd0,
-      0x04, 0x8e, 0x13, 0x8d, 0x98, 0xfc, 0x36, 0x24 },
-    { 0x1f, 0xc7, 0xf8, 0x10, 0x4e, 0x27, 0xff, 0x2a,
-      0x45, 0x56, 0xf9, 0x1e, 0x05, 0x42, 0x17, 0xc5,
-      0x8f, 0x69, 0x3f, 0x70, 0x36, 0x25, 0x9e, 0x39,
-      0x80, 0xb5, 0x59, 0x5b, 0x04, 0x3d, 0x11, 0x92 },
-    { 0x20, 0x0b, 0x49, 0xbd, 0xd6, 0x35, 0x02, 0x57,
-      0xcc, 0xd4, 0xe6, 0xad, 0xe1, 0xcb, 0x75, 0x13,
-      0x8d, 0xd6, 0xd9, 0x06, 0xfe, 0xf3, 0x49, 0xc0,
-      0xc9, 0x86, 0xa5, 0x1b, 0x29, 0xb9, 0xe5, 0x2d },
-    { 0x21, 0x78, 0xe8, 0x28, 0x3a, 0x73, 0x39, 0x6e,
-      0x08, 0xc0, 0xa1, 0x1a, 0x88, 0x72, 0xfa, 0x4a,
-      0x9f, 0xcc, 0x05, 0x67, 0x0c, 0xee, 0xff, 0xb8,
-      0x95, 0x83, 0x8e, 0xb6, 0x59, 0xde, 0x38, 0xdb },
-    { 0x22, 0x01, 0x71, 0xf7, 0x0e, 0x1f, 0xc3, 0xc4,
-      0xf7, 0x8d, 0xa6, 0xc8, 0xb1, 0xd7, 0x2c, 0x3b,
-      0xa8, 0x31, 0x9a, 0x46, 0xf8, 0x19, 0x2d, 0x1e,
-      0x19, 0xb9, 0xe2, 0x9a, 0xba, 0x18, 0xee, 0x87 },
-    { 0x23, 0x19, 0xcb, 0x3d, 0x58, 0xc6, 0xd5, 0x53,
-      0x62, 0x5d, 0xe5, 0xf4, 0x25, 0x2b, 0xf0, 0x29,
-      0xab, 0x83, 0x05, 0xeb, 0xf2, 0x2f, 0xa2, 0x3e,
-      0x99, 0x73, 0x04, 0x66, 0xde, 0x24, 0xd6, 0xc3 },
-    { 0x23, 0x8a, 0x80, 0xcc, 0x9b, 0x58, 0x9a, 0xdc,
-      0x89, 0xb7, 0xa8, 0xf3, 0x4d, 0xdf, 0x12, 0x48,
-      0x73, 0x4b, 0x9f, 0x7f, 0x78, 0x20, 0xb6, 0x04,
-      0x07, 0x66, 0xc5, 0x41, 0x3a, 0xd2, 0xbd, 0xef },
-    { 0x23, 0x9c, 0x79, 0x5f, 0x0c, 0x55, 0xa5, 0x53,
-      0x16, 0x2a, 0x9c, 0xa0, 0x6e, 0x88, 0x01, 0xe1,
-      0x19, 0xbd, 0xff, 0x54, 0x35, 0x4a, 0x3f, 0x68,
-      0x43, 0xcf, 0x2a, 0x2f, 0xa6, 0x01, 0x75, 0x8e },
-    { 0x24, 0x62, 0x52, 0x48, 0x32, 0xc1, 0x54, 0xd8,
-      0x4d, 0xf5, 0x8e, 0xd7, 0x75, 0x22, 0x3b, 0xbe,
-      0x25, 0x7d, 0xea, 0xf7, 0x0e, 0xf9, 0xd2, 0x08,
-      0x61, 0x4e, 0xc0, 0xf5, 0x97, 0x7f, 0x6d, 0x58 },
-    { 0x24, 0x6d, 0x0c, 0x31, 0x48, 0x72, 0x75, 0x59,
-      0xf9, 0x9a, 0xd0, 0xc1, 0x50, 0x37, 0x70, 0x06,
-      0xb7, 0xa1, 0x7a, 0x60, 0x3a, 0x47, 0x3b, 0x6a,
-      0xac, 0xd2, 0x4e, 0x16, 0xc6, 0xc5, 0x1b, 0x42 },
-    { 0x25, 0x1b, 0xb7, 0xc5, 0x42, 0x33, 0xda, 0x44,
-      0xbf, 0x53, 0xb5, 0x8a, 0xf2, 0x9a, 0xe1, 0x74,
-      0xb9, 0x78, 0xba, 0xdb, 0x89, 0xa9, 0x50, 0xab,
-      0x3e, 0x5f, 0x9b, 0x4d, 0x0d, 0xcd, 0xbc, 0x62 },
-    { 0x26, 0x03, 0xcb, 0xdf, 0x69, 0x75, 0xe3, 0x68,
-      0x83, 0x7f, 0x95, 0x1a, 0x00, 0x49, 0xfd, 0xc3,
-      0xc4, 0xb2, 0x39, 0xf0, 0x82, 0xf6, 0xbf, 0x89,
-      0x5d, 0xb8, 0xf3, 0x27, 0x05, 0xe6, 0x9c, 0xf3 },
-    { 0x27, 0x50, 0x11, 0x93, 0xe4, 0x61, 0xca, 0xce,
-      0x55, 0x32, 0xfa, 0xd5, 0xd5, 0xb2, 0x7e, 0x01,
-      0x16, 0x57, 0x92, 0xe0, 0x4f, 0x24, 0x21, 0x93,
-      0x2f, 0x39, 0x28, 0xaf, 0x9f, 0xcd, 0xa4, 0xf3 },
-    { 0x27, 0xa8, 0x41, 0xae, 0xcf, 0xe0, 0xa1, 0x39,
-      0x37, 0x51, 0xc2, 0x55, 0xf9, 0x06, 0xdb, 0x9e,
-      0x88, 0x6b, 0xba, 0x4d, 0x7c, 0x44, 0xec, 0x63,
-      0xce, 0x7d, 0xc6, 0xde, 0xc1, 0x8b, 0xb9, 0x20 },
-    { 0x28, 0x07, 0x10, 0x60, 0x44, 0x03, 0x45, 0xd0,
-      0x0e, 0x80, 0xb9, 0xd7, 0xcb, 0xe1, 0x87, 0xc1,
-      0xd8, 0xb0, 0xf2, 0xef, 0x5d, 0x0a, 0xac, 0x9c,
-      0xce, 0xef, 0x9a, 0x8c, 0x5a, 0x06, 0xf3, 0x02 },
-    { 0x28, 0xd9, 0x51, 0x84, 0xb5, 0xea, 0x14, 0x0f,
-      0x47, 0x4f, 0x3a, 0xf6, 0xce, 0x70, 0x52, 0xe8,
-      0x59, 0x3c, 0xf3, 0xa5, 0x01, 0x0f, 0x52, 0x24,
-      0x1a, 0x1e, 0x36, 0x64, 0x60, 0xe5, 0x91, 0x9e },
-    { 0x29, 0x01, 0x93, 0xe3, 0x7a, 0x38, 0x87, 0xfd,
-      0x36, 0x15, 0xdf, 0x12, 0x2e, 0x95, 0x21, 0x17,
-      0x42, 0x15, 0xee, 0x68, 0xf7, 0x44, 0xb2, 0xfa,
-      0x35, 0xd2, 0x9c, 0x5d, 0xf1, 0x08, 0xf5, 0x5b },
-    { 0x2a, 0x0f, 0x70, 0x67, 0x6e, 0x18, 0x4d, 0x49,
-      0x39, 0xa4, 0x04, 0xde, 0x35, 0xac, 0x84, 0xab,
-      0x81, 0xaf, 0xec, 0x36, 0x17, 0xe7, 0xe1, 0xbf,
-      0x34, 0x67, 0xd4, 0x19, 0x25, 0x5d, 0xd8, 0x17 },
-    { 0x2a, 0xa6, 0x47, 0x8c, 0xc7, 0x5d, 0x67, 0xa8,
-      0xca, 0x55, 0xb2, 0xe1, 0x63, 0xfd, 0xbb, 0xbc,
-      0x9d, 0x74, 0xb4, 0xe5, 0xf3, 0x7b, 0x7d, 0xbd,
-      0x13, 0xc9, 0x4e, 0x85, 0x8d, 0x40, 0xda, 0xd0 },
-    { 0x2c, 0x82, 0x47, 0x4f, 0x0e, 0xf6, 0xcb, 0x65,
-      0x0a, 0x13, 0xef, 0x20, 0x99, 0x6e, 0x65, 0x7b,
-      0x67, 0x24, 0xf0, 0xa0, 0xd5, 0xee, 0x24, 0x6d,
-      0x26, 0xbb, 0xfa, 0x0a, 0xbb, 0x2c, 0x22, 0xe1 },
-    { 0x2c, 0x9b, 0xe1, 0x2d, 0xa4, 0x99, 0xea, 0xbb,
-      0x2f, 0xfd, 0xf9, 0x91, 0x6f, 0x2b, 0x27, 0x18,
-      0x81, 0x19, 0x5b, 0x74, 0x19, 0xbd, 0x1e, 0xef,
-      0x8d, 0x50, 0x77, 0x2a, 0xb9, 0x46, 0x4a, 0xa8 },
-    { 0x2c, 0xbd, 0xd5, 0x6c, 0xe4, 0xb4, 0x06, 0x09,
-      0xe9, 0xaa, 0x52, 0x1e, 0xaa, 0x76, 0xac, 0x7e,
-      0x55, 0x73, 0x7b, 0xf4, 0x3e, 0x2b, 0x0c, 0x30,
-      0xdd, 0xcf, 0x59, 0x87, 0x2e, 0xab, 0xe7, 0x7b },
-    { 0x2d, 0xde, 0xe4, 0x5f, 0x72, 0x78, 0x38, 0xde,
-      0xad, 0xe6, 0x7e, 0x9c, 0xa7, 0x05, 0xeb, 0xb4,
-      0xc2, 0xe9, 0x40, 0xae, 0x1b, 0x9d, 0x62, 0x35,
-      0x72, 0x18, 0x04, 0x58, 0x31, 0xe9, 0x8f, 0xde },
-    { 0x2e, 0x5d, 0xd2, 0x55, 0x09, 0x6d, 0x64, 0x83,
-      0x10, 0x5c, 0xb6, 0x03, 0x6c, 0x59, 0x17, 0x57,
-      0xfd, 0x98, 0x49, 0x70, 0x66, 0x05, 0x3f, 0x83,
-      0x39, 0xe4, 0xd8, 0xd0, 0xc3, 0x75, 0x49, 0x03 },
-    { 0x2e, 0xd2, 0x05, 0x8f, 0x39, 0xea, 0xba, 0x5c,
-      0xb3, 0xd7, 0xdf, 0x24, 0xca, 0x74, 0xa7, 0x7d,
-      0xdc, 0x12, 0x06, 0x01, 0x52, 0x7b, 0x0f, 0x51,
-      0x06, 0x91, 0x05, 0xca, 0x88, 0x37, 0x6e, 0x20 },
-    { 0x30, 0x7b, 0x09, 0x34, 0xef, 0x97, 0x85, 0xe7,
-      0x08, 0xed, 0x48, 0x1a, 0x99, 0x7a, 0x8a, 0x88,
-      0xb7, 0xbf, 0x22, 0xdd, 0x26, 0xaa, 0x17, 0x17,
-      0x31, 0xb8, 0xf7, 0xe0, 0xd5, 0x97, 0xb7, 0x08 },
-    { 0x30, 0xe0, 0x69, 0x80, 0x9c, 0x79, 0x90, 0xf0,
-      0xb5, 0xf2, 0x66, 0xe8, 0x94, 0x59, 0x96, 0x42,
-      0xe8, 0x53, 0x50, 0xab, 0x82, 0x81, 0x05, 0x34,
-      0xc7, 0xf3, 0xfd, 0x67, 0x0c, 0x1b, 0xeb, 0x18 },
-    { 0x31, 0x53, 0x47, 0x52, 0xb6, 0xf5, 0x48, 0x20,
-      0x91, 0x5c, 0x39, 0x5b, 0xee, 0x97, 0x5b, 0xc5,
-      0x4e, 0x3f, 0x07, 0xc0, 0x8c, 0xd3, 0x4c, 0x5a,
-      0x51, 0x15, 0xde, 0xf0, 0x17, 0xdb, 0x2b, 0x54 },
-    { 0x31, 0xb8, 0x3e, 0x01, 0x90, 0x98, 0x95, 0xbc,
-      0x74, 0x2d, 0x6b, 0xe8, 0x40, 0x0a, 0xde, 0x51,
-      0xb2, 0x09, 0x83, 0xf6, 0x83, 0xa2, 0xaa, 0xee,
-      0xb2, 0x5f, 0x58, 0xdf, 0x98, 0x1b, 0xde, 0x0d },
-    { 0x32, 0xef, 0x13, 0x33, 0x86, 0xbf, 0x0c, 0x63,
-      0xcf, 0x29, 0xd6, 0x2b, 0x0d, 0x76, 0x88, 0x9e,
-      0x9d, 0x9d, 0x53, 0x2e, 0xe4, 0x90, 0x38, 0x94,
-      0x4d, 0xbc, 0x21, 0x49, 0xd8, 0xca, 0xa5, 0xd1 },
-    { 0x33, 0xd1, 0x6c, 0xd9, 0xe8, 0x2e, 0xdf, 0xfd,
-      0x0b, 0x3a, 0xfb, 0x46, 0xa6, 0x84, 0xc5, 0xa0,
-      0xd1, 0x2f, 0x2b, 0x40, 0x58, 0x6d, 0x53, 0x2f,
-      0x6a, 0xab, 0x54, 0xce, 0xbc, 0x42, 0x33, 0xd3 },
-    { 0x34, 0x06, 0x4f, 0xf9, 0x3b, 0x27, 0x4c, 0xf5,
-      0xa7, 0x24, 0xec, 0x19, 0x64, 0x50, 0x4a, 0x71,
-      0x0a, 0xb9, 0x7b, 0xa1, 0x10, 0x3c, 0xd9, 0xb9,
-      0x8c, 0x81, 0xd0, 0xab, 0xcf, 0x3b, 0x19, 0xbd },
-    { 0x34, 0x65, 0xc2, 0xf9, 0xa0, 0xcf, 0x36, 0xe5,
-      0xee, 0xf0, 0x27, 0x1c, 0x52, 0x91, 0x2d, 0x58,
-      0x6f, 0xb2, 0x0b, 0x94, 0x43, 0xe7, 0xd5, 0x82,
-      0xa3, 0xe2, 0x23, 0x93, 0xfa, 0xc8, 0x1b, 0xb4 },
-    { 0x34, 0x87, 0x46, 0xbf, 0xd4, 0x98, 0xc3, 0xf5,
-      0xc8, 0x68, 0x5e, 0xea, 0xac, 0x57, 0x87, 0x2d,
-      0x3b, 0x47, 0xe6, 0x02, 0xf4, 0x97, 0xe9, 0xf0,
-      0x28, 0x54, 0x12, 0x32, 0x59, 0xfb, 0xe1, 0x69 },
-    { 0x36, 0x45, 0xef, 0x7f, 0x5d, 0x15, 0xa5, 0x46,
-      0x7e, 0x85, 0x30, 0x7d, 0xda, 0x15, 0xcb, 0xbb,
-      0x55, 0xb7, 0x30, 0xae, 0xf8, 0xef, 0x9c, 0x71,
-      0x5d, 0x7d, 0x9f, 0xb4, 0x7f, 0xdf, 0x33, 0xad },
-    { 0x36, 0xb4, 0xfe, 0x74, 0x3b, 0x6d, 0xf4, 0x4a,
-      0x71, 0x3e, 0x91, 0x4c, 0xab, 0xfb, 0xf2, 0xbe,
-      0x60, 0x24, 0x9b, 0x46, 0x43, 0x4d, 0x04, 0x43,
-      0x59, 0x12, 0x5a, 0x10, 0x6a, 0x37, 0xeb, 0x1c },
-    { 0x36, 0xf5, 0xa9, 0x7d, 0x79, 0x3f, 0x84, 0x97,
-      0x44, 0xd6, 0xab, 0x39, 0xb7, 0xa8, 0x18, 0xf8,
-      0x17, 0x6e, 0x65, 0x20, 0xdc, 0x86, 0x3d, 0xce,
-      0x43, 0xb3, 0x98, 0xc3, 0x0b, 0x5e, 0xdb, 0x09 },
-    { 0x38, 0x23, 0x4e, 0x55, 0x9d, 0x30, 0x27, 0xd1,
-      0x61, 0xda, 0x8c, 0x98, 0x88, 0x04, 0x9a, 0x4d,
-      0x20, 0xac, 0xf2, 0x00, 0x90, 0xad, 0x1a, 0x22,
-      0x2b, 0x73, 0x9a, 0xc8, 0x6e, 0xb7, 0x6f, 0x06 },
-    { 0x39, 0x02, 0x27, 0xce, 0x88, 0x1c, 0x71, 0x8b,
-      0x59, 0xa6, 0xbc, 0x31, 0x90, 0xd5, 0x17, 0xe7,
-      0x1e, 0x1e, 0x58, 0x66, 0x93, 0xc8, 0xbf, 0x8a,
-      0x30, 0x27, 0x26, 0x20, 0x13, 0xfe, 0x16, 0x63 },
-    { 0x39, 0x21, 0x5c, 0xaa, 0x37, 0x1a, 0xbe, 0x57,
-      0x6a, 0xb9, 0x3b, 0x18, 0xc2, 0xf3, 0x75, 0x5e,
-      0xe2, 0x6f, 0x8c, 0x3a, 0xdb, 0x75, 0x9b, 0x6f,
-      0x34, 0x78, 0x9f, 0xb8, 0xec, 0xf0, 0x54, 0x28 },
-    { 0x39, 0x7d, 0x00, 0x6e, 0xf8, 0xaf, 0xb2, 0x0f,
-      0x43, 0x61, 0xa6, 0xc9, 0x72, 0xf0, 0xc5, 0x7c,
-      0xc0, 0x87, 0x74, 0x01, 0x06, 0x12, 0x78, 0x3f,
-      0xba, 0xbc, 0xb8, 0xd6, 0xf6, 0x03, 0x9e, 0x2c },
-    { 0x3a, 0xcf, 0x85, 0x3c, 0x4e, 0x45, 0x02, 0xbd,
-      0x82, 0xd5, 0x85, 0xd5, 0xe0, 0x82, 0xc4, 0xb3,
-      0xad, 0x03, 0xcd, 0xb6, 0xb5, 0x05, 0xca, 0x80,
-      0x47, 0x19, 0x88, 0xec, 0x4c, 0x58, 0x99, 0x9e },
-    { 0x3a, 0xea, 0x2c, 0xef, 0xae, 0x63, 0x44, 0xff,
-      0xae, 0x67, 0x49, 0x4c, 0x68, 0x4e, 0x1e, 0xbf,
-      0x87, 0x95, 0x40, 0xb5, 0x3d, 0x40, 0xf5, 0x16,
-      0x9f, 0x78, 0x89, 0x7f, 0x1b, 0x38, 0xab, 0x66 },
-    { 0x3b, 0x47, 0x85, 0x0b, 0xf8, 0x4c, 0x4c, 0xf2,
-      0xca, 0x6c, 0x31, 0xb3, 0x78, 0x39, 0xc9, 0x50,
-      0x76, 0x63, 0x70, 0xd7, 0xf4, 0xb6, 0x4a, 0xd0,
-      0x18, 0x55, 0xca, 0xcf, 0xe3, 0x51, 0x2f, 0xc3 },
-    { 0x3b, 0xaa, 0x31, 0x31, 0x70, 0x68, 0xac, 0xe0,
-      0x89, 0xae, 0xb4, 0xa8, 0x8d, 0x7e, 0xde, 0xbe,
-      0x94, 0xab, 0x4a, 0xce, 0x46, 0xbb, 0xd2, 0x68,
-      0x3e, 0x3f, 0xdf, 0xf5, 0x59, 0x30, 0x0f, 0x93 },
-    { 0x3c, 0x38, 0x36, 0x2e, 0x16, 0x8b, 0xb4, 0xa7,
-      0x59, 0xc4, 0x80, 0x55, 0x1c, 0xb1, 0x65, 0x6f,
-      0x6a, 0x96, 0x8b, 0x9b, 0x43, 0xcb, 0xe0, 0xd7,
-      0x39, 0x75, 0x4a, 0xb7, 0x8a, 0x28, 0x87, 0x0e },
-    { 0x3c, 0x84, 0xa8, 0xb3, 0x4d, 0x0f, 0x95, 0xca,
-      0xc6, 0xfa, 0xaa, 0xb6, 0x22, 0xc2, 0x74, 0x46,
-      0xb4, 0xc4, 0x72, 0xdf, 0x34, 0x53, 0xd7, 0x54,
-      0x64, 0xc0, 0x96, 0x23, 0x86, 0x56, 0xb9, 0xd4 },
-    { 0x3d, 0x14, 0x47, 0x2d, 0xce, 0x4a, 0xfd, 0xc2,
-      0x27, 0x6c, 0x81, 0x47, 0x97, 0xc7, 0xbc, 0x7a,
-      0x6c, 0x14, 0xf7, 0x95, 0x3e, 0x7e, 0x9f, 0xea,
-      0x69, 0x51, 0x04, 0x0f, 0x2d, 0xaf, 0xbe, 0x9a },
-    { 0x3e, 0x8e, 0x9b, 0xad, 0x8e, 0xd9, 0xb5, 0x72,
-      0x38, 0x2e, 0x59, 0x8d, 0x2d, 0x73, 0x67, 0xe1,
-      0xfd, 0x6a, 0xf6, 0x95, 0x25, 0x00, 0x9d, 0x67,
-      0xb4, 0xe8, 0xaf, 0x80, 0xd9, 0x15, 0x85, 0x49 },
-    { 0x3f, 0x27, 0xbd, 0xca, 0x9b, 0x0e, 0x42, 0xf3,
-      0xf6, 0xd0, 0x91, 0x2c, 0x92, 0xe2, 0xda, 0x65,
-      0xcb, 0x35, 0x8f, 0x0b, 0x8f, 0x80, 0x5b, 0xec,
-      0x5d, 0xe9, 0x32, 0x51, 0xd9, 0xc4, 0xb1, 0x99 },
-    { 0x3f, 0x2e, 0xa6, 0x4e, 0xfb, 0xd6, 0xbf, 0xc4,
-      0x0a, 0xf0, 0xad, 0x46, 0xa4, 0xa2, 0x57, 0x84,
-      0x19, 0xd8, 0x68, 0x6e, 0x38, 0x98, 0x8b, 0x91,
-      0x47, 0x01, 0x8c, 0x36, 0x29, 0x31, 0xe4, 0xf9 },
-    { 0x3f, 0x4f, 0x28, 0x8b, 0xaf, 0x5b, 0xde, 0x86,
-      0x72, 0xd6, 0xad, 0xd1, 0x50, 0xe3, 0x23, 0x79,
-      0x49, 0x9a, 0x16, 0xc5, 0x81, 0xfb, 0x77, 0x37,
-      0xec, 0x49, 0x80, 0xe4, 0xf9, 0xc3, 0x3d, 0x4d },
-    { 0x3f, 0x92, 0x54, 0x89, 0x64, 0xcc, 0xde, 0xfb,
-      0x29, 0x96, 0x5a, 0x27, 0xc1, 0x6c, 0x2f, 0xed,
-      0x28, 0xd9, 0xb9, 0x14, 0x0e, 0x4f, 0xb5, 0x5b,
-      0x37, 0x22, 0x4c, 0x67, 0xb2, 0xa0, 0x55, 0x1f },
-    { 0x40, 0x58, 0xec, 0x4a, 0x7a, 0x7b, 0xa0, 0xb8,
-      0x65, 0xa7, 0x39, 0xa0, 0x0c, 0x85, 0xf3, 0x44,
-      0x58, 0x79, 0xd6, 0x5e, 0x1d, 0x42, 0x2e, 0xed,
-      0x07, 0x65, 0x5a, 0x8e, 0x3e, 0xc3, 0x18, 0xcf },
-    { 0x41, 0x29, 0x6b, 0x9f, 0xaa, 0xd6, 0x41, 0x33,
-      0xfc, 0xcb, 0xa6, 0xba, 0x74, 0x54, 0x11, 0xec,
-      0xc9, 0x11, 0xfd, 0x8e, 0xd5, 0x41, 0x90, 0x0f,
-      0x9e, 0x20, 0x36, 0x08, 0xee, 0xa3, 0x59, 0x2d },
-    { 0x41, 0x88, 0x71, 0x80, 0x7e, 0xdc, 0xed, 0xa8,
-      0x57, 0xd7, 0xe8, 0x48, 0x31, 0x71, 0x81, 0xe1,
-      0xe8, 0x33, 0xf5, 0x4c, 0x89, 0xa6, 0x11, 0xa2,
-      0x30, 0xad, 0x99, 0x06, 0x5d, 0x45, 0x86, 0x95 },
-    { 0x41, 0xa6, 0x8d, 0xfd, 0x90, 0xda, 0x6d, 0x12,
-      0x09, 0x84, 0x85, 0xbf, 0x6f, 0x87, 0x24, 0x5f,
-      0x4e, 0xc0, 0x54, 0x71, 0xda, 0x59, 0xd0, 0x81,
-      0x06, 0x01, 0x53, 0xa2, 0x22, 0x25, 0x23, 0x7f },
-    { 0x42, 0x08, 0x71, 0xd8, 0xac, 0x49, 0x3c, 0xf9,
-      0x46, 0x8b, 0xb3, 0x76, 0x97, 0x6d, 0x65, 0x5e,
-      0xf0, 0xaf, 0xaa, 0xc2, 0x3d, 0x77, 0x00, 0x92,
-      0x20, 0xc3, 0xaf, 0x8b, 0xdd, 0x37, 0x5a, 0x24 },
-    { 0x42, 0x5d, 0x4e, 0xbf, 0x1b, 0xde, 0x0b, 0xf8,
-      0xd1, 0xdb, 0xd3, 0x3d, 0x8d, 0x16, 0x34, 0xc4,
-      0xfa, 0xfe, 0xb6, 0xf8, 0x05, 0xf1, 0xcc, 0xb5,
-      0x34, 0xac, 0xb7, 0x2a, 0xed, 0xa2, 0xcd, 0x0a },
-    { 0x44, 0x12, 0x63, 0x80, 0xa0, 0x73, 0xfe, 0xa1,
-      0xa2, 0x00, 0x4f, 0x71, 0x1d, 0xf2, 0xca, 0x47,
-      0xc2, 0xc4, 0xb4, 0xff, 0x64, 0x4e, 0x76, 0xaf,
-      0xbe, 0x27, 0x97, 0xc9, 0x63, 0x7c, 0x6a, 0xf9 },
-    { 0x44, 0x25, 0xdd, 0xfb, 0xba, 0xfb, 0xe1, 0xaa,
-      0xce, 0x25, 0x85, 0x70, 0x48, 0x96, 0x9d, 0xc8,
-      0x9d, 0xf5, 0x97, 0x7b, 0xb2, 0xe3, 0x34, 0x7c,
-      0x9c, 0xeb, 0x0e, 0x5a, 0x7b, 0x68, 0xc5, 0x31 },
-    { 0x45, 0x63, 0xcf, 0x13, 0xc2, 0x49, 0x2c, 0xaa,
-      0x92, 0xf5, 0x5b, 0x17, 0x26, 0x3a, 0xdd, 0x72,
-      0x04, 0xa8, 0x0f, 0xe6, 0x24, 0x0c, 0x4d, 0x63,
-      0xe8, 0x39, 0x59, 0x58, 0xf6, 0x94, 0xcd, 0x33 },
-    { 0x45, 0xcb, 0x86, 0xca, 0x97, 0x52, 0x29, 0xb7,
-      0xd5, 0xda, 0xfc, 0x05, 0xeb, 0x0c, 0x53, 0x65,
-      0x82, 0x3a, 0x91, 0xa9, 0x8b, 0x7d, 0xbe, 0x81,
-      0xab, 0x5f, 0x17, 0x8b, 0x2d, 0xa4, 0xad, 0x9e },
-    { 0x46, 0x9b, 0xd8, 0x04, 0xe9, 0x98, 0xae, 0x27,
-      0x9a, 0xc3, 0xfe, 0x1b, 0x52, 0x88, 0x46, 0xe7,
-      0xae, 0xc7, 0x6c, 0x56, 0xb8, 0x0b, 0x40, 0xf3,
-      0x24, 0x20, 0x8f, 0x5a, 0x9f, 0x64, 0x5c, 0xb5 },
-    { 0x46, 0xcd, 0x08, 0x08, 0x8d, 0x36, 0x06, 0x2c,
-      0x56, 0x71, 0x09, 0x2c, 0x02, 0x76, 0x7a, 0x25,
-      0x0d, 0xe7, 0x0b, 0xf3, 0xe1, 0x53, 0x63, 0x69,
-      0x66, 0xe6, 0x6e, 0xc5, 0x7e, 0x8e, 0xe9, 0xf5 },
-    { 0x47, 0x84, 0xf6, 0xcd, 0x59, 0x3d, 0x7b, 0x31,
-      0x2e, 0xb1, 0xf6, 0x19, 0xe1, 0x11, 0xdf, 0x3b,
-      0x48, 0x6d, 0x1b, 0xf8, 0x37, 0x15, 0xad, 0x8d,
-      0xab, 0xa5, 0x72, 0xaf, 0xb2, 0x61, 0xd5, 0xbe },
-    { 0x47, 0x8c, 0xdd, 0x82, 0x3f, 0x81, 0x7d, 0x21,
-      0x8b, 0xf5, 0xdd, 0xa4, 0xc3, 0xe9, 0x9e, 0x7f,
-      0xa3, 0x10, 0x9b, 0x67, 0xbd, 0x0c, 0x9b, 0x1f,
-      0x40, 0x75, 0x96, 0x65, 0xb9, 0xec, 0x3f, 0xf2 },
-    { 0x48, 0xc5, 0xd4, 0xff, 0x5d, 0x08, 0x4a, 0xc1,
-      0x95, 0xb1, 0xa6, 0xa2, 0x19, 0xf8, 0x1b, 0xbd,
-      0xf9, 0xd2, 0xe5, 0xc0, 0x70, 0xec, 0x97, 0xdf,
-      0x3c, 0xb0, 0xb7, 0x3e, 0xf4, 0x70, 0xdc, 0xe9 },
-    { 0x49, 0xdc, 0xf8, 0xfa, 0x68, 0xe9, 0x2b, 0x5c,
-      0x21, 0xfe, 0xf9, 0x3d, 0x26, 0x0c, 0x24, 0x8c,
-      0xe3, 0xbe, 0x98, 0x62, 0x68, 0x68, 0xe7, 0x5a,
-      0x3f, 0x63, 0x34, 0xbb, 0x7d, 0xc1, 0x81, 0xec },
-    { 0x4b, 0x1f, 0xc8, 0x2d, 0x24, 0x72, 0x92, 0x7a,
-      0xc1, 0x7c, 0x58, 0x43, 0x07, 0xcb, 0x96, 0xd6,
-      0xfd, 0xdb, 0x8d, 0x50, 0xa5, 0x29, 0x53, 0x07,
-      0xd3, 0x0c, 0x75, 0x88, 0x59, 0x6a, 0xd4, 0x0b },
-    { 0x4b, 0x51, 0xfc, 0x11, 0x4b, 0xac, 0x8e, 0x2d,
-      0x2a, 0xf2, 0xae, 0x56, 0x84, 0x42, 0x9c, 0xca,
-      0xab, 0x21, 0x39, 0xc9, 0xb3, 0x51, 0xbf, 0x7e,
-      0x1b, 0x03, 0x0a, 0xe8, 0x62, 0x4a, 0xc1, 0x72 },
-    { 0x4c, 0xd0, 0xd6, 0x7e, 0xcc, 0x3b, 0x01, 0xc8,
-      0xc2, 0x63, 0x4e, 0x7a, 0x73, 0x76, 0x12, 0xf6,
-      0x3a, 0x17, 0xff, 0x51, 0x0a, 0x77, 0xa8, 0x04,
-      0xbb, 0x33, 0x1b, 0x2b, 0xe5, 0x8d, 0xfe, 0x0c },
-    { 0x4d, 0xcf, 0xeb, 0xdc, 0x15, 0x4b, 0x0c, 0x85,
-      0x46, 0x7f, 0x6f, 0x52, 0xad, 0x80, 0x4e, 0x19,
-      0x1d, 0x5b, 0xc8, 0x13, 0x51, 0x72, 0x0e, 0xc0,
-      0xd1, 0x9b, 0xd2, 0x5b, 0xf8, 0xf0, 0xa5, 0x53 },
-    { 0x4f, 0x19, 0xdd, 0x12, 0x92, 0x4c, 0xe0, 0xc1,
-      0x4f, 0x82, 0xc0, 0x56, 0xc7, 0xd4, 0x2b, 0xac,
-      0x43, 0xd0, 0x13, 0x3a, 0xaf, 0x89, 0xc1, 0xef,
-      0xdc, 0xfa, 0x3c, 0x3e, 0x47, 0x09, 0x7d, 0x59 },
-    { 0x4f, 0xfb, 0x59, 0x19, 0xbc, 0x38, 0x5c, 0x8c,
-      0x58, 0xe4, 0x62, 0xbf, 0x13, 0x22, 0x10, 0xd8,
-      0xb7, 0x86, 0x12, 0xd0, 0xc2, 0x2a, 0x6b, 0x6a,
-      0x68, 0x2e, 0x0b, 0x9e, 0x9c, 0x9f, 0x9a, 0x44 },
-    { 0x50, 0xf4, 0x78, 0x1e, 0xb1, 0xc1, 0x46, 0x70,
-      0xd9, 0xa5, 0x52, 0xc3, 0x49, 0x5f, 0xb9, 0xf6,
-      0xae, 0x86, 0x8a, 0xb1, 0xc9, 0xd9, 0x83, 0xe0,
-      0x82, 0x68, 0x65, 0xa1, 0x02, 0xec, 0xa6, 0xd3 },
-    { 0x51, 0x6a, 0x2f, 0x33, 0x60, 0xc7, 0x6f, 0xc4,
-      0x6a, 0xb2, 0x88, 0x7f, 0x88, 0xe8, 0xd0, 0x8e,
-      0xfb, 0xd8, 0x44, 0x5a, 0xa7, 0xbb, 0xd2, 0x29,
-      0xdf, 0xc7, 0x1a, 0x90, 0x4f, 0x55, 0xae, 0xb4 },
-    { 0x52, 0x1f, 0x6c, 0x6a, 0x84, 0x36, 0x65, 0x79,
-      0xca, 0x2d, 0xea, 0xeb, 0x23, 0x15, 0xbf, 0x8e,
-      0x53, 0x1c, 0x9f, 0xa4, 0x7b, 0x89, 0x9d, 0xa2,
-      0x72, 0x16, 0xa9, 0x98, 0x82, 0x86, 0xaf, 0xe5 },
-    { 0x52, 0xff, 0x8b, 0x6e, 0x98, 0xb0, 0x96, 0x19,
-      0x90, 0x03, 0xde, 0x97, 0xbc, 0xcf, 0xd2, 0xa7,
-      0xf1, 0xac, 0x57, 0xa8, 0x31, 0x35, 0xb9, 0x55,
-      0xff, 0x68, 0x63, 0x36, 0xa6, 0x91, 0xd5, 0xca },
-    { 0x53, 0x79, 0x64, 0x58, 0xda, 0x97, 0xce, 0x36,
-      0x78, 0xf2, 0xd1, 0xd9, 0xb2, 0xa5, 0xb2, 0xfb,
-      0x30, 0x75, 0xea, 0xfa, 0xf6, 0xff, 0x04, 0x78,
-      0xb5, 0x72, 0xdd, 0xfd, 0x70, 0x99, 0xae, 0xe2 },
-    { 0x53, 0x82, 0xd6, 0xba, 0xb5, 0x78, 0x51, 0xd9,
-      0xb5, 0x8c, 0x17, 0x54, 0x46, 0xbf, 0x2d, 0x1b,
-      0xb7, 0x86, 0xa5, 0x30, 0xfb, 0xf0, 0xae, 0xcd,
-      0x12, 0xea, 0xb8, 0xa9, 0xa5, 0xb4, 0x96, 0x60 },
-    { 0x53, 0x9c, 0xa9, 0xe1, 0xf0, 0x6a, 0xf2, 0x10,
-      0x7f, 0x96, 0xbf, 0x4b, 0x7d, 0xd4, 0xce, 0xcd,
-      0x9e, 0xd1, 0x1a, 0x38, 0xd6, 0x70, 0x91, 0x69,
-      0x9c, 0x56, 0x26, 0xe2, 0x7a, 0x1f, 0x54, 0xa5 },
-    { 0x55, 0x21, 0xf9, 0x63, 0x57, 0x81, 0x58, 0xb8,
-      0xd0, 0xe7, 0xc4, 0x91, 0xcd, 0xb8, 0x5c, 0x3d,
-      0xe9, 0xd5, 0x2e, 0xa5, 0x1f, 0xfc, 0xb0, 0x93,
-      0xd3, 0x12, 0x28, 0x11, 0x13, 0x14, 0x97, 0xeb },
-    { 0x55, 0xd0, 0xeb, 0xe3, 0x2c, 0xba, 0x09, 0xf6,
-      0x58, 0x4d, 0x9e, 0x7b, 0x57, 0x92, 0xa4, 0x03,
-      0xc2, 0x1d, 0x39, 0xd6, 0xe1, 0xf5, 0xe8, 0xed,
-      0x37, 0xb9, 0x3f, 0xa6, 0x1d, 0x88, 0x35, 0x16 },
-    { 0x58, 0x1a, 0xde, 0x64, 0x84, 0x95, 0xb4, 0xb1,
-      0x62, 0x9c, 0x3c, 0x7c, 0x78, 0xef, 0xbe, 0xf2,
-      0x75, 0x06, 0x56, 0x65, 0xb2, 0x41, 0x1c, 0x0e,
-      0x5f, 0xcf, 0xbc, 0x7e, 0xb4, 0xbe, 0x34, 0x0b },
-    { 0x59, 0xc9, 0xe8, 0xdf, 0x03, 0x0b, 0x1c, 0xd5,
-      0x89, 0xa8, 0xb3, 0x4f, 0xe7, 0x42, 0x51, 0xea,
-      0xd5, 0xa5, 0xfb, 0xe9, 0xe6, 0x13, 0x67, 0xca,
-      0x76, 0xaf, 0xd9, 0xdd, 0xd9, 0xc6, 0xf1, 0x6f },
-    { 0x59, 0xe9, 0xfa, 0x2f, 0xf0, 0x76, 0x89, 0x33,
-      0x28, 0x33, 0xc6, 0x40, 0xf5, 0x05, 0xfa, 0x24,
-      0x09, 0xeb, 0x88, 0x93, 0x32, 0x57, 0xc1, 0x93,
-      0xb0, 0x07, 0xd3, 0xa2, 0x89, 0x6a, 0x98, 0x50 },
-    { 0x59, 0xee, 0x9b, 0x36, 0x80, 0xae, 0x20, 0x56,
-      0x83, 0x9c, 0x0b, 0xf6, 0x9e, 0xe6, 0x63, 0x26,
-      0x57, 0x16, 0xa8, 0xe2, 0x4c, 0xc6, 0x49, 0x95,
-      0xfb, 0xa6, 0xcb, 0x6f, 0x0c, 0x12, 0x39, 0xdc },
-    { 0x5a, 0x84, 0xaf, 0xe6, 0x74, 0x05, 0xab, 0xe8,
-      0x4a, 0x0c, 0xd4, 0x2c, 0x2b, 0xa2, 0xe4, 0xc8,
-      0x8f, 0x35, 0xe0, 0xa5, 0x95, 0xe5, 0x69, 0xa3,
-      0xe1, 0x86, 0x69, 0x44, 0x40, 0x5b, 0xe7, 0x36 },
-    { 0x5a, 0x8e, 0x86, 0x21, 0x2c, 0x06, 0x33, 0x94,
-      0x94, 0xf8, 0x5b, 0x5f, 0x85, 0x11, 0xdf, 0x00,
-      0x00, 0x23, 0x94, 0x07, 0x8f, 0xfc, 0x77, 0x4d,
-      0x43, 0x6f, 0x0d, 0x63, 0x86, 0xd7, 0xa6, 0xf7 },
-    { 0x5a, 0xc0, 0x98, 0x2d, 0xa0, 0xc8, 0x3d, 0x0b,
-      0xa9, 0x38, 0x1a, 0x5c, 0xd8, 0x7b, 0x80, 0xd1,
-      0x10, 0xf2, 0x6e, 0xe8, 0x39, 0x27, 0x1b, 0xc2,
-      0x70, 0x60, 0x8f, 0xd1, 0x43, 0x7f, 0x55, 0xb0 },
-    { 0x5c, 0x7f, 0xf0, 0x55, 0xc2, 0xfd, 0x03, 0x3f,
-      0x34, 0xc4, 0xc4, 0xf7, 0xc4, 0xfb, 0x7d, 0xda,
-      0xaa, 0xfb, 0x43, 0x56, 0xc5, 0x60, 0xc9, 0x9e,
-      0xdf, 0xf0, 0x74, 0xda, 0x04, 0xaf, 0x65, 0x7c },
-    { 0x5c, 0xd2, 0x44, 0x6a, 0x8e, 0x4a, 0x0f, 0xa7,
-      0xe3, 0xcd, 0xf8, 0x00, 0x5d, 0xed, 0xce, 0xba,
-      0xe9, 0xe6, 0x81, 0x9a, 0x8a, 0x69, 0x87, 0x31,
-      0x55, 0x5b, 0x7d, 0xc9, 0xd0, 0xa2, 0x3f, 0xc0 },
-    { 0x5c, 0xeb, 0xeb, 0xd8, 0x34, 0x01, 0xb7, 0x0b,
-      0xac, 0xb5, 0x4f, 0x66, 0xa9, 0xb7, 0x78, 0x55,
-      0x69, 0x6e, 0xce, 0x16, 0x7f, 0xe6, 0xc6, 0x0a,
-      0x05, 0x16, 0x8b, 0xe4, 0x39, 0x19, 0xc8, 0x0f },
-    { 0x5f, 0x8b, 0x88, 0x8e, 0xe9, 0x6c, 0x0c, 0x0f,
-      0x5a, 0x91, 0x72, 0x90, 0xac, 0xa6, 0x5a, 0xfd,
-      0x6e, 0xbd, 0xae, 0x05, 0xa0, 0x2a, 0xaf, 0x04,
-      0x29, 0xe9, 0x72, 0xec, 0x01, 0x90, 0xec, 0xfc },
-    { 0x62, 0x2e, 0xc3, 0xbe, 0x7c, 0xf5, 0xe4, 0xe6,
-      0x3f, 0x74, 0x18, 0x69, 0x28, 0x74, 0x40, 0x05,
-      0xcb, 0xb7, 0x8d, 0xf3, 0x06, 0xb8, 0x67, 0xc3,
-      0xfc, 0xad, 0x5e, 0x2b, 0xa7, 0x53, 0x96, 0x83 },
-    { 0x62, 0x6f, 0x7e, 0xb4, 0xfd, 0x9b, 0x71, 0xff,
-      0xaa, 0x0c, 0x8e, 0xc9, 0x65, 0x54, 0x64, 0xe6,
-      0x5e, 0x7f, 0x96, 0xcf, 0xa3, 0x82, 0x73, 0x97,
-      0x41, 0x35, 0x66, 0xaa, 0x2c, 0xc1, 0xe5, 0x72 },
-    { 0x63, 0x64, 0x15, 0x61, 0x77, 0xdc, 0xdf, 0x60,
-      0x4d, 0xf9, 0x1e, 0x31, 0x32, 0x2e, 0x57, 0x74,
-      0x69, 0x1e, 0x0c, 0x41, 0xfa, 0x0d, 0x2f, 0x25,
-      0x7a, 0xd7, 0xf9, 0xf0, 0x25, 0x98, 0x14, 0x45 },
-    { 0x65, 0x66, 0x00, 0xa4, 0x5e, 0x45, 0x6a, 0xba,
-      0x5b, 0x00, 0x8d, 0x87, 0x91, 0x54, 0xb7, 0x69,
-      0x0d, 0x7f, 0x27, 0x31, 0x02, 0x09, 0x7d, 0x8f,
-      0xd8, 0xc3, 0xde, 0xab, 0x30, 0xd8, 0x4a, 0xb2 },
-    { 0x65, 0xed, 0x61, 0xa8, 0x8c, 0x55, 0xef, 0xb0,
-      0x38, 0x07, 0x1a, 0xee, 0xde, 0xf8, 0xe1, 0x83,
-      0xe2, 0x37, 0x38, 0x46, 0x97, 0x26, 0xeb, 0x99,
-      0x68, 0x0c, 0xd2, 0x44, 0x72, 0x73, 0x6b, 0xec },
-    { 0x66, 0x50, 0xb2, 0xea, 0x64, 0x4c, 0x3f, 0x4e,
-      0x8c, 0x9e, 0x3c, 0x46, 0xac, 0xea, 0xc4, 0x52,
-      0x33, 0xd8, 0x66, 0xe3, 0x98, 0xff, 0x90, 0xeb,
-      0x59, 0xb2, 0xc6, 0x25, 0x20, 0x82, 0xac, 0x04 },
-    { 0x66, 0xbe, 0x7e, 0xa1, 0x13, 0x8b, 0xcb, 0xa4,
-      0xde, 0x0b, 0x41, 0x28, 0x5d, 0x9a, 0x13, 0x3f,
-      0xa7, 0xf5, 0x70, 0xa3, 0xc8, 0x13, 0x55, 0x79,
-      0xb8, 0x60, 0x19, 0x9d, 0x0a, 0x51, 0x45, 0x7c },
-    { 0x69, 0x01, 0x4b, 0xbc, 0x84, 0x29, 0xd8, 0x5f,
-      0x41, 0xc2, 0x22, 0xd9, 0x7f, 0x7e, 0xd5, 0x35,
-      0xcf, 0x81, 0x23, 0x9a, 0xf2, 0x7a, 0xcc, 0x88,
-      0x70, 0xdc, 0xd4, 0x08, 0x34, 0x8b, 0x48, 0xba },
-    { 0x69, 0x21, 0x1f, 0x36, 0x3a, 0x2d, 0xbe, 0x01,
-      0x5b, 0x31, 0xcb, 0xd9, 0xfc, 0x5e, 0x94, 0xc2,
-      0xf6, 0xf4, 0x3c, 0x58, 0xdb, 0xde, 0xe9, 0xe3,
-      0xe4, 0x6b, 0x19, 0xd7, 0x59, 0xbb, 0xb8, 0x81 },
-    { 0x69, 0x75, 0x67, 0xbb, 0xac, 0x94, 0xee, 0xc3,
-      0xe6, 0xfa, 0x4a, 0x4e, 0x46, 0xfa, 0x51, 0x74,
-      0x05, 0xf3, 0x77, 0xc0, 0xde, 0xe3, 0xd4, 0x29,
-      0x91, 0x4e, 0x6b, 0x7e, 0xa0, 0x8c, 0xb1, 0xa6 },
-    { 0x6a, 0xac, 0xc5, 0x09, 0x2f, 0x12, 0xbc, 0x94,
-      0xa0, 0xad, 0x0e, 0x9e, 0xf6, 0x36, 0x43, 0x7d,
-      0x36, 0x0d, 0xc7, 0xc9, 0xf1, 0x40, 0x44, 0x17,
-      0xa3, 0x36, 0x91, 0x94, 0x4e, 0x76, 0x31, 0x36 },
-    { 0x6b, 0x4a, 0x8c, 0xb6, 0x07, 0xf5, 0x1c, 0x83,
-      0x0d, 0xe7, 0x20, 0xf4, 0xbb, 0xde, 0xdf, 0x49,
-      0x10, 0x15, 0x13, 0xdf, 0xd1, 0xdb, 0x0b, 0x0a,
-      0x97, 0xcc, 0x3f, 0xdd, 0x9a, 0x39, 0xc6, 0xe7 },
-    { 0x6c, 0x8f, 0xd1, 0xe6, 0xe1, 0x1b, 0xaf, 0xa6,
-      0x17, 0x78, 0x13, 0xa0, 0x44, 0x40, 0xb1, 0xb9,
-      0x6a, 0x1c, 0xdb, 0x7c, 0x2d, 0x70, 0x3f, 0x55,
-      0xde, 0x85, 0x7c, 0x80, 0xa8, 0x9e, 0x73, 0x25 },
-    { 0x6c, 0xc6, 0xdc, 0xda, 0x58, 0xc6, 0x1f, 0xb2,
-      0x86, 0x70, 0xd1, 0xc2, 0x01, 0x76, 0x57, 0xb0,
-      0xc5, 0xd6, 0x1a, 0x26, 0xc9, 0xcb, 0xd1, 0xea,
-      0x75, 0x5c, 0x68, 0x20, 0xb5, 0xf6, 0xd6, 0x7d },
-    { 0x6d, 0x32, 0xf4, 0x93, 0x40, 0x56, 0xee, 0x17,
-      0x14, 0xca, 0x72, 0x70, 0x3f, 0x64, 0x46, 0x9b,
-      0x98, 0x58, 0xfc, 0x39, 0x96, 0x4b, 0x4c, 0x03,
-      0x93, 0xb3, 0x7d, 0xde, 0xab, 0x8b, 0x19, 0x75 },
-    { 0x6e, 0x1a, 0x88, 0x63, 0xf2, 0x93, 0x4b, 0x39,
-      0x01, 0x23, 0x7e, 0x84, 0xd0, 0x76, 0x27, 0x04,
-      0x23, 0x06, 0x78, 0x7f, 0x2d, 0xe0, 0x66, 0x30,
-      0xbd, 0x37, 0xd8, 0x03, 0x94, 0x35, 0xbf, 0xca },
-    { 0x6e, 0x99, 0x8d, 0xdd, 0xf2, 0x93, 0x9b, 0xfe,
-      0x8c, 0xc5, 0x2a, 0x48, 0x0a, 0xc0, 0x6d, 0x69,
-      0x71, 0xc5, 0xa3, 0xda, 0x97, 0xcf, 0x3e, 0xf0,
-      0x1a, 0xf2, 0x9d, 0x74, 0x72, 0x62, 0x31, 0xe2 },
-    { 0x6f, 0x3b, 0xb3, 0x4b, 0x5d, 0x32, 0x91, 0xdf,
-      0xb3, 0xe4, 0x12, 0x71, 0xa1, 0xd7, 0x30, 0xcd,
-      0xbc, 0xff, 0xc1, 0x0b, 0x68, 0x05, 0x9d, 0xcc,
-      0xd3, 0x1c, 0x47, 0x4b, 0xb7, 0x44, 0x16, 0xe5 },
-    { 0x6f, 0xbd, 0xcd, 0xf1, 0xb4, 0x37, 0x9f, 0xc4,
-      0x73, 0xab, 0x5e, 0xea, 0x4e, 0xc2, 0xf4, 0x84,
-      0xce, 0x91, 0xd1, 0x0e, 0x31, 0x34, 0x5f, 0x15,
-      0xa7, 0x6a, 0x84, 0x85, 0xb8, 0xff, 0xfb, 0x7e },
-    { 0x70, 0xb8, 0xec, 0xd5, 0x62, 0xec, 0x3d, 0x9f,
-      0x48, 0x64, 0x75, 0x2a, 0x3a, 0x8c, 0x54, 0x39,
-      0x93, 0xb4, 0x38, 0x72, 0x8f, 0xe2, 0x71, 0x81,
-      0xf4, 0xc0, 0x8d, 0xe6, 0xa0, 0xd8, 0xb7, 0x9a },
-    { 0x72, 0x1b, 0x1f, 0x92, 0x9d, 0xa7, 0xea, 0xf8,
-      0x96, 0x24, 0x64, 0x7b, 0xa3, 0xcc, 0x4e, 0x1e,
-      0xd1, 0x57, 0x54, 0xab, 0x83, 0x6e, 0x33, 0x58,
-      0xb0, 0x35, 0xa1, 0xf2, 0x27, 0x4a, 0x43, 0xbe },
-    { 0x72, 0x81, 0xda, 0x0d, 0x8c, 0xe9, 0xd5, 0x3e,
-      0xa3, 0xd1, 0xf5, 0x93, 0x5c, 0x58, 0x21, 0xea,
-      0x8d, 0x9a, 0xf1, 0xce, 0x0b, 0xca, 0xf8, 0x82,
-      0x5d, 0x78, 0x3f, 0x37, 0xea, 0xc3, 0x4f, 0x40 },
-    { 0x72, 0xe7, 0x49, 0x87, 0x21, 0x0c, 0x7e, 0xf6,
-      0x67, 0x46, 0xe4, 0x9a, 0x96, 0xdf, 0x55, 0xcc,
-      0x6f, 0xad, 0xf7, 0xa6, 0x31, 0xc7, 0xae, 0x3f,
-      0x3e, 0x9e, 0x18, 0x72, 0x3d, 0xe5, 0x2a, 0x6e },
-    { 0x73, 0x3b, 0x42, 0x24, 0x25, 0x8d, 0xee, 0x07,
-      0x0e, 0xdf, 0xa3, 0x41, 0x1f, 0xbc, 0x9b, 0xad,
-      0x31, 0x65, 0xbe, 0x66, 0x0f, 0x34, 0x0a, 0xa2,
-      0x30, 0x8a, 0x5a, 0x33, 0x23, 0xfa, 0xbf, 0xa7 },
-    { 0x74, 0x8e, 0xbb, 0x72, 0xd1, 0x02, 0x04, 0xf4,
-      0x04, 0x10, 0xbe, 0x70, 0x80, 0xbf, 0xe7, 0xee,
-      0x63, 0x1f, 0xc0, 0x4d, 0x1f, 0xdb, 0x50, 0x72,
-      0x04, 0x4b, 0xfa, 0x55, 0x7a, 0xdf, 0x6e, 0x5a },
-    { 0x74, 0xe2, 0xcc, 0xcf, 0x62, 0xd5, 0xb9, 0xf9,
-      0x00, 0xb4, 0x14, 0x73, 0xca, 0x44, 0xe6, 0x87,
-      0x96, 0x38, 0x74, 0x3d, 0x8f, 0xee, 0x66, 0xee,
-      0x71, 0x8c, 0x18, 0xd8, 0xf1, 0x12, 0x15, 0xd1 },
-    { 0x76, 0x98, 0x67, 0x60, 0xac, 0xfe, 0x55, 0x59,
-      0xa2, 0xa2, 0xab, 0x2a, 0x4e, 0x85, 0x49, 0x83,
-      0xc5, 0xfd, 0xe6, 0x73, 0xce, 0x8e, 0xb1, 0x71,
-      0x23, 0x49, 0x48, 0x64, 0x86, 0x7a, 0x98, 0xb1 },
-    { 0x78, 0x0c, 0x33, 0xfe, 0x95, 0x4c, 0xc4, 0xdb,
-      0x39, 0x04, 0xd7, 0x6a, 0x68, 0x58, 0xbc, 0xd1,
-      0x01, 0x7f, 0x52, 0xda, 0x59, 0x9d, 0x36, 0xda,
-      0xe6, 0x66, 0xc0, 0x4e, 0x41, 0xaf, 0x8d, 0xcd },
-    { 0x78, 0xc9, 0x30, 0x40, 0x5a, 0x72, 0x0d, 0x9f,
-      0x00, 0x66, 0xdd, 0x88, 0xa2, 0xa8, 0xda, 0xfb,
-      0xbe, 0x6c, 0xd6, 0x5d, 0x54, 0xb7, 0x76, 0x06,
-      0x42, 0x1b, 0x45, 0x43, 0x8c, 0x65, 0x8a, 0xd4 },
-    { 0x79, 0x8f, 0x83, 0xb1, 0xc4, 0xc6, 0x5c, 0x4d,
-      0x5d, 0xea, 0x13, 0x03, 0x53, 0x53, 0xd8, 0xed,
-      0xe5, 0xd7, 0x1d, 0x99, 0x47, 0xf4, 0x34, 0xfd,
-      0xea, 0x0d, 0xbc, 0x1e, 0xc8, 0x2f, 0x45, 0x35 },
-    { 0x7b, 0xfe, 0x47, 0xae, 0xba, 0x8b, 0x0a, 0x3a,
-      0x94, 0x5a, 0x88, 0xd8, 0xef, 0x18, 0x91, 0xc9,
-      0x89, 0x97, 0x8a, 0xbf, 0x12, 0x2e, 0xc5, 0xe0,
-      0x51, 0x4b, 0xe3, 0x6c, 0x3a, 0x7f, 0x22, 0x9b },
-    { 0x7d, 0x20, 0xc7, 0xa9, 0x27, 0x26, 0x2b, 0xe7,
-      0x38, 0xd2, 0x58, 0xd0, 0xfd, 0x97, 0x6e, 0x9a,
-      0xf3, 0x6e, 0xf7, 0x99, 0x5f, 0x05, 0xe2, 0x87,
-      0x6a, 0x29, 0xae, 0xbc, 0x3a, 0x24, 0xaa, 0xce },
-    { 0x7e, 0x2e, 0xdb, 0x9d, 0x38, 0xf9, 0x29, 0x3c,
-      0xdd, 0xd6, 0x03, 0xb1, 0x75, 0xc9, 0xb2, 0x05,
-      0xac, 0x0b, 0x55, 0x3a, 0x4b, 0xf5, 0xfb, 0x08,
-      0xc2, 0x46, 0xec, 0xf9, 0xc8, 0x49, 0xdb, 0x28 },
-    { 0x7f, 0x95, 0x9b, 0x06, 0x34, 0xda, 0x94, 0xfa,
-      0xca, 0xda, 0xb0, 0x21, 0xcf, 0x94, 0x20, 0x78,
-      0x16, 0x00, 0x36, 0x13, 0xef, 0x09, 0xeb, 0x54,
-      0xf6, 0x48, 0x60, 0x50, 0x08, 0x19, 0x02, 0x75 },
-    { 0x7f, 0x9a, 0x69, 0xcf, 0xa2, 0xf5, 0x0c, 0x13,
-      0xe1, 0xb7, 0x11, 0xdd, 0x6b, 0x14, 0x69, 0x2b,
-      0xdb, 0x77, 0xd9, 0xff, 0xd8, 0xc1, 0x10, 0xae,
-      0x5d, 0x05, 0xa4, 0xcb, 0x73, 0x12, 0x37, 0x48 },
-    { 0x7f, 0xcc, 0xa8, 0xb5, 0xf5, 0xe3, 0x3b, 0xca,
-      0x6d, 0xe0, 0x9c, 0x14, 0xaf, 0xbb, 0xe0, 0xc3,
-      0x41, 0x21, 0xac, 0xbb, 0x22, 0x22, 0x9f, 0x44,
-      0xee, 0x5c, 0x3f, 0x4d, 0xde, 0x73, 0x50, 0x55 },
-    { 0x80, 0x20, 0x56, 0xe1, 0xdb, 0x9d, 0x9b, 0x73,
-      0x21, 0xd1, 0xff, 0xbb, 0xe1, 0x2f, 0x5c, 0xbe,
-      0xde, 0xc3, 0x6d, 0x0b, 0x5e, 0xc2, 0xa4, 0xe1,
-      0x8d, 0x99, 0x54, 0x36, 0x4c, 0xec, 0x81, 0x29 },
-    { 0x80, 0x97, 0x63, 0x4c, 0xe3, 0x3d, 0x41, 0x53,
-      0x3d, 0x41, 0x5d, 0xaf, 0xdb, 0x8b, 0xa1, 0x91,
-      0xc0, 0x30, 0x52, 0xac, 0x8b, 0xaa, 0x25, 0x54,
-      0x34, 0x77, 0x3a, 0x16, 0x4b, 0x91, 0x1d, 0x6e },
-    { 0x80, 0xd0, 0x17, 0x09, 0x34, 0xd2, 0x2a, 0xea,
-      0x73, 0x3f, 0x11, 0x5e, 0x52, 0x42, 0xc6, 0xb8,
-      0x6d, 0x7f, 0xcf, 0xb4, 0x90, 0x4e, 0x65, 0xb7,
-      0xb7, 0xb9, 0x07, 0xf2, 0xca, 0x94, 0xed, 0x71 },
-    { 0x81, 0x1d, 0xf2, 0xf4, 0x73, 0x6f, 0x85, 0x62,
-      0xe2, 0x02, 0xfd, 0x00, 0x75, 0x32, 0xf1, 0xde,
-      0x40, 0x17, 0x86, 0x1e, 0xfa, 0xbe, 0x67, 0x34,
-      0x20, 0xc2, 0x7f, 0x2e, 0x2a, 0x33, 0xfa, 0xc1 },
-    { 0x81, 0x1e, 0x37, 0x86, 0x37, 0xb1, 0xd2, 0xcb,
-      0xb1, 0x89, 0xaf, 0xd6, 0x74, 0x95, 0xfe, 0x8a,
-      0xb9, 0xd8, 0x3a, 0x74, 0x2e, 0x35, 0x8c, 0xbb,
-      0xdb, 0xd1, 0x54, 0x98, 0xbf, 0x9c, 0x7b, 0x56 },
-    { 0x81, 0xa0, 0xf1, 0xd0, 0x29, 0x46, 0x8e, 0xe8,
-      0x66, 0x36, 0x4a, 0x19, 0x8a, 0x26, 0x08, 0x58,
-      0x30, 0xc2, 0xa4, 0x16, 0xe4, 0x9e, 0x22, 0x4c,
-      0xe8, 0x09, 0x66, 0xfc, 0xc4, 0x99, 0xd6, 0x36 },
-    { 0x82, 0x56, 0x8b, 0x3b, 0xb3, 0xc6, 0x55, 0xd7,
-      0xf2, 0x2d, 0x8c, 0x97, 0xa5, 0x66, 0x9c, 0xc8,
-      0x34, 0xa2, 0xdd, 0x7c, 0xda, 0xe7, 0x5a, 0x26,
-      0x45, 0x59, 0x55, 0x16, 0x46, 0x55, 0x8e, 0x14 },
-    { 0x82, 0x7c, 0x8c, 0x80, 0x11, 0x1f, 0xf2, 0x21,
-      0xc3, 0xeb, 0x1e, 0xf5, 0xc0, 0xd5, 0xd4, 0x34,
-      0x48, 0x31, 0x86, 0xe2, 0x09, 0x00, 0x75, 0x63,
-      0x15, 0x8e, 0x9e, 0x76, 0xd2, 0x79, 0x0f, 0x1c },
-    { 0x82, 0x92, 0x67, 0xc5, 0xad, 0x70, 0xe5, 0x45,
-      0x18, 0x02, 0x3a, 0xb7, 0x85, 0xfa, 0x3c, 0xde,
-      0xd6, 0x6f, 0x42, 0x5d, 0xe1, 0xf3, 0x2f, 0xcd,
-      0x72, 0x1b, 0x49, 0x46, 0x3a, 0x5a, 0x5f, 0x5b },
-    { 0x83, 0x34, 0xea, 0xb8, 0x1c, 0x60, 0x4e, 0x99,
-      0xd5, 0x40, 0x51, 0x3e, 0xf2, 0xe3, 0x7a, 0xba,
-      0x71, 0x4f, 0x07, 0xb2, 0xba, 0x01, 0x0a, 0xd7,
-      0x1d, 0xc4, 0xe1, 0x1a, 0x92, 0x18, 0xc1, 0x8c },
-    { 0x83, 0x54, 0x7a, 0xca, 0x3c, 0xed, 0x73, 0xdf,
-      0x99, 0x14, 0xf3, 0x15, 0x60, 0x74, 0x63, 0x79,
-      0x29, 0x4c, 0x76, 0x0e, 0xf9, 0xa8, 0xb7, 0x6e,
-      0x00, 0x06, 0x46, 0xc7, 0x39, 0x07, 0x21, 0x65 },
-    { 0x83, 0x89, 0xc8, 0x79, 0xb6, 0x3b, 0x82, 0x9d,
-      0x2d, 0x39, 0xa8, 0xcf, 0xb7, 0x87, 0xe7, 0x72,
-      0x77, 0xd5, 0xcf, 0xa3, 0xe3, 0x6f, 0xda, 0xcb,
-      0xab, 0x4d, 0x18, 0xb2, 0xb0, 0x4e, 0x32, 0x94 },
-    { 0x84, 0x23, 0xb3, 0xf1, 0xcc, 0x85, 0x2b, 0x49,
-      0xcf, 0x81, 0xb7, 0xd5, 0xff, 0x51, 0xa7, 0xa5,
-      0x6a, 0x84, 0x78, 0x3a, 0x2d, 0xf7, 0x43, 0x61,
-      0xff, 0x2e, 0xee, 0x0f, 0x92, 0x12, 0xc1, 0x59 },
-    { 0x84, 0x7b, 0x5f, 0x1e, 0xeb, 0x2a, 0x44, 0x13,
-      0xc8, 0xfa, 0x37, 0x98, 0x21, 0x97, 0x37, 0xe1,
-      0x92, 0xba, 0x72, 0x72, 0xa1, 0x08, 0xb7, 0x17,
-      0x28, 0xa8, 0xd1, 0x65, 0x17, 0xf6, 0x1e, 0x9d },
-    { 0x85, 0x31, 0xb2, 0xbf, 0xc5, 0x45, 0x79, 0xe8,
-      0xf1, 0x8f, 0x27, 0xb2, 0xe6, 0xec, 0xc0, 0xf8,
-      0x90, 0x64, 0xee, 0x86, 0x87, 0x0e, 0xcc, 0x8b,
-      0xbe, 0x0c, 0xe6, 0x86, 0xec, 0xda, 0x2c, 0x17 },
-    { 0x85, 0x76, 0x0f, 0x59, 0x51, 0x90, 0xe9, 0xb4,
-      0x67, 0x8b, 0xbf, 0x44, 0xef, 0xb5, 0xcf, 0x8f,
-      0x6b, 0x19, 0x37, 0xa9, 0xb8, 0x6b, 0x31, 0xb7,
-      0x51, 0xbe, 0xcf, 0x72, 0x18, 0x03, 0xb0, 0x1c },
-    { 0x85, 0xf0, 0x79, 0x36, 0xb4, 0x29, 0x1f, 0x36,
-      0xd9, 0xb7, 0x5f, 0x42, 0xe8, 0xb7, 0xee, 0x8a,
-      0x64, 0xe6, 0x32, 0xa1, 0x18, 0x11, 0x65, 0xfe,
-      0x72, 0xb4, 0x88, 0x23, 0xc3, 0xd9, 0x9d, 0x9d },
-    { 0x86, 0x12, 0x9f, 0xe7, 0x61, 0x99, 0x4d, 0x7b,
-      0x64, 0xe4, 0x02, 0x85, 0x8f, 0x88, 0xc5, 0x2b,
-      0x3e, 0xb9, 0xc0, 0x71, 0xff, 0xbe, 0x80, 0x02,
-      0x80, 0xac, 0x8c, 0x0c, 0x6f, 0x79, 0xe7, 0xa6 },
-    { 0x86, 0x19, 0x6b, 0x0f, 0xd3, 0x0f, 0x8f, 0x57,
-      0x56, 0x98, 0xb5, 0xee, 0xf2, 0x69, 0xd0, 0x69,
-      0x2f, 0x88, 0xad, 0xea, 0xc4, 0x83, 0x6a, 0x62,
-      0x67, 0xab, 0xc8, 0x36, 0x23, 0x34, 0x00, 0x86 },
-    { 0x86, 0xcf, 0xec, 0xbe, 0x82, 0xba, 0xdb, 0x93,
-      0x14, 0x75, 0xf1, 0x9e, 0xcd, 0x6e, 0xa6, 0x7d,
-      0x59, 0xc2, 0xc7, 0x00, 0x78, 0xb6, 0xcc, 0x56,
-      0xbf, 0xdc, 0x27, 0x55, 0x47, 0x67, 0xf2, 0x3f },
-    { 0x86, 0xd1, 0x8b, 0xcd, 0xde, 0x16, 0x45, 0x42,
-      0x48, 0x6e, 0x56, 0x44, 0x2c, 0xe1, 0xb8, 0x8b,
-      0x1a, 0x10, 0x73, 0x7c, 0xbd, 0x5e, 0xa4, 0xaa,
-      0xb8, 0xd5, 0xb8, 0xaf, 0x51, 0xf5, 0x29, 0x09 },
-    { 0x87, 0x5f, 0x57, 0x42, 0x4c, 0x90, 0x2b, 0x24,
-      0xe8, 0x1c, 0x27, 0xd1, 0xca, 0xf2, 0x74, 0xb1,
-      0x7d, 0x72, 0x0d, 0xf8, 0x07, 0x8b, 0x6f, 0x2a,
-      0x5c, 0x3b, 0xb8, 0xd8, 0xdf, 0xf0, 0x55, 0x00 },
-    { 0x88, 0x8d, 0x6d, 0x77, 0xd8, 0x1c, 0x62, 0x91,
-      0xcb, 0x84, 0xd9, 0xd6, 0x56, 0x27, 0x82, 0xfd,
-      0x2e, 0xb3, 0x42, 0x5d, 0x49, 0x1e, 0x68, 0x74,
-      0x20, 0x28, 0x4b, 0x76, 0xa1, 0xde, 0xbf, 0xab },
-    { 0x89, 0xaf, 0x0e, 0x54, 0xc7, 0x62, 0x77, 0x86,
-      0x93, 0x52, 0x9d, 0x0a, 0x95, 0x0b, 0x78, 0x33,
-      0xf5, 0xea, 0xba, 0xf3, 0x42, 0x79, 0x72, 0x60,
-      0x7f, 0xb2, 0xc7, 0x0c, 0x96, 0xa3, 0x21, 0x61 },
-    { 0x89, 0xda, 0xc7, 0x89, 0x6b, 0x46, 0xf2, 0xfc,
-      0x8b, 0xea, 0x62, 0x11, 0xff, 0x98, 0xb6, 0x1f,
-      0xaa, 0x15, 0x7b, 0xa8, 0xc4, 0xad, 0x6f, 0xd1,
-      0x75, 0x92, 0x75, 0xce, 0x39, 0x41, 0xc3, 0x28 },
-    { 0x8a, 0x09, 0x85, 0xbf, 0x86, 0xe8, 0xc9, 0xb9,
-      0x17, 0xec, 0x84, 0xda, 0x2a, 0x56, 0x73, 0x1e,
-      0x75, 0x2a, 0xa0, 0xdc, 0x52, 0x87, 0xc2, 0xbf,
-      0x39, 0x51, 0x0b, 0xb3, 0xf0, 0xf2, 0x0a, 0xd1 },
-    { 0x8a, 0xaf, 0x36, 0x3c, 0xc9, 0xd8, 0x44, 0x15,
-      0xa7, 0xeb, 0x0d, 0x72, 0xda, 0x08, 0xb3, 0x58,
-      0x80, 0x68, 0x55, 0x9c, 0xb0, 0xa9, 0xae, 0x92,
-      0xb8, 0xf4, 0x60, 0x2e, 0xda, 0x23, 0x82, 0xaa },
-    { 0x8a, 0xb2, 0x77, 0x62, 0xf4, 0xa2, 0xe3, 0x11,
-      0x22, 0x04, 0x96, 0x98, 0x39, 0x99, 0xc8, 0xc4,
-      0x60, 0x96, 0x3d, 0xfc, 0x1b, 0x88, 0x51, 0x11,
-      0x1d, 0xa4, 0x1d, 0x3f, 0x3b, 0x0a, 0x6e, 0x94 },
-    { 0x8a, 0xd1, 0xd5, 0x48, 0x95, 0x27, 0xb5, 0x28,
-      0xe5, 0xb5, 0xd6, 0xa5, 0x95, 0x78, 0x87, 0x08,
-      0x88, 0x8a, 0x3f, 0xb1, 0x9f, 0x2c, 0x7c, 0x8b,
-      0x38, 0x07, 0x0e, 0x1f, 0x38, 0x98, 0x96, 0x8b },
-    { 0x8a, 0xdb, 0x49, 0xd4, 0x15, 0x53, 0x56, 0x70,
-      0x5b, 0x64, 0x42, 0x6a, 0x99, 0x0f, 0x58, 0xb3,
-      0xa0, 0x71, 0xef, 0x78, 0x2e, 0x6c, 0x09, 0x53,
-      0x07, 0xd7, 0x74, 0x74, 0xd5, 0xb5, 0x7a, 0x62 },
-    { 0x8b, 0x3a, 0x10, 0x35, 0xc3, 0xfd, 0xf3, 0x45,
-      0xfb, 0x70, 0x80, 0x44, 0x83, 0xa5, 0x04, 0x49,
-      0xa3, 0xd7, 0x60, 0xc6, 0xba, 0x48, 0xf5, 0xb8,
-      0x2d, 0x6b, 0xb2, 0x62, 0xed, 0x9d, 0xe3, 0x73 },
-    { 0x8b, 0x3a, 0x75, 0xcb, 0xc3, 0x62, 0xd2, 0x35,
-      0x57, 0x0e, 0x5d, 0xe7, 0x04, 0x29, 0x38, 0x70,
-      0x8a, 0x1b, 0x0f, 0xce, 0xb4, 0x59, 0x86, 0x2a,
-      0x38, 0x67, 0xb7, 0x34, 0xcd, 0xcb, 0x97, 0x94 },
-    { 0x8c, 0x3e, 0x7c, 0x1d, 0xcc, 0x7d, 0xd8, 0xe7,
-      0xd8, 0xbf, 0x7b, 0x5b, 0x3a, 0xe5, 0xe0, 0x27,
-      0x2e, 0x81, 0x1a, 0xb9, 0xf3, 0xc3, 0xc5, 0x38,
-      0xe5, 0x74, 0x71, 0x77, 0xe6, 0x2d, 0x62, 0x92 },
-    { 0x8c, 0x7c, 0x65, 0x7b, 0xda, 0x13, 0xca, 0x62,
-      0xf2, 0x9a, 0x65, 0xc6, 0xd5, 0x19, 0x3a, 0x93,
-      0xcf, 0x6c, 0x58, 0x77, 0x18, 0xad, 0xca, 0x67,
-      0x15, 0x8e, 0x97, 0xd3, 0x6a, 0x62, 0x3e, 0xca },
-    { 0x8c, 0xa6, 0x79, 0x62, 0xc4, 0xa8, 0x09, 0x13,
-      0x33, 0xf2, 0x4e, 0xfd, 0x60, 0xee, 0x70, 0xcf,
-      0xed, 0xdb, 0xd6, 0x41, 0x59, 0x04, 0x70, 0x9e,
-      0x78, 0x5c, 0x33, 0x1b, 0x1e, 0xf5, 0x8f, 0x8e },
-    { 0x8e, 0x18, 0xfd, 0xbd, 0xb0, 0x08, 0x16, 0x00,
-      0x35, 0xfa, 0xf5, 0x01, 0x5b, 0xe7, 0xda, 0xf4,
-      0x63, 0xb5, 0xc4, 0x14, 0xea, 0xbc, 0x8b, 0x89,
-      0xf3, 0xdb, 0xa2, 0x05, 0xab, 0x09, 0xa6, 0x43 },
-    { 0x8f, 0x10, 0x10, 0x47, 0x93, 0xe8, 0x55, 0x42,
-      0xbc, 0x06, 0x04, 0xd6, 0xcf, 0x21, 0x5f, 0x78,
-      0x80, 0xbd, 0x6a, 0x4d, 0xd0, 0xfd, 0xf1, 0xe7,
-      0xa5, 0xb9, 0xca, 0x12, 0x46, 0xf5, 0xc4, 0x09 },
-    { 0x8f, 0x71, 0x27, 0x76, 0x2e, 0xe7, 0x51, 0x69,
-      0xbd, 0xc3, 0x5b, 0x04, 0xa7, 0x28, 0xe9, 0xd3,
-      0x1b, 0x7e, 0x4d, 0x37, 0x89, 0xaa, 0x2c, 0x46,
-      0xd8, 0xa3, 0x1b, 0x3d, 0xfa, 0x81, 0xa9, 0x7e },
-    { 0x8f, 0x94, 0x15, 0x92, 0x6f, 0x40, 0x49, 0xea,
-      0x41, 0x8a, 0x30, 0x7c, 0x76, 0x36, 0xe4, 0x9b,
-      0x14, 0x4f, 0xa5, 0x3e, 0x52, 0xe1, 0x04, 0x15,
-      0x5f, 0x58, 0x03, 0x5e, 0x45, 0x41, 0xcd, 0x6e },
-    { 0x90, 0xe2, 0x51, 0x86, 0x7f, 0x6b, 0x0c, 0x14,
-      0xbd, 0x9b, 0x51, 0x0c, 0xfd, 0xa8, 0x48, 0x49,
-      0x72, 0xfd, 0xf0, 0xe0, 0x6d, 0xc1, 0x1f, 0x5d,
-      0x1d, 0x59, 0x0b, 0xe3, 0xfc, 0x38, 0xdf, 0xf0 },
-    { 0x91, 0x90, 0xf8, 0x25, 0x51, 0x0c, 0x65, 0x98,
-      0xe1, 0x9d, 0x17, 0xdb, 0xbe, 0x6e, 0x7c, 0x82,
-      0x31, 0x86, 0x9c, 0xa7, 0xf6, 0xe3, 0x07, 0xa2,
-      0xc2, 0xcc, 0x54, 0x77, 0x8d, 0x4a, 0x89, 0xb3 },
-    { 0x92, 0x3f, 0x0f, 0x8c, 0x40, 0x5a, 0x02, 0xe6,
-      0x82, 0xc4, 0xb4, 0x66, 0x5a, 0x7e, 0xe7, 0x16,
-      0xaa, 0x57, 0xe0, 0xa5, 0x86, 0xc2, 0x4a, 0x16,
-      0x5a, 0xad, 0x7e, 0x5b, 0xda, 0x22, 0x78, 0x24 },
-    { 0x92, 0x71, 0x44, 0x12, 0x1c, 0x23, 0x63, 0x57,
-      0x07, 0xe9, 0x40, 0x7f, 0x7f, 0xff, 0x6a, 0x64,
-      0x63, 0x5d, 0x7c, 0xe9, 0x06, 0x66, 0xd4, 0x29,
-      0x94, 0x09, 0x7a, 0xf4, 0x0c, 0x31, 0x36, 0xfb },
-    { 0x94, 0xdc, 0x80, 0x07, 0x49, 0x1d, 0xa8, 0xbf,
-      0xb7, 0x39, 0x14, 0xad, 0xce, 0xf7, 0x1a, 0x12,
-      0x41, 0x58, 0xba, 0xd1, 0x7b, 0xa8, 0x8f, 0xa9,
-      0x46, 0x57, 0x9b, 0xbc, 0x2d, 0x64, 0x97, 0x8d },
-    { 0x95, 0x68, 0x33, 0xae, 0xe6, 0x61, 0x19, 0x26,
-      0xe9, 0x52, 0x72, 0xa1, 0xf5, 0x88, 0xf9, 0x2a,
-      0xf5, 0x2c, 0xae, 0x70, 0x7a, 0xcd, 0xcc, 0x82,
-      0x63, 0x99, 0x7b, 0xfa, 0x8c, 0x71, 0x9c, 0xa8 },
-    { 0x95, 0x89, 0xda, 0xc9, 0xec, 0xe7, 0x6d, 0xf5,
-      0x72, 0x01, 0x96, 0xdc, 0x58, 0x6d, 0x17, 0x9d,
-      0x73, 0x5d, 0xf7, 0x17, 0x92, 0x6c, 0x06, 0x1e,
-      0xa7, 0x0c, 0x40, 0x85, 0x64, 0x8f, 0xf3, 0x12 },
-    { 0x96, 0xa4, 0x59, 0x90, 0xfc, 0xd0, 0x1c, 0x9c,
-      0x2a, 0xf0, 0x64, 0x5f, 0x87, 0xb9, 0x69, 0x8b,
-      0x05, 0xaf, 0xe6, 0x94, 0x32, 0xeb, 0x57, 0x01,
-      0x08, 0x20, 0x13, 0xba, 0xc5, 0xb0, 0x55, 0x60 },
-    { 0x96, 0xeb, 0x44, 0xaa, 0x6a, 0x20, 0x49, 0xe6,
-      0xba, 0xff, 0xe6, 0xb5, 0x21, 0xc4, 0xad, 0x8c,
-      0x58, 0x77, 0x26, 0xca, 0xa0, 0x12, 0xe8, 0xfb,
-      0x8e, 0x8e, 0x21, 0x89, 0x77, 0xbf, 0x1d, 0xf6 },
-    { 0x97, 0x4f, 0x51, 0xa6, 0x04, 0x68, 0x48, 0xfa,
-      0xa7, 0xb3, 0x3f, 0xd2, 0x39, 0x13, 0x86, 0x42,
-      0x8b, 0xd5, 0x24, 0xea, 0xeb, 0xa8, 0x01, 0x4e,
-      0x6d, 0x1f, 0xe2, 0x54, 0x38, 0x3f, 0x41, 0x79 },
-    { 0x97, 0x8d, 0x6f, 0x1e, 0x9a, 0xa3, 0xa3, 0xce,
-      0xb1, 0xad, 0xa6, 0x09, 0xe2, 0x00, 0x95, 0xfb,
-      0xc3, 0x3a, 0x6b, 0xbc, 0x6a, 0x21, 0xd8, 0x0a,
-      0x4e, 0xcb, 0x27, 0x3c, 0x60, 0xac, 0x2a, 0xc7 },
-    { 0x99, 0xa5, 0x5f, 0x76, 0xcb, 0xea, 0x0f, 0x3e,
-      0x60, 0x71, 0xd3, 0x82, 0x18, 0x1a, 0xf6, 0xcb,
-      0x25, 0xbd, 0xc5, 0x87, 0x5e, 0x29, 0xf0, 0xf4,
-      0xd7, 0x19, 0xa9, 0xd3, 0x5b, 0x5b, 0xd6, 0xbf },
-    { 0x9a, 0x4b, 0x49, 0x93, 0xb4, 0xed, 0x8c, 0x27,
-      0xe7, 0x7f, 0x3c, 0x8a, 0xaf, 0xdb, 0xdc, 0x11,
-      0x1a, 0x36, 0xb7, 0x3c, 0xca, 0xdb, 0x87, 0x04,
-      0x98, 0x25, 0x00, 0xd1, 0xb0, 0xf1, 0x09, 0xf2 },
-    { 0x9a, 0xae, 0x9d, 0x45, 0xaa, 0x04, 0x03, 0x06,
-      0x4b, 0xc5, 0xa7, 0x4d, 0xd0, 0x32, 0x5d, 0xa4,
-      0x1e, 0x12, 0xcf, 0x58, 0x6c, 0x46, 0x2e, 0xe0,
-      0x6c, 0x2b, 0xb4, 0x56, 0xf8, 0x44, 0x1c, 0x4f },
-    { 0x9b, 0x8f, 0x9f, 0xc4, 0xaf, 0xa7, 0x04, 0x0d,
-      0x4e, 0x59, 0x4d, 0x66, 0x7c, 0x44, 0x44, 0xb5,
-      0x25, 0x88, 0x20, 0xc0, 0x8f, 0x89, 0x91, 0x0e,
-      0xd3, 0x42, 0x1c, 0xb4, 0xa9, 0x7b, 0xb7, 0x9e },
-    { 0x9c, 0x70, 0x8d, 0x5b, 0xab, 0x37, 0xf5, 0xb6,
-      0xbc, 0x8a, 0x77, 0x53, 0x12, 0x57, 0x2a, 0xb2,
-      0x79, 0x21, 0x6d, 0x55, 0x6d, 0xa7, 0x4a, 0xc2,
-      0xa7, 0xc0, 0x41, 0xe8, 0xce, 0xb0, 0xbe, 0x0a },
-    { 0x9d, 0x6b, 0xdf, 0xcf, 0x0c, 0xbf, 0xfe, 0xea,
-      0x3b, 0x1a, 0xc7, 0xe9, 0x63, 0xcb, 0xb5, 0xf2,
-      0x7f, 0xbd, 0xa8, 0x9d, 0x27, 0x77, 0xf6, 0x0e,
-      0x56, 0x5b, 0x27, 0x78, 0x54, 0xef, 0xb0, 0x19 },
-    { 0x9d, 0xac, 0x33, 0x14, 0xb2, 0x5b, 0xb7, 0x9a,
-      0x39, 0xcd, 0x01, 0xec, 0x4b, 0x33, 0xa1, 0x2f,
-      0x47, 0x51, 0x2f, 0x54, 0x09, 0xff, 0x09, 0x5d,
-      0x40, 0xaa, 0xd6, 0x20, 0x84, 0xef, 0x15, 0xbe },
-    { 0x9f, 0x24, 0x5c, 0x0a, 0x0e, 0xc6, 0x3a, 0xaa,
-      0xcb, 0xf9, 0x69, 0xc6, 0xfc, 0x24, 0xa1, 0x07,
-      0x15, 0x83, 0xb7, 0x79, 0xa5, 0x8a, 0xb6, 0x23,
-      0xdd, 0x15, 0x31, 0xa2, 0xca, 0x9f, 0x87, 0x51 },
-    { 0x9f, 0xaf, 0x1c, 0x11, 0xa3, 0xc7, 0xe2, 0x41,
-      0xf8, 0x63, 0x71, 0x97, 0xe8, 0x99, 0x68, 0xdb,
-      0x86, 0x6a, 0xd0, 0x1a, 0x5d, 0x4e, 0xd5, 0x34,
-      0x59, 0x48, 0x65, 0xb9, 0x70, 0x75, 0xf2, 0x60 },
-    { 0xa0, 0x05, 0x20, 0xb9, 0x68, 0xbf, 0xcb, 0x63,
-      0x40, 0x87, 0x9f, 0xa8, 0x43, 0x82, 0x0c, 0xec,
-      0x95, 0x45, 0x86, 0x0f, 0xe2, 0x9e, 0x2f, 0x8f,
-      0xee, 0x00, 0xb0, 0x0f, 0xf8, 0x43, 0x42, 0x74 },
-    { 0xa0, 0xc2, 0xd2, 0x07, 0xa4, 0x7e, 0x18, 0xd0,
-      0x37, 0x14, 0xd5, 0xb3, 0x44, 0x5d, 0x88, 0xbe,
-      0x81, 0xff, 0x5e, 0x1d, 0x16, 0x07, 0x3d, 0xc1,
-      0x16, 0x6b, 0xb5, 0x44, 0x8f, 0xf6, 0x52, 0xdf },
-    { 0xa1, 0x50, 0x03, 0x2f, 0x4e, 0xf5, 0xd4, 0xfe,
-      0xb0, 0xae, 0x4a, 0xe1, 0xcd, 0x54, 0x35, 0xba,
-      0x04, 0xa9, 0xb6, 0xa0, 0xf9, 0x0e, 0x2f, 0x3c,
-      0x4b, 0x8a, 0x7b, 0x69, 0xe7, 0xc8, 0x7e, 0x43 },
-    { 0xa1, 0x97, 0x7d, 0x0c, 0x92, 0x7c, 0x21, 0xeb,
-      0x47, 0x6f, 0x67, 0xbe, 0xfe, 0xd6, 0xcf, 0x2c,
-      0x61, 0xb7, 0x45, 0xf0, 0xce, 0x8d, 0x26, 0x58,
-      0x3d, 0x03, 0xb2, 0x70, 0x02, 0xd5, 0xcd, 0xaf },
-    { 0xa2, 0x6c, 0x37, 0x5e, 0xb3, 0x19, 0x6e, 0x28,
-      0x3b, 0xec, 0x60, 0x3d, 0xb6, 0xbb, 0xda, 0xe2,
-      0x49, 0x55, 0xe4, 0xba, 0x91, 0x0c, 0xd4, 0x2d,
-      0x9e, 0xac, 0x55, 0xca, 0xc6, 0x10, 0x3a, 0xb9 },
-    { 0xa3, 0xa4, 0xfc, 0x03, 0xe1, 0x75, 0xf2, 0x68,
-      0x02, 0x57, 0x46, 0x34, 0xde, 0x70, 0x7d, 0x2f,
-      0x92, 0xf4, 0xd0, 0xcb, 0x90, 0xcd, 0xb6, 0x1d,
-      0xd1, 0x95, 0x8b, 0xcf, 0x0c, 0x55, 0x20, 0x86 },
-    { 0xa6, 0x62, 0xfc, 0x81, 0xc9, 0x09, 0x34, 0xb9,
-      0xb4, 0xd6, 0x30, 0xb5, 0xd8, 0x2e, 0x86, 0xf2,
-      0x36, 0x3e, 0xc1, 0x5c, 0xcf, 0xcd, 0xaf, 0xa7,
-      0xa2, 0x0c, 0x9b, 0x4e, 0x3a, 0x90, 0x0d, 0xd1 },
-    { 0xa6, 0xa4, 0xa3, 0xf6, 0x1f, 0xa5, 0x8c, 0xe9,
-      0x70, 0xb4, 0x58, 0xb7, 0xc3, 0x7c, 0x05, 0x2e,
-      0xad, 0x1e, 0xb2, 0x0b, 0x85, 0x67, 0xe3, 0x51,
-      0xad, 0x8e, 0x6f, 0xba, 0x49, 0xc2, 0x69, 0x2c },
-    { 0xa6, 0xde, 0x6c, 0x3b, 0x8c, 0x14, 0x05, 0xcb,
-      0xe1, 0x2d, 0xb4, 0x09, 0x97, 0x61, 0x71, 0xac,
-      0xb5, 0x1f, 0xb3, 0xdc, 0xfb, 0xb7, 0x6e, 0xe3,
-      0x84, 0x95, 0x39, 0xcd, 0x8a, 0xb0, 0x66, 0xdf },
-    { 0xa8, 0x53, 0xad, 0xc1, 0xc2, 0x18, 0x59, 0xaf,
-      0x7c, 0x46, 0x2b, 0x4a, 0xa0, 0xa5, 0x74, 0xca,
-      0x9f, 0xee, 0xfb, 0x18, 0x5a, 0x1f, 0xdb, 0xb6,
-      0xc1, 0x0e, 0x17, 0xd6, 0x01, 0xb7, 0x09, 0x8f },
-    { 0xa8, 0xdf, 0xf0, 0x6a, 0x17, 0x35, 0xb4, 0x6d,
-      0x17, 0xda, 0xeb, 0xc3, 0x43, 0x43, 0x18, 0x31,
-      0x3b, 0x2d, 0x9e, 0x7c, 0x3e, 0xf4, 0x8f, 0x28,
-      0x53, 0x75, 0x35, 0x13, 0xe1, 0xb2, 0x53, 0xa8 },
-    { 0xa8, 0xe3, 0x8c, 0x6e, 0xc0, 0x93, 0xf5, 0xaf,
-      0x53, 0x88, 0xf1, 0xe7, 0x66, 0xd7, 0x5f, 0xfb,
-      0x57, 0xdd, 0xbe, 0x3e, 0x9d, 0xc2, 0xe0, 0xbe,
-      0x57, 0xbb, 0x88, 0x36, 0x46, 0xc5, 0xc0, 0x32 },
-    { 0xa9, 0x0b, 0x8d, 0xe1, 0x7f, 0x6b, 0x68, 0x37,
-      0x56, 0x21, 0x2d, 0xb3, 0xab, 0x34, 0x89, 0x6e,
-      0x91, 0x70, 0x93, 0x11, 0x3e, 0x47, 0xca, 0x35,
-      0x96, 0x2e, 0xac, 0xca, 0x9c, 0xb3, 0x86, 0xf0 },
-    { 0xaa, 0x4b, 0xb3, 0x6f, 0x51, 0xd3, 0xc5, 0x33,
-      0xb5, 0x27, 0x23, 0xcf, 0x66, 0xa5, 0xa9, 0x9f,
-      0xc1, 0x2f, 0x11, 0xd4, 0xcc, 0x12, 0x87, 0x56,
-      0xa5, 0xa3, 0xe8, 0x9c, 0x57, 0xbb, 0x97, 0x51 },
-    { 0xaa, 0xeb, 0xfe, 0x2d, 0x21, 0xb7, 0xe5, 0x35,
-      0x1b, 0xb9, 0x99, 0x69, 0x44, 0x44, 0x19, 0xef,
-      0x21, 0xc9, 0x68, 0x8c, 0xe0, 0x53, 0x24, 0x88,
-      0x84, 0xca, 0xb0, 0xb8, 0x95, 0x10, 0x30, 0xff },
-    { 0xab, 0x41, 0x28, 0x10, 0x9c, 0xab, 0x8a, 0x58,
-      0x7c, 0x8f, 0xf4, 0xc7, 0xf6, 0x87, 0x34, 0x49,
-      0x98, 0x18, 0xd1, 0x3f, 0x52, 0x26, 0x76, 0xd0,
-      0x66, 0xb3, 0x52, 0x17, 0x6f, 0xd2, 0x35, 0x96 },
-    { 0xab, 0x80, 0xd9, 0xba, 0x0a, 0xef, 0xad, 0x7b,
-      0xec, 0xce, 0x7f, 0x5e, 0x61, 0x59, 0x9a, 0xf5,
-      0x26, 0x69, 0xbf, 0x59, 0x50, 0x7f, 0x8e, 0xf1,
-      0x99, 0x13, 0xc4, 0x2e, 0xe1, 0x29, 0xda, 0xf0 },
-    { 0xab, 0xeb, 0x6a, 0xa0, 0xd1, 0xb0, 0xe0, 0x49,
-      0xd6, 0x9d, 0xf8, 0x3a, 0xdd, 0x19, 0xf7, 0x26,
-      0x8a, 0x38, 0xde, 0x6c, 0x00, 0x72, 0x60, 0x68,
-      0xc2, 0xee, 0xe4, 0x55, 0x44, 0xf6, 0xd6, 0x7a },
-    { 0xac, 0x1b, 0x4c, 0x64, 0x6c, 0xae, 0xfb, 0x10,
-      0x8a, 0x54, 0xca, 0xb5, 0x4a, 0x96, 0xe9, 0x66,
-      0x6e, 0x72, 0xa8, 0x20, 0x22, 0x44, 0xef, 0x3d,
-      0x7c, 0xa9, 0x34, 0xdf, 0xcc, 0x24, 0xfc, 0xa7 },
-    { 0xad, 0x69, 0x54, 0x5f, 0x9f, 0x85, 0x25, 0x5f,
-      0xe4, 0x16, 0x51, 0x3d, 0x94, 0xdb, 0x31, 0x50,
-      0x5f, 0x38, 0x4b, 0x52, 0x3c, 0x2c, 0xa2, 0x6e,
-      0xdc, 0x0a, 0x54, 0x9a, 0x8f, 0x16, 0x26, 0xf9 },
-    { 0xae, 0x03, 0x19, 0xfe, 0xa6, 0xa6, 0x5e, 0x84,
-      0xe8, 0x54, 0xb5, 0x15, 0x50, 0xea, 0x44, 0x4f,
-      0xa3, 0xb8, 0xbb, 0x50, 0xae, 0x93, 0x74, 0x01,
-      0x3c, 0xfe, 0xf3, 0x88, 0x73, 0x5d, 0x0b, 0xd3 },
-    { 0xaf, 0x1f, 0x37, 0x1f, 0x34, 0x84, 0x57, 0x51,
-      0x65, 0x2d, 0xc7, 0x48, 0x23, 0xf3, 0x01, 0x5c,
-      0x5a, 0x11, 0xca, 0x65, 0x3f, 0x28, 0x70, 0x1e,
-      0xdd, 0x4a, 0x7e, 0x0d, 0x23, 0x17, 0x1b, 0xbb },
-    { 0xaf, 0x6b, 0x80, 0x51, 0x47, 0x14, 0x0a, 0x0e,
-      0x41, 0x81, 0xd8, 0x6a, 0x7e, 0x8f, 0x07, 0x69,
-      0xb6, 0x1d, 0x46, 0xd7, 0xb6, 0xfa, 0xc6, 0xe6,
-      0xf9, 0x59, 0x6d, 0xe9, 0x4a, 0xa8, 0xe2, 0xe8 },
-    { 0xb0, 0x5c, 0x14, 0x33, 0x61, 0x75, 0x9b, 0xe1,
-      0x52, 0xfd, 0x76, 0xa5, 0xff, 0xa4, 0x87, 0x2d,
-      0xd4, 0x2e, 0xa0, 0x60, 0xae, 0x40, 0xa3, 0x83,
-      0x13, 0xb7, 0xb5, 0x4a, 0xec, 0x06, 0x73, 0xc2 },
-    { 0xb0, 0xe0, 0xe1, 0x6c, 0x5f, 0x69, 0x1f, 0x66,
-      0xa9, 0x57, 0x3b, 0xd3, 0xcf, 0x43, 0xf9, 0xdf,
-      0xd2, 0xad, 0x3e, 0x56, 0x15, 0x54, 0x63, 0x7f,
-      0x1e, 0x7b, 0x71, 0x91, 0x4d, 0x62, 0x73, 0x38 },
-    { 0xb2, 0xdc, 0x86, 0x25, 0x6c, 0xcf, 0xf4, 0xbb,
-      0x14, 0xfd, 0x70, 0x27, 0x9f, 0xcc, 0x3c, 0xe9,
-      0x25, 0xc5, 0x1f, 0xb7, 0x17, 0xe5, 0x87, 0x6f,
-      0x29, 0x1b, 0xa1, 0x70, 0x73, 0x43, 0x85, 0x68 },
-    { 0xb3, 0x0d, 0x88, 0x44, 0x30, 0x43, 0xf5, 0xf3,
-      0x72, 0x32, 0xbb, 0x9b, 0xac, 0xb9, 0x94, 0xc5,
-      0xba, 0xe9, 0x3a, 0x46, 0xfc, 0x87, 0xf1, 0x51,
-      0x29, 0xc9, 0x74, 0x69, 0xa5, 0x81, 0x4e, 0xca },
-    { 0xb3, 0x1a, 0xf0, 0xc2, 0xe5, 0x1e, 0xa2, 0x1c,
-      0x91, 0x04, 0xf9, 0x4f, 0xaa, 0x66, 0xe0, 0xcc,
-      0xc0, 0x41, 0x34, 0xd5, 0x80, 0x9a, 0x2a, 0x26,
-      0x70, 0xa3, 0xb7, 0xbc, 0x7d, 0xd9, 0x64, 0xf8 },
-    { 0xb3, 0xf4, 0xb1, 0x6f, 0x8e, 0xce, 0xbb, 0x41,
-      0x47, 0x4f, 0x92, 0x4f, 0xee, 0xf9, 0xb0, 0xbd,
-      0x97, 0x9b, 0x36, 0x36, 0xc3, 0x4f, 0xf2, 0x72,
-      0x3f, 0x67, 0x3c, 0x8e, 0xee, 0x2a, 0xf1, 0x52 },
-    { 0xb5, 0xe5, 0xdc, 0xde, 0xcb, 0x8d, 0xeb, 0x27,
-      0x13, 0x4f, 0x02, 0xa5, 0x18, 0x79, 0x43, 0x16,
-      0xf0, 0x8f, 0xaf, 0x9c, 0x2b, 0x1f, 0xda, 0xd6,
-      0xd4, 0x86, 0x61, 0xf5, 0x7e, 0xa6, 0x45, 0xd9 },
-    { 0xb7, 0x06, 0xde, 0x1b, 0xd1, 0xee, 0x2f, 0x4c,
-      0xec, 0x6c, 0xe0, 0x92, 0x02, 0x2b, 0x49, 0x32,
-      0x81, 0xe2, 0x9a, 0x21, 0x73, 0x50, 0x8c, 0x9b,
-      0xd0, 0xfb, 0xc2, 0xc3, 0xd9, 0x68, 0xe3, 0xe7 },
-    { 0xb7, 0xa2, 0xae, 0x06, 0x06, 0xaa, 0x2c, 0xfb,
-      0x27, 0x01, 0xb3, 0xb2, 0x77, 0xf4, 0xd7, 0x12,
-      0x54, 0x70, 0x48, 0x7e, 0xfd, 0x94, 0x05, 0x85,
-      0x7f, 0xfc, 0xe4, 0xbf, 0x29, 0x10, 0x5e, 0x68 },
-    { 0xb8, 0x74, 0x36, 0x95, 0x1c, 0xec, 0x37, 0x7e,
-      0xef, 0x73, 0xde, 0x4b, 0x74, 0xf2, 0x83, 0xc4,
-      0x2b, 0x2c, 0xcb, 0x1c, 0xa3, 0x7c, 0x5b, 0x30,
-      0xaa, 0xd6, 0x55, 0xa7, 0x40, 0x1a, 0x3d, 0x2f },
-    { 0xb9, 0x8d, 0x83, 0x38, 0x55, 0xc3, 0x67, 0x88,
-      0x62, 0xb6, 0x2f, 0x36, 0x50, 0xdb, 0x00, 0xa3,
-      0x45, 0xf4, 0x6a, 0x0e, 0x8e, 0x01, 0x1a, 0x20,
-      0x01, 0x3f, 0xd8, 0xed, 0xce, 0x25, 0x27, 0x0d },
-    { 0xba, 0x51, 0xaf, 0xf5, 0xd5, 0xd3, 0x10, 0x5f,
-      0x34, 0xa2, 0xb3, 0x3a, 0x83, 0xe3, 0xad, 0xfd,
-      0x12, 0xd7, 0x9c, 0xa6, 0x05, 0x90, 0x9d, 0x96,
-      0x03, 0x3e, 0x32, 0xa5, 0xcf, 0x2f, 0x71, 0xf6 },
-    { 0xbb, 0x5c, 0xb3, 0x78, 0xb7, 0xb9, 0x48, 0x7f,
-      0xa6, 0x1b, 0xc0, 0x91, 0x3d, 0xa1, 0xdf, 0x26,
-      0xa1, 0xcf, 0xef, 0xf7, 0x45, 0x2d, 0x9b, 0xa3,
-      0x6c, 0xac, 0x47, 0xa8, 0x5c, 0x7f, 0xf3, 0x48 },
-    { 0xbc, 0x14, 0x2e, 0xba, 0xc2, 0x78, 0xa8, 0xfe,
-      0x8c, 0xa8, 0xbc, 0x2c, 0x62, 0xfb, 0xcc, 0x40,
-      0x17, 0xff, 0x24, 0x96, 0x98, 0xbe, 0xed, 0xfb,
-      0x1e, 0xf3, 0x6f, 0x37, 0x5f, 0xb3, 0x9f, 0x72 },
-    { 0xbd, 0x2e, 0x2f, 0x37, 0xc9, 0x66, 0xc3, 0x86,
-      0xd9, 0x70, 0x44, 0xfd, 0xe3, 0xe3, 0xf9, 0x00,
-      0xfb, 0x1a, 0x0b, 0x04, 0x03, 0xb5, 0x81, 0x72,
-      0x5f, 0x34, 0xe3, 0xc1, 0x90, 0x05, 0x60, 0x56 },
-    { 0xbe, 0xb9, 0x09, 0x0c, 0x92, 0xd1, 0x6b, 0xd0,
-      0x5a, 0xf3, 0x91, 0x5a, 0x39, 0xcc, 0x2a, 0xfa,
-      0x9f, 0x6a, 0x8a, 0x6f, 0xbe, 0xd4, 0xfe, 0x54,
-      0xd9, 0xde, 0x32, 0x49, 0x23, 0xb3, 0x93, 0x5a },
-    { 0xbf, 0x38, 0xe6, 0xae, 0x32, 0x0f, 0x69, 0x16,
-      0x16, 0x0d, 0xa6, 0x06, 0x86, 0x83, 0xbf, 0x49,
-      0xf2, 0xb2, 0x2b, 0x25, 0x24, 0x84, 0x63, 0x68,
-      0xf5, 0x04, 0x51, 0x81, 0x52, 0x40, 0x25, 0x9a },
-    { 0xbf, 0x60, 0xae, 0xb3, 0x91, 0xc0, 0xfb, 0xd0,
-      0x49, 0x53, 0x52, 0x6d, 0xa9, 0xfd, 0x59, 0x96,
-      0x9a, 0x82, 0xf1, 0xee, 0x81, 0xa7, 0x97, 0x98,
-      0xa4, 0x17, 0x1e, 0x14, 0x59, 0x39, 0x19, 0x67 },
-    { 0xbf, 0xf4, 0x3a, 0x97, 0x20, 0x48, 0x2d, 0x13,
-      0x4c, 0xd5, 0xee, 0x8a, 0x88, 0x99, 0xe1, 0xa7,
-      0x36, 0xbf, 0x54, 0xa2, 0xb7, 0x86, 0x26, 0x9c,
-      0x0d, 0xcb, 0x8b, 0xa1, 0x92, 0xa8, 0x1f, 0xa4 },
-    { 0xc0, 0x09, 0xa1, 0xbe, 0x5b, 0xe8, 0xaf, 0xb5,
-      0x25, 0x8e, 0x12, 0x85, 0x5c, 0x64, 0xd0, 0x4d,
-      0x13, 0xe8, 0xcc, 0xc4, 0x7b, 0x02, 0xbf, 0x3b,
-      0x51, 0xc6, 0xe1, 0x18, 0x05, 0xae, 0xec, 0xeb },
-    { 0xc0, 0x9f, 0xfa, 0x0e, 0xdd, 0x16, 0xba, 0x55,
-      0xf2, 0x3c, 0xea, 0xf7, 0x2b, 0x11, 0x34, 0xe9,
-      0x28, 0xdb, 0xa1, 0xc2, 0x34, 0x5a, 0x5a, 0xb5,
-      0x63, 0x1e, 0x25, 0x41, 0x24, 0x05, 0x4a, 0xdb },
-    { 0xc0, 0xab, 0xd1, 0xc3, 0x56, 0x2f, 0xbc, 0x7f,
-      0xf7, 0xbd, 0x38, 0x95, 0x54, 0x60, 0xc3, 0xfc,
-      0x43, 0x55, 0x0d, 0x97, 0x7f, 0x25, 0xe3, 0x43,
-      0xd4, 0x9c, 0xd4, 0xaf, 0xad, 0xf2, 0x09, 0x3c },
-    { 0xc0, 0xfe, 0xb7, 0x2a, 0x5f, 0x33, 0x16, 0x5c,
-      0x0d, 0xc7, 0xc4, 0x24, 0x7e, 0x23, 0xf3, 0x8c,
-      0xc6, 0x1f, 0x25, 0x24, 0x42, 0xb2, 0xf6, 0x13,
-      0x40, 0x92, 0xde, 0x3b, 0xad, 0x7e, 0x45, 0x0d },
-    { 0xc1, 0x77, 0x12, 0x97, 0xa4, 0xe8, 0xdc, 0x53,
-      0x75, 0x19, 0x5e, 0x1b, 0x63, 0x04, 0x2b, 0x59,
-      0x19, 0x09, 0xf1, 0xd7, 0xeb, 0x5d, 0x25, 0xf2,
-      0x97, 0xae, 0x7a, 0x61, 0xc1, 0x53, 0x8f, 0x9e },
-    { 0xc1, 0x86, 0xbe, 0x26, 0xe4, 0x47, 0x89, 0x7c,
-      0x48, 0x3c, 0x43, 0xfd, 0xc0, 0x86, 0xe2, 0x60,
-      0x74, 0x17, 0xeb, 0x3e, 0xa7, 0x88, 0xec, 0x03,
-      0x10, 0xa7, 0x9d, 0xa9, 0x24, 0x1d, 0x16, 0xde },
-    { 0xc1, 0xde, 0x5f, 0xa3, 0x92, 0x13, 0x68, 0x58,
-      0x11, 0xa5, 0xba, 0x93, 0x12, 0x1d, 0xe7, 0xa3,
-      0x95, 0x98, 0x4e, 0x84, 0x44, 0x4e, 0x58, 0xf1,
-      0x63, 0xb7, 0xa6, 0x20, 0xae, 0x3b, 0xbf, 0xa8 },
-    { 0xc2, 0xad, 0xdf, 0x99, 0xcf, 0xc4, 0x2c, 0xe0,
-      0xe5, 0xa0, 0x93, 0xbc, 0xbf, 0x87, 0x40, 0x7c,
-      0x61, 0x1f, 0x9d, 0x0a, 0xbf, 0x2a, 0x35, 0xd6,
-      0xe8, 0x03, 0xa3, 0x8e, 0xcb, 0x92, 0xc7, 0xb3 },
-    { 0xc2, 0xe7, 0x92, 0x11, 0x6a, 0x05, 0x00, 0x00,
-      0xbd, 0x47, 0x59, 0x1d, 0x93, 0x04, 0x71, 0xe6,
-      0x17, 0x4c, 0x93, 0x85, 0xf5, 0xdc, 0x32, 0xb7,
-      0x62, 0x31, 0x65, 0x5f, 0xc8, 0x5e, 0x22, 0xe2 },
-    { 0xc3, 0x79, 0x03, 0xc5, 0x3a, 0xe6, 0x02, 0xec,
-      0x96, 0x9e, 0xc3, 0x3f, 0x63, 0xfe, 0x9a, 0xb2,
-      0x0c, 0x39, 0x5f, 0x83, 0x0d, 0x30, 0xe4, 0xee,
-      0x9d, 0x8d, 0xd9, 0x05, 0x92, 0x1e, 0xc1, 0xa0 },
-    { 0xc3, 0xcf, 0x54, 0x16, 0xa5, 0x31, 0xaf, 0x4b,
-      0xfa, 0xe8, 0x9c, 0x45, 0x14, 0x3f, 0x20, 0xcc,
-      0x1b, 0x3e, 0x18, 0x1d, 0x29, 0xc2, 0xd0, 0xe8,
-      0xff, 0x7d, 0x3f, 0x2a, 0x66, 0xb1, 0x82, 0xfe },
-    { 0xc4, 0x98, 0xa1, 0xb6, 0x9f, 0x54, 0x40, 0x86,
-      0x17, 0x47, 0x47, 0x71, 0x5a, 0x27, 0x4d, 0x3f,
-      0xb5, 0x90, 0x19, 0xbe, 0x09, 0x21, 0x31, 0xbc,
-      0xfa, 0xa8, 0x3a, 0x39, 0x5f, 0x7e, 0x57, 0x3c },
-    { 0xc4, 0xe2, 0x8d, 0xd8, 0x3f, 0xe3, 0x0c, 0x96,
-      0x33, 0x8c, 0xef, 0x77, 0x73, 0xc6, 0xdf, 0xca,
-      0x6c, 0xe4, 0xfa, 0x96, 0x41, 0xbe, 0xab, 0x38,
-      0x05, 0xa8, 0xef, 0xb6, 0xcd, 0xc3, 0xcf, 0x0a },
-    { 0xc5, 0x00, 0xb8, 0x3f, 0x3e, 0x06, 0x6c, 0xd1,
-      0xdd, 0x0e, 0xbc, 0xd7, 0x3d, 0xd4, 0x01, 0x61,
-      0xb9, 0x25, 0x9a, 0xa7, 0x7a, 0xb8, 0xa6, 0x47,
-      0xe8, 0x57, 0x1f, 0xf3, 0x37, 0xcf, 0x94, 0x6d },
-    { 0xc5, 0x29, 0x5b, 0xa6, 0xe2, 0x7e, 0x72, 0x10,
-      0x22, 0xfe, 0xb2, 0x1e, 0x78, 0xeb, 0x7b, 0x03,
-      0x57, 0xc9, 0xcd, 0x56, 0x5b, 0xd0, 0xe5, 0x96,
-      0x72, 0xf6, 0x66, 0x34, 0x2b, 0x79, 0x94, 0x9d },
-    { 0xc6, 0x12, 0x75, 0x6b, 0xa5, 0x42, 0x34, 0x4a,
-      0xdc, 0x1b, 0x80, 0xe9, 0x38, 0x84, 0x5a, 0x1e,
-      0xd6, 0xe9, 0x38, 0xfe, 0xf4, 0x0d, 0x04, 0xec,
-      0x86, 0x55, 0x8f, 0x4b, 0x21, 0x05, 0x2f, 0xd2 },
-    { 0xc6, 0x17, 0xe0, 0x85, 0x5b, 0xf1, 0x4f, 0xbf,
-      0x21, 0xaf, 0x00, 0x82, 0x25, 0xca, 0xbe, 0x40,
-      0x4f, 0x73, 0x8c, 0x27, 0x8a, 0x4a, 0x42, 0x87,
-      0xf1, 0xee, 0x38, 0x01, 0x27, 0xc5, 0x61, 0xfa },
-    { 0xc6, 0xa4, 0x24, 0xbf, 0x7c, 0xfe, 0x31, 0x72,
-      0x74, 0x7a, 0x47, 0x14, 0xa0, 0xef, 0xb9, 0x17,
-      0x93, 0x8c, 0x5e, 0xbd, 0x59, 0x12, 0x9d, 0xed,
-      0x7a, 0x81, 0x18, 0xc7, 0xf6, 0x59, 0xd1, 0x33 },
-    { 0xc6, 0xad, 0x1d, 0x7a, 0x14, 0x1a, 0x91, 0x75,
-      0x2d, 0x31, 0xfb, 0xc1, 0x06, 0x16, 0xbf, 0x1c,
-      0xa2, 0xfb, 0x5b, 0x02, 0xe8, 0x46, 0xb5, 0x9e,
-      0x63, 0x34, 0x6b, 0x31, 0x92, 0xa7, 0x52, 0x92 },
-    { 0xc7, 0x01, 0x83, 0x64, 0x38, 0xf3, 0x7b, 0xea,
-      0x8a, 0x88, 0x16, 0x10, 0x63, 0x70, 0x86, 0xf8,
-      0x8d, 0x9a, 0x11, 0x5e, 0x00, 0x92, 0x46, 0xd2,
-      0x7f, 0x48, 0x9f, 0xa7, 0x18, 0x51, 0x88, 0xa8 },
-    { 0xc7, 0xff, 0x8e, 0xfd, 0xec, 0xdf, 0x00, 0xd1,
-      0xfc, 0x8d, 0x55, 0x2d, 0x2a, 0x70, 0x70, 0xe5,
-      0xe3, 0x3d, 0x42, 0xe5, 0x90, 0xf5, 0x86, 0xc6,
-      0xae, 0xde, 0x03, 0x2b, 0x2d, 0x86, 0x7b, 0xd5 },
-    { 0xc7, 0xff, 0xb4, 0x9f, 0xbc, 0x94, 0x72, 0x24,
-      0x5c, 0x8e, 0x95, 0xde, 0x62, 0x9a, 0xf5, 0xc1,
-      0xbf, 0xea, 0xc5, 0x50, 0x04, 0xc1, 0x54, 0x82,
-      0x3a, 0x58, 0xba, 0xe8, 0x05, 0x6e, 0x3c, 0x64 },
-    { 0xc8, 0x37, 0xd6, 0xf2, 0xab, 0x14, 0x79, 0x91,
-      0x42, 0xed, 0x3c, 0x79, 0xbe, 0xd9, 0x44, 0x1e,
-      0x92, 0x50, 0xbd, 0x05, 0x20, 0x25, 0xad, 0x8a,
-      0xf4, 0x40, 0x41, 0xac, 0x19, 0xef, 0xbb, 0x4c },
-    { 0xc9, 0x72, 0xf4, 0xf9, 0x6e, 0x71, 0x33, 0xe1,
-      0x6e, 0x55, 0x57, 0xa0, 0x57, 0xb1, 0xd4, 0x2b,
-      0xa9, 0x2d, 0x98, 0x5c, 0xae, 0xe7, 0x3c, 0xaf,
-      0xda, 0xeb, 0x55, 0xec, 0xa2, 0xe4, 0xab, 0xb0 },
-    { 0xc9, 0x78, 0x37, 0x2c, 0x9e, 0x11, 0x60, 0x71,
-      0xb6, 0x1b, 0x90, 0x92, 0xa9, 0xaa, 0x96, 0x81,
-      0x62, 0x36, 0x55, 0xa6, 0x6f, 0x4f, 0xcb, 0xc4,
-      0xd3, 0xa6, 0x7e, 0xfd, 0x56, 0x72, 0x48, 0x30 },
-    { 0xca, 0x55, 0x6f, 0x82, 0xc9, 0x68, 0x4c, 0x9a,
-      0xf3, 0x55, 0x7d, 0x3e, 0x2d, 0x88, 0xaf, 0x92,
-      0xed, 0x25, 0x9c, 0x20, 0xff, 0xd1, 0xdd, 0xe9,
-      0xf7, 0x9d, 0x6b, 0x92, 0xc6, 0x1e, 0xe1, 0xb9 },
-    { 0xca, 0xbe, 0x25, 0x56, 0xf1, 0xbb, 0x56, 0x57,
-      0x0c, 0xef, 0x3a, 0x87, 0x03, 0x32, 0x71, 0xa1,
-      0xf2, 0x1d, 0x09, 0xb7, 0xfd, 0x04, 0x12, 0x83,
-      0x18, 0xe5, 0xe7, 0xbc, 0xe3, 0xa2, 0x01, 0xe2 },
-    { 0xca, 0xdc, 0xd5, 0xae, 0x1b, 0x75, 0x6a, 0xb7,
-      0x41, 0xb3, 0x56, 0x9c, 0x42, 0xa5, 0x41, 0x1f,
-      0x09, 0x3e, 0x4e, 0x1f, 0x01, 0x2e, 0xc5, 0x79,
-      0x91, 0xcb, 0xd6, 0xdb, 0xe0, 0x8f, 0xaa, 0xc1 },
-    { 0xcb, 0x7a, 0x43, 0x8d, 0x16, 0xe4, 0xa5, 0xf3,
-      0xc5, 0x6f, 0xdf, 0x19, 0x1e, 0x1d, 0xaf, 0x9f,
-      0x32, 0x5c, 0x65, 0x0b, 0xd6, 0x2f, 0x07, 0xc4,
-      0x67, 0x71, 0x72, 0x07, 0x35, 0x1a, 0xe3, 0x29 },
-    { 0xcc, 0x30, 0xd8, 0x19, 0xde, 0x54, 0x05, 0xf6,
-      0x49, 0xc8, 0xb7, 0xa8, 0x14, 0x8f, 0x26, 0xd7,
-      0x71, 0x08, 0x3e, 0xc5, 0x18, 0xf9, 0xb6, 0x6f,
-      0xf5, 0x47, 0xf2, 0x82, 0x2d, 0x11, 0x93, 0x6d },
-    { 0xcc, 0x65, 0xcd, 0xc5, 0x33, 0x62, 0xd4, 0x21,
-      0x62, 0x7e, 0xae, 0xf5, 0xd0, 0xc8, 0xe4, 0xc4,
-      0xe2, 0x40, 0xad, 0xe0, 0xc9, 0xd4, 0x20, 0xbe,
-      0x67, 0x1e, 0x70, 0xf0, 0xfb, 0xac, 0x8d, 0x0a },
-    { 0xcd, 0xb1, 0x62, 0x53, 0xd2, 0x2e, 0xd5, 0xd4,
-      0x26, 0xcf, 0xa1, 0xb0, 0x5c, 0xec, 0xd8, 0x6e,
-      0xf1, 0xb7, 0xde, 0xaa, 0x07, 0xc5, 0x70, 0x5e,
-      0xbb, 0xaf, 0x7d, 0x9a, 0x80, 0x7d, 0x56, 0x16 },
-    { 0xcd, 0xc0, 0x39, 0xf3, 0xa2, 0xd1, 0xbb, 0xa5,
-      0xe8, 0x09, 0x4e, 0x55, 0x23, 0xcf, 0x60, 0x47,
-      0x09, 0x7d, 0x4b, 0x3c, 0xd4, 0xec, 0x4e, 0xd6,
-      0xaa, 0x8e, 0xb7, 0xb4, 0xd8, 0xb5, 0x77, 0x7d },
-    { 0xcd, 0xc4, 0xea, 0x92, 0x02, 0xe3, 0x3e, 0xdd,
-      0x0f, 0x2d, 0x3a, 0xe8, 0x6a, 0xca, 0xc7, 0xfb,
-      0x25, 0x35, 0x4b, 0x02, 0x23, 0x5b, 0x09, 0x33,
-      0xaa, 0x81, 0xa3, 0x13, 0xb5, 0xfd, 0xfe, 0xec },
-    { 0xce, 0x4c, 0x2f, 0x8f, 0x16, 0x46, 0x8a, 0x58,
-      0x88, 0xe9, 0x0f, 0x73, 0x4e, 0x4d, 0x22, 0x02,
-      0xdf, 0xad, 0xbf, 0xa6, 0x6f, 0x5b, 0x35, 0x75,
-      0x2b, 0xaa, 0x76, 0x21, 0xa7, 0x60, 0xb0, 0x88 },
-    { 0xce, 0x81, 0x44, 0x58, 0x54, 0x03, 0x1f, 0x3d,
-      0x0f, 0x5c, 0x88, 0x75, 0x46, 0x4d, 0xcd, 0x5b,
-      0xa6, 0xc8, 0x90, 0xf4, 0x49, 0xb3, 0x20, 0x7b,
-      0xca, 0x2b, 0xc9, 0x61, 0x82, 0x2d, 0x27, 0xc4 },
-    { 0xcf, 0xa0, 0xc0, 0x0c, 0xb2, 0xfb, 0x4b, 0x85,
-      0x7a, 0xad, 0x22, 0xb1, 0x3a, 0x90, 0xe3, 0x46,
-      0xa0, 0x3e, 0x6b, 0x79, 0xab, 0xd5, 0xd2, 0x75,
-      0xb5, 0x43, 0x24, 0x68, 0x17, 0x92, 0xd6, 0xd1 },
-    { 0xd0, 0xf5, 0x93, 0xc1, 0xa8, 0x1b, 0x1e, 0xf8,
-      0x51, 0x69, 0x81, 0xee, 0x56, 0xf1, 0xd5, 0x98,
-      0xa2, 0xa6, 0x03, 0x48, 0x8c, 0x67, 0x8c, 0x1b,
-      0x7b, 0xbe, 0xa6, 0x44, 0x6b, 0x00, 0x83, 0xad },
-    { 0xd2, 0x90, 0x3c, 0xa2, 0x55, 0x17, 0x27, 0xed,
-      0x01, 0x71, 0xcc, 0x4a, 0x43, 0xb3, 0xca, 0xe0,
-      0x09, 0xb7, 0x47, 0xb9, 0xf4, 0xf8, 0x48, 0x72,
-      0x92, 0x27, 0xbf, 0x59, 0x02, 0xf2, 0x3e, 0x47 },
-    { 0xd2, 0xe8, 0xa1, 0x23, 0x7a, 0x93, 0xf5, 0x78,
-      0xd1, 0xba, 0x8f, 0x09, 0xe4, 0xff, 0x10, 0x7b,
-      0x62, 0x35, 0x78, 0x85, 0x42, 0xaa, 0x61, 0x83,
-      0xd1, 0x76, 0xdb, 0xf1, 0xc8, 0x8d, 0xcf, 0xb6 },
-    { 0xd5, 0x04, 0x88, 0x96, 0x86, 0x07, 0x29, 0xa8,
-      0xfa, 0x5d, 0x23, 0x57, 0x81, 0x2b, 0xa5, 0x6c,
-      0xbe, 0x84, 0xc9, 0xab, 0x7d, 0x14, 0xdf, 0x47,
-      0x64, 0xe0, 0xb6, 0x62, 0x0f, 0xa3, 0x20, 0x10 },
-    { 0xd5, 0x41, 0xa7, 0x7e, 0x13, 0x6e, 0x9e, 0x70,
-      0x3b, 0xb9, 0x9f, 0x80, 0x68, 0xcf, 0xee, 0x86,
-      0xa4, 0xb9, 0xf0, 0x89, 0xe0, 0x2d, 0x0c, 0x6c,
-      0xb6, 0xd4, 0xa3, 0x94, 0x6c, 0x6b, 0x16, 0x7a },
-    { 0xd5, 0x83, 0x94, 0x96, 0xcd, 0xc8, 0x5b, 0xe3,
-      0xd1, 0xf1, 0xac, 0x65, 0x2e, 0xfa, 0x92, 0xbe,
-      0xa3, 0xb0, 0x61, 0xc1, 0x3d, 0xad, 0x5a, 0x82,
-      0x11, 0x22, 0xcf, 0xe9, 0xc7, 0x1a, 0x5a, 0x32 },
-    { 0xd5, 0xa4, 0xee, 0x46, 0x95, 0xb5, 0x65, 0xa6,
-      0x7e, 0x50, 0x48, 0x66, 0xfe, 0x5b, 0xa3, 0xc0,
-      0xed, 0xca, 0xee, 0xd5, 0x2a, 0xd0, 0xaf, 0x07,
-      0xe6, 0x79, 0x17, 0x73, 0x85, 0x12, 0xc8, 0xf5 },
-    { 0xd6, 0x25, 0xc0, 0x59, 0x2b, 0x25, 0xdc, 0x03,
-      0xaa, 0x7e, 0x87, 0x8e, 0x6a, 0x85, 0x09, 0x1b,
-      0xaa, 0x07, 0x8d, 0x26, 0x8b, 0xbd, 0xb4, 0x9f,
-      0x09, 0x67, 0x94, 0x08, 0x61, 0x2d, 0x1e, 0xfe },
-    { 0xd6, 0xd1, 0xb3, 0x5c, 0xbc, 0x12, 0xfb, 0x1c,
-      0x70, 0xa0, 0xb4, 0x3b, 0xa5, 0x9a, 0xb3, 0xd3,
-      0x22, 0x5f, 0x37, 0x32, 0x64, 0xdd, 0x87, 0xfb,
-      0xca, 0x00, 0x61, 0xec, 0x1c, 0x4d, 0xa1, 0x1a },
-    { 0xd7, 0x32, 0x49, 0x74, 0xb5, 0x60, 0x09, 0x62,
-      0x17, 0x61, 0xf7, 0xc0, 0xff, 0x68, 0x9d, 0xde,
-      0x47, 0x74, 0x99, 0x85, 0xe1, 0xee, 0x8b, 0x5c,
-      0x89, 0x61, 0xdd, 0x8f, 0x6a, 0x78, 0xbb, 0xf5 },
-    { 0xd9, 0x2e, 0x3e, 0xe3, 0x82, 0xc8, 0xdc, 0xaf,
-      0xa0, 0x39, 0x3d, 0x9f, 0x9a, 0x00, 0xbf, 0x4c,
-      0xd9, 0xd5, 0x64, 0x26, 0x2b, 0x18, 0x0f, 0x68,
-      0x16, 0x0b, 0x20, 0x34, 0xc5, 0x44, 0xd1, 0x0a },
-    { 0xd9, 0x65, 0xf7, 0x41, 0x62, 0x04, 0xda, 0x83,
-      0x1a, 0xf6, 0x6b, 0xfa, 0x8f, 0x90, 0xd1, 0x41,
-      0xe9, 0x93, 0xf0, 0x00, 0x21, 0x33, 0xf2, 0x8d,
-      0xe9, 0x7f, 0x56, 0x4a, 0x1d, 0x60, 0x4e, 0xcc },
-    { 0xda, 0xdf, 0x97, 0x13, 0x34, 0x14, 0xad, 0x51,
-      0x3f, 0xc7, 0x50, 0x14, 0xe9, 0x56, 0x65, 0xda,
-      0xd7, 0x76, 0xb1, 0x50, 0x4b, 0x15, 0x67, 0x43,
-      0x4f, 0xd8, 0x2a, 0x79, 0xa2, 0x20, 0xe9, 0xa1 },
-    { 0xda, 0xff, 0xd4, 0x05, 0x6f, 0xc3, 0x68, 0xfa,
-      0x64, 0x8d, 0x0e, 0xd8, 0x9b, 0x5d, 0xe0, 0xee,
-      0x93, 0x1f, 0x1b, 0x33, 0x84, 0x78, 0xab, 0xf5,
-      0x69, 0x29, 0xa9, 0x4d, 0x3b, 0xd6, 0x1d, 0x46 },
-    { 0xde, 0xcd, 0xb9, 0xfc, 0x1d, 0xde, 0xc9, 0x7e,
-      0x09, 0xc3, 0x02, 0x6a, 0xce, 0xb7, 0x6b, 0xda,
-      0xe9, 0xde, 0xb6, 0x62, 0x75, 0x1d, 0xda, 0x34,
-      0x9d, 0x2f, 0xa6, 0xbd, 0x75, 0xca, 0x59, 0x14 },
-    { 0xde, 0xd1, 0x9a, 0xd5, 0xde, 0x99, 0x65, 0xd9,
-      0x22, 0x5c, 0x1b, 0xba, 0x5f, 0xb4, 0xd8, 0x90,
-      0xc8, 0xe5, 0xc0, 0x35, 0xe4, 0x85, 0x27, 0x52,
-      0xb6, 0x69, 0xb0, 0x40, 0x0f, 0x24, 0xf1, 0x74 },
-    { 0xdf, 0x30, 0xbf, 0x8d, 0x1b, 0xf9, 0x37, 0x8e,
-      0x43, 0x3e, 0xf9, 0xe1, 0xb3, 0xa2, 0x28, 0xa0,
-      0x7e, 0x36, 0x58, 0xa5, 0xbc, 0x43, 0x88, 0x23,
-      0x45, 0x4d, 0xb0, 0x6a, 0x67, 0x94, 0x4c, 0x6e },
-    { 0xe0, 0x0b, 0xd7, 0x86, 0xd1, 0xf2, 0xf4, 0x46,
-      0xc4, 0xba, 0x83, 0x99, 0xd4, 0xd8, 0xd5, 0xa0,
-      0xd1, 0x98, 0x57, 0x8f, 0x42, 0x99, 0xfd, 0xfd,
-      0xaf, 0xf7, 0x8c, 0x3f, 0x67, 0x71, 0xf3, 0x94 },
-    { 0xe0, 0x8b, 0x2c, 0xc2, 0x7a, 0xe8, 0xe2, 0xef,
-      0x1a, 0x33, 0x01, 0x7a, 0x9a, 0xc2, 0x5d, 0xda,
-      0xfb, 0x5e, 0xa1, 0x12, 0xc9, 0x56, 0xb0, 0x02,
-      0xfe, 0x6c, 0x79, 0x80, 0x14, 0xaa, 0x90, 0x65 },
-    { 0xe1, 0xb2, 0xe8, 0x6b, 0x0d, 0xa8, 0x69, 0xe9,
-      0x25, 0x26, 0x6c, 0x1b, 0x56, 0x88, 0x34, 0x5a,
-      0x17, 0xb0, 0xf6, 0xe2, 0xa2, 0x14, 0x94, 0x54,
-      0x7e, 0xac, 0x09, 0x7c, 0x8b, 0xf5, 0x3c, 0x5a },
-    { 0xe1, 0xd6, 0x44, 0xa0, 0x96, 0xbd, 0x8a, 0x6c,
-      0xac, 0xbb, 0xda, 0x3e, 0x7f, 0xc3, 0x38, 0xea,
-      0xdd, 0xc1, 0x2f, 0x23, 0x6c, 0x72, 0x61, 0xe4,
-      0x5f, 0x8a, 0xd2, 0xd8, 0x42, 0x42, 0x4f, 0x72 },
-    { 0xe2, 0x24, 0x10, 0xb5, 0xa6, 0x7f, 0xed, 0xc2,
-      0x64, 0x69, 0x4c, 0x44, 0x9d, 0x84, 0xfa, 0x1a,
-      0x02, 0xbc, 0x8b, 0x21, 0x28, 0xc1, 0x25, 0x60,
-      0x71, 0x58, 0xc9, 0x1b, 0x05, 0x38, 0x6c, 0x6a },
-    { 0xe2, 0xa8, 0x47, 0xc3, 0xf0, 0x9b, 0xeb, 0x6f,
-      0x05, 0x68, 0x6f, 0x17, 0x79, 0x1b, 0x05, 0xf1,
-      0xfe, 0x25, 0xf7, 0x71, 0x86, 0x9c, 0x42, 0x63,
-      0xa5, 0x5b, 0x94, 0x18, 0x77, 0xe4, 0x79, 0x04 },
-    { 0xe2, 0xf3, 0x9a, 0x9d, 0x48, 0xa3, 0x22, 0x10,
-      0x55, 0xb3, 0xc8, 0xa3, 0xeb, 0x14, 0x39, 0xd6,
-      0xb8, 0x73, 0x01, 0x3e, 0xe4, 0xd0, 0x97, 0x12,
-      0x20, 0x64, 0xf2, 0x7e, 0xc0, 0x3d, 0xd4, 0xda },
-    { 0xe2, 0xf5, 0xde, 0x57, 0xcd, 0x67, 0x24, 0x9a,
-      0x7e, 0x1f, 0x45, 0x5b, 0x85, 0xc0, 0x6f, 0x0d,
-      0x80, 0x9e, 0x75, 0xa5, 0x5c, 0x6b, 0x05, 0x48,
-      0x16, 0xe0, 0x19, 0x89, 0x9a, 0x3a, 0x02, 0xff },
-    { 0xe4, 0xf1, 0xde, 0x31, 0xcd, 0xaa, 0x6d, 0x9e,
-      0xb1, 0xaa, 0xfd, 0x10, 0x81, 0x27, 0xa2, 0xf0,
-      0xa8, 0xfb, 0x6d, 0xa8, 0x5a, 0x04, 0x14, 0xad,
-      0x24, 0x99, 0x47, 0xc4, 0x8d, 0x24, 0x92, 0xc5 },
-    { 0xe6, 0x44, 0xd1, 0x1c, 0x37, 0x07, 0x0f, 0x89,
-      0x69, 0x33, 0x08, 0x17, 0x8d, 0x6b, 0xe4, 0x95,
-      0x94, 0x96, 0x92, 0xc1, 0xfb, 0xeb, 0x30, 0xed,
-      0x32, 0x9b, 0x74, 0x02, 0x7f, 0xcf, 0xfd, 0x48 },
-    { 0xe6, 0xb0, 0xf2, 0xe2, 0x5b, 0xd5, 0x16, 0xe4,
-      0xbb, 0xa3, 0x7a, 0x2b, 0xf2, 0xe2, 0xc7, 0x2a,
-      0x1e, 0x53, 0x9c, 0x60, 0x30, 0xf3, 0xcf, 0x9b,
-      0xbe, 0x5e, 0x79, 0x72, 0x8d, 0x68, 0x64, 0x78 },
-    { 0xe6, 0xe5, 0x4d, 0xe7, 0xb4, 0x97, 0x54, 0xd3,
-      0x57, 0xb0, 0xa8, 0xd9, 0x4a, 0x4d, 0x4f, 0x80,
-      0xac, 0xd1, 0x99, 0x4c, 0xcc, 0x1c, 0x99, 0x08,
-      0xe9, 0xf0, 0xd9, 0x21, 0xe4, 0x28, 0xb8, 0x38 },
-    { 0xe7, 0x0c, 0xbb, 0x7a, 0xf7, 0xaa, 0x20, 0xb9,
-      0x89, 0x0b, 0xc1, 0xf9, 0xfa, 0x00, 0xd8, 0x09,
-      0x0b, 0x5a, 0xc9, 0x82, 0x5e, 0xa9, 0xd2, 0xfd,
-      0xf7, 0x7c, 0xa4, 0xda, 0xe9, 0x44, 0x51, 0xb2 },
-    { 0xe8, 0x16, 0xf9, 0x92, 0x94, 0xa1, 0x3a, 0xc2,
-      0xfa, 0x2b, 0xfb, 0x76, 0xc2, 0x2d, 0xfa, 0x71,
-      0xbc, 0x3d, 0xa4, 0x8f, 0x67, 0x1e, 0xf7, 0x7c,
-      0x00, 0xaa, 0x8e, 0x45, 0x9b, 0x7c, 0xc8, 0x2a },
-    { 0xe9, 0xd4, 0x98, 0x51, 0xbf, 0x78, 0x37, 0x6d,
-      0x54, 0x08, 0x2d, 0x1e, 0xb8, 0x2b, 0xd2, 0xdc,
-      0x96, 0x82, 0x07, 0x09, 0xb7, 0x77, 0x2d, 0x3f,
-      0xbc, 0xa3, 0x90, 0x08, 0x8b, 0x54, 0xc4, 0x53 },
-    { 0xe9, 0xf5, 0x71, 0xc7, 0x71, 0x64, 0xab, 0xea,
-      0xe1, 0x85, 0x28, 0x37, 0x5c, 0xfd, 0xc7, 0x21,
-      0x9a, 0x6b, 0xde, 0x46, 0x1b, 0x19, 0x73, 0xbe,
-      0x2b, 0xb8, 0xbd, 0xf0, 0xda, 0x78, 0xb2, 0xb4 },
-    { 0xeb, 0x11, 0x63, 0xaa, 0xef, 0xe8, 0xfd, 0x88,
-      0xe1, 0x32, 0x7b, 0x48, 0xa9, 0xc0, 0x06, 0x2e,
-      0x06, 0xf0, 0xa6, 0xea, 0xa0, 0xa0, 0x18, 0x24,
-      0x7f, 0x9f, 0xa4, 0xe3, 0x4e, 0x3a, 0x47, 0x4c },
-    { 0xec, 0x4b, 0xbd, 0xeb, 0x15, 0x12, 0x1d, 0x96,
-      0x76, 0x4d, 0x6c, 0x01, 0xb2, 0x7e, 0xd5, 0xae,
-      0x86, 0x46, 0x5c, 0x46, 0xd5, 0xa4, 0x0e, 0x34,
-      0xae, 0xfc, 0x09, 0x2d, 0x3e, 0x8b, 0xb1, 0x76 },
-    { 0xec, 0x5f, 0xa4, 0x73, 0x12, 0x1e, 0x3f, 0x49,
-      0xf0, 0x95, 0x3a, 0x2a, 0x91, 0x83, 0x39, 0xe3,
-      0x6f, 0x3c, 0xb6, 0xb8, 0xd8, 0xb8, 0x9e, 0x91,
-      0x74, 0x23, 0xda, 0xce, 0xac, 0xe6, 0xd5, 0x8a },
-    { 0xec, 0xce, 0x4e, 0x52, 0x82, 0xfd, 0x2e, 0xe0,
-      0x03, 0xa4, 0x03, 0x2c, 0x80, 0xd3, 0x32, 0x1a,
-      0x69, 0x47, 0x25, 0x98, 0x94, 0x59, 0x09, 0xcb,
-      0x25, 0x55, 0x7a, 0xa8, 0x47, 0x74, 0x2d, 0xdf },
-    { 0xed, 0x5b, 0xb8, 0x6a, 0x95, 0xa5, 0xfe, 0x2b,
-      0x17, 0x08, 0xf2, 0x56, 0x75, 0x4a, 0x89, 0xc4,
-      0x29, 0x67, 0x9b, 0x30, 0x75, 0x8e, 0xe0, 0x12,
-      0x2b, 0x9e, 0x50, 0x85, 0x8d, 0xe2, 0x10, 0x4b },
-    { 0xed, 0xc1, 0xbf, 0x3e, 0xfb, 0xf7, 0xe1, 0xd9,
-      0x5e, 0x19, 0xc5, 0x5e, 0xca, 0xe7, 0x7e, 0x83,
-      0x69, 0x46, 0xab, 0x0a, 0x26, 0xa7, 0x8e, 0x32,
-      0xa4, 0x72, 0xc9, 0xd3, 0x6c, 0x69, 0xce, 0xcd },
-    { 0xed, 0xf4, 0xdf, 0x97, 0x2c, 0xad, 0x6c, 0x47,
-      0x0b, 0xab, 0x5d, 0x66, 0x42, 0xf6, 0x60, 0xb8,
-      0x42, 0xd6, 0xc9, 0x73, 0x07, 0x44, 0x93, 0xe4,
-      0xef, 0x1b, 0xbf, 0x31, 0x1a, 0x92, 0x79, 0x95 },
-    { 0xee, 0x34, 0xe1, 0xa1, 0x9b, 0xc8, 0x89, 0xf8,
-      0x5f, 0x7f, 0x0f, 0x5b, 0xf8, 0x72, 0xb1, 0xac,
-      0x56, 0x5e, 0xc6, 0xf1, 0x9d, 0xb5, 0x17, 0xba,
-      0x4e, 0xd7, 0x55, 0xc4, 0x18, 0x5f, 0x69, 0xe8 },
-    { 0xef, 0x36, 0xa2, 0x29, 0x89, 0x65, 0xe4, 0x98,
-      0x84, 0x59, 0xb9, 0x21, 0x6a, 0xb3, 0x3c, 0x3c,
-      0xa8, 0x42, 0xd2, 0x16, 0x83, 0xb6, 0x2a, 0x2b,
-      0xf1, 0x53, 0x0d, 0x30, 0xb0, 0xae, 0x78, 0x25 },
-    { 0xef, 0xaf, 0xca, 0x84, 0x90, 0x30, 0x7b, 0x0f,
-      0x62, 0x2b, 0xf4, 0x3a, 0x0e, 0xb3, 0xc5, 0x1a,
-      0xcb, 0xdd, 0xde, 0xdc, 0x23, 0x92, 0xf1, 0x61,
-      0xac, 0xed, 0x16, 0x71, 0xa6, 0x53, 0x60, 0x7e },
-    { 0xef, 0xd1, 0xe0, 0xe7, 0x3f, 0xa8, 0x71, 0x00,
-      0xb7, 0x6a, 0x93, 0x23, 0x49, 0xc4, 0x5d, 0x09,
-      0xb2, 0x8b, 0x2d, 0x8a, 0x00, 0x17, 0x19, 0xa5,
-      0x8d, 0xfa, 0xcc, 0x74, 0x84, 0xc7, 0xcf, 0x42 },
-    { 0xf0, 0x6b, 0x35, 0x95, 0x36, 0xd1, 0x34, 0x32,
-      0x8b, 0x36, 0x00, 0x4d, 0xa9, 0xa9, 0x19, 0x0c,
-      0x3a, 0x76, 0x69, 0xe8, 0x27, 0x8d, 0xb9, 0xf7,
-      0x58, 0x57, 0xc4, 0x8d, 0x64, 0x4b, 0xe2, 0x03 },
-    { 0xf0, 0xcf, 0xc7, 0x79, 0x13, 0x39, 0x7d, 0xe2,
-      0x38, 0xed, 0xb5, 0x9f, 0x0f, 0x99, 0x23, 0xc6,
-      0xd4, 0x11, 0x0a, 0x4b, 0x3a, 0xc8, 0xac, 0x76,
-      0x55, 0x6a, 0x0c, 0x92, 0x44, 0xf0, 0x3f, 0xc1 },
-    { 0xf2, 0xb1, 0x95, 0x84, 0x6e, 0xe2, 0xb9, 0xab,
-      0x5f, 0x18, 0xe6, 0x80, 0x21, 0xf8, 0xdf, 0x7c,
-      0x0b, 0x60, 0x58, 0xde, 0xde, 0x86, 0xc5, 0xd5,
-      0x90, 0xf2, 0xe8, 0x64, 0x3a, 0xfe, 0x04, 0x52 },
-    { 0xf2, 0xe5, 0x30, 0x0c, 0x39, 0xf2, 0x86, 0xc6,
-      0x78, 0x99, 0x90, 0x9c, 0x7c, 0xe7, 0x35, 0x9b,
-      0x09, 0x45, 0xd2, 0xaf, 0xd3, 0x4a, 0x6d, 0xd6,
-      0x9e, 0x08, 0xcd, 0xa5, 0x44, 0xc8, 0x7b, 0x3a },
-    { 0xf3, 0x0c, 0x0a, 0xed, 0x70, 0x6d, 0x22, 0x55,
-      0x5f, 0x07, 0x09, 0x6a, 0xf4, 0xb8, 0xbe, 0xdc,
-      0x16, 0x3c, 0x0f, 0x6e, 0xd5, 0x34, 0x6e, 0xfc,
-      0x28, 0xe8, 0xcf, 0xaf, 0x84, 0x2f, 0xa5, 0xd9 },
-    { 0xf6, 0x13, 0xd5, 0x90, 0x46, 0xd1, 0x66, 0x71,
-      0xd3, 0xc5, 0x60, 0x17, 0x6f, 0x3d, 0x77, 0xfd,
-      0xc5, 0x1e, 0x5f, 0x57, 0xb5, 0xe4, 0x8a, 0xe7,
-      0xa4, 0xb9, 0x70, 0x0a, 0x11, 0xd4, 0x69, 0x3a },
-    { 0xf6, 0x54, 0x6b, 0x2f, 0xfe, 0x2b, 0xae, 0xf7,
-      0x35, 0xe8, 0x25, 0x67, 0xa6, 0xe2, 0x36, 0x75,
-      0x03, 0x94, 0xc1, 0x19, 0x14, 0x09, 0x87, 0x0c,
-      0x6f, 0xbe, 0x95, 0x2d, 0x08, 0xa3, 0x3a, 0xba },
-    { 0xf8, 0x64, 0x44, 0x3e, 0x2f, 0x63, 0x9e, 0x7c,
-      0xff, 0xd2, 0x42, 0x21, 0xf6, 0x1b, 0xbf, 0xf0,
-      0x7c, 0xce, 0x5c, 0x61, 0xdd, 0xb1, 0x68, 0xb3,
-      0xb4, 0x04, 0xd7, 0xc8, 0xcd, 0xca, 0x18, 0xb2 },
-    { 0xf8, 0x94, 0xf9, 0x67, 0x36, 0x9c, 0xe7, 0xcf,
-      0xa3, 0x1a, 0xc1, 0x9a, 0x66, 0x65, 0xb0, 0xc4,
-      0x24, 0xba, 0x40, 0x8a, 0xd5, 0xd3, 0x65, 0xf1,
-      0x68, 0xd8, 0xbe, 0xeb, 0x79, 0xf4, 0x89, 0xf3 },
-    { 0xf8, 0xcf, 0x1e, 0x08, 0x6a, 0x6a, 0x06, 0x3f,
-      0xad, 0x25, 0x74, 0x25, 0xaa, 0xe7, 0x20, 0x01,
-      0x40, 0x05, 0xb4, 0x15, 0x91, 0x2d, 0xbb, 0x8c,
-      0x0b, 0xc9, 0x99, 0xaf, 0x48, 0x48, 0xcf, 0xe5 },
-    { 0xfb, 0x9a, 0xf7, 0x9d, 0xea, 0x18, 0xaf, 0x62,
-      0x99, 0x85, 0x0e, 0x25, 0x15, 0x9b, 0x4f, 0xb2,
-      0x24, 0xcb, 0xb0, 0xf1, 0x4e, 0xad, 0x7e, 0x85,
-      0xf6, 0x0c, 0x2a, 0xb2, 0x09, 0xea, 0x45, 0x0d },
-    { 0xfb, 0xc4, 0xc9, 0xba, 0xcf, 0xe3, 0xda, 0x64,
-      0x13, 0x18, 0x26, 0x6b, 0x72, 0x58, 0x56, 0x00,
-      0x35, 0xbc, 0x64, 0x60, 0x8e, 0x34, 0xb9, 0x90,
-      0xca, 0x92, 0xa5, 0x52, 0xf3, 0x14, 0x21, 0x61 },
-    { 0xfb, 0xed, 0xd3, 0x88, 0x89, 0xf0, 0xb4, 0x1f,
-      0x73, 0x4d, 0xe2, 0xf4, 0xc9, 0xd6, 0xf2, 0x7c,
-      0x8d, 0x4a, 0xa9, 0xab, 0x73, 0x64, 0x91, 0xe1,
-      0x64, 0xe1, 0x21, 0xb7, 0xbc, 0xaf, 0x44, 0xe8 },
-    { 0xfc, 0x01, 0xa5, 0x5a, 0x36, 0xcc, 0x8b, 0x7b,
-      0x7c, 0xa2, 0xea, 0xb0, 0x84, 0x60, 0xc2, 0x8d,
-      0x1d, 0x6c, 0xd8, 0x9c, 0x57, 0x59, 0x94, 0x05,
-      0xd5, 0x37, 0x4b, 0x91, 0xaa, 0xeb, 0xc8, 0x79 },
-    { 0xfc, 0x4d, 0x9a, 0x37, 0xe5, 0xf7, 0x32, 0x72,
-      0xd0, 0xa9, 0xdf, 0xcc, 0xe9, 0x03, 0x12, 0xc7,
-      0x52, 0xe1, 0xb5, 0x2e, 0xb6, 0x54, 0xc4, 0x2c,
-      0x36, 0x94, 0x4b, 0x90, 0x2a, 0x30, 0x41, 0x07 },
-    { 0xfc, 0x56, 0xdb, 0xa1, 0xe7, 0xaf, 0xbd, 0xaa,
-      0x07, 0x33, 0xc6, 0x91, 0x1c, 0x5f, 0x1f, 0x18,
-      0x28, 0xcb, 0x12, 0x98, 0x31, 0x40, 0x1a, 0x3c,
-      0xfd, 0xea, 0xa7, 0x24, 0x62, 0x95, 0x35, 0x94 },
-    { 0xfc, 0x83, 0xc2, 0x89, 0x89, 0x5a, 0x92, 0x08,
-      0xc9, 0xb1, 0x7a, 0x16, 0xbc, 0xe5, 0xce, 0x80,
-      0xe8, 0xf4, 0xa0, 0x77, 0x21, 0x25, 0x29, 0xce,
-      0x0b, 0xc7, 0xf5, 0x42, 0xc6, 0xcb, 0xde, 0x1a },
-    { 0xfc, 0xa6, 0x23, 0x5d, 0x2a, 0xa4, 0xb1, 0xb2,
-      0x51, 0x50, 0x78, 0x57, 0xb4, 0xf0, 0x08, 0xdf,
-      0xd5, 0x27, 0x04, 0x2c, 0xe0, 0x45, 0x01, 0xaa,
-      0xe2, 0x9d, 0xd2, 0x05, 0xbb, 0xef, 0xce, 0x0d },
-    { 0xfc, 0xe7, 0x34, 0xe1, 0x2b, 0x8e, 0xfb, 0x43,
-      0x12, 0x71, 0xbf, 0xf6, 0x7a, 0x7a, 0x0a, 0x93,
-      0xb2, 0x19, 0xdd, 0x5e, 0x5d, 0xcc, 0x12, 0x58,
-      0x59, 0x4d, 0x96, 0xfc, 0xe1, 0x93, 0xb8, 0x60 },
-    { 0xfd, 0x9c, 0xfe, 0x14, 0xda, 0xd8, 0x97, 0x8c,
-      0x5b, 0xc8, 0x88, 0x93, 0x8f, 0x16, 0xf3, 0xb3,
-      0x98, 0xf7, 0x63, 0xa3, 0xad, 0xaf, 0xaa, 0x4a,
-      0xd9, 0x41, 0xb7, 0xe3, 0x87, 0xeb, 0x4f, 0x4a },
-    { 0xfd, 0xed, 0x92, 0xcb, 0x40, 0x91, 0x66, 0x82,
-      0x3a, 0x35, 0xe2, 0x17, 0xf3, 0x0b, 0x38, 0xc4,
-      0x86, 0xf8, 0x3e, 0xf2, 0xd4, 0xf2, 0x7b, 0x05,
-      0xf1, 0x8c, 0x74, 0x49, 0x81, 0x33, 0x9a, 0x1c },
-    { 0xfe, 0x26, 0xb2, 0xa6, 0x45, 0xa3, 0x1a, 0x91,
-      0x11, 0x00, 0x09, 0x9a, 0xa9, 0xa2, 0x93, 0x9f,
-      0x49, 0xe9, 0xfb, 0xea, 0x64, 0x48, 0x7b, 0xdf,
-      0x68, 0xa5, 0x23, 0x70, 0x32, 0x92, 0xd6, 0xa0 },
-    { 0xfe, 0x42, 0x1b, 0x24, 0x4e, 0x0e, 0x81, 0x6d,
-      0x9f, 0x26, 0xb3, 0x52, 0xc8, 0x31, 0xd9, 0x30,
-      0xe1, 0xc1, 0xc5, 0xd2, 0xfa, 0x4e, 0x0a, 0x1c,
-      0x77, 0x96, 0xa1, 0xf2, 0x02, 0x0e, 0xf1, 0x67 },
-    { 0xfe, 0x4f, 0x35, 0x6c, 0x7f, 0x9b, 0xfc, 0x17,
-      0xff, 0xcb, 0x68, 0xd0, 0x76, 0x4e, 0xcb, 0x2a,
-      0x87, 0xca, 0xa0, 0xae, 0x4c, 0xb5, 0x66, 0x62,
-      0x21, 0x04, 0xd3, 0x6f, 0xfb, 0x52, 0xcb, 0x29 },
-    { 0xff, 0x82, 0x6e, 0x2d, 0x0c, 0xb7, 0x71, 0x68,
-      0x68, 0x67, 0x5a, 0xe4, 0xb4, 0x31, 0xb6, 0x37,
-      0x1e, 0x9f, 0x0c, 0xdf, 0xcc, 0xb4, 0x9d, 0x43,
-      0xba, 0x30, 0x49, 0xbf, 0xdd, 0x2c, 0x41, 0xb1 },
-    { 0xff, 0xdc, 0x6b, 0x85, 0xfe, 0x7b, 0x10, 0x83,
-      0xb5, 0x41, 0x6f, 0x80, 0x6f, 0xc2, 0x44, 0xb9,
-      0xe4, 0xdf, 0x42, 0x99, 0xfb, 0xe3, 0xf6, 0x81,
-      0xaf, 0x3f, 0x5c, 0xf4, 0x22, 0x5a, 0x8e, 0xaf },
-};
-
-// SHA-256 hashes of leaf certificates issued by CNNIC's EV root.
-const uint8_t kCNNICEVWhitelist[][crypto::kSHA256Length] = {
-    { 0xb5, 0xef, 0x42, 0xc4, 0xbc, 0xed, 0xf1, 0x7b,
-      0xec, 0xc7, 0x5b, 0xf4, 0x63, 0x66, 0x49, 0xce,
-      0xbf, 0xf8, 0x71, 0x1b, 0xce, 0xff, 0xfa, 0x69,
-      0x5c, 0xc2, 0x52, 0xfa, 0x57, 0x4d, 0x42, 0x18 },
-    { 0xb6, 0x82, 0x3c, 0x9d, 0xbc, 0x8e, 0x8c, 0x05,
-      0x4b, 0xcf, 0x60, 0xf2, 0x38, 0x21, 0xac, 0x6c,
-      0x58, 0x19, 0x73, 0x51, 0xea, 0xcf, 0xa5, 0x57,
-      0x4c, 0xf0, 0x41, 0xb4, 0xce, 0x6b, 0x84, 0x04 },
-    { 0xdf, 0x69, 0xf9, 0x6a, 0x85, 0x67, 0x8f, 0x6c,
-      0xaf, 0x3f, 0xde, 0x25, 0xec, 0xfb, 0x5d, 0xf4,
-      0x74, 0x70, 0x87, 0xc2, 0xaf, 0x3b, 0x00, 0x65,
-      0xfb, 0x15, 0x10, 0x55, 0xcb, 0xcb, 0xa8, 0xc1 },
-    { 0xee, 0x0c, 0xf6, 0x2b, 0x9d, 0x8e, 0x42, 0xa2,
-      0x23, 0xb9, 0xa9, 0x60, 0xb5, 0xe9, 0x67, 0x0c,
-      0xcc, 0x34, 0x6d, 0x89, 0x93, 0x8f, 0xfa, 0x5d,
-      0xf7, 0x98, 0x65, 0xe4, 0x13, 0xd6, 0x31, 0x54 },
-};
-
-const PublicKeyWhitelist kBuiltinWhitelist[] = {
-    // C=CN, O=China Internet Network Information Center,
-    // CN=China Internet Network Information Center EV Certificates Root
-    // Expires: August 31 2030.
-    { { 0x9d, 0xd5, 0x5f, 0xc5, 0x73, 0xf5, 0x46, 0xcb,
-        0x6a, 0x38, 0x31, 0xd1, 0x11, 0x2d, 0x87, 0x10,
-        0xa6, 0xf4, 0xf8, 0x2d, 0xc8, 0x7f, 0x5f, 0xae,
-        0x9d, 0x3a, 0x1a, 0x02, 0x8d, 0xd3, 0x6e, 0x4b },
-      kCNNICEVWhitelist, arraysize(kCNNICEVWhitelist)
-    },
-    // C=CN, O=CNNIC, CN=CNNIC ROOT
-    // Expires: April 16 2027.
-    { { 0x1f, 0x42, 0x24, 0xce, 0xc8, 0x4f, 0xc9, 0x9c,
-        0xed, 0x88, 0x1f, 0xf6, 0xfc, 0xfd, 0x3e, 0x21,
-        0xf8, 0xc5, 0x19, 0xc5, 0x47, 0xaa, 0x6a, 0x5d,
-        0xd3, 0xde, 0x24, 0x73, 0x02, 0xce, 0x50, 0xd1 },
-      kCNNICDVWhitelist, arraysize(kCNNICDVWhitelist)
-    },
-};
 // clang-format on
-const size_t kBuiltinWhitelistSize = arraysize(kBuiltinWhitelist);
-
-const PublicKeyWhitelist* g_whitelist = kBuiltinWhitelist;
-size_t g_whitelist_size = kBuiltinWhitelistSize;
-
-// Comparator to compare a SHA256HashValue with a uint8_t array containing a
-// raw SHA-256 hash. Return value follows memcmp semantics.
-int CompareSHA256HashValueToRawHash(const void* key, const void* element) {
-  const SHA256HashValue* search_key =
-      reinterpret_cast<const SHA256HashValue*>(key);
-  return memcmp(search_key->data, element, sizeof(search_key->data));
-}
 
 // Comparator to compare a (SHA-256) HashValue with a uint8_t array containing
 // a raw SHA-256 hash. Return value follows memcmp semantics.
@@ -1671,36 +74,8 @@
          cert.valid_start() > last_wosign_cert)) {
       return true;
     }
-
-    // Check the public key whitelist.
-    for (size_t i = 0; i < g_whitelist_size; ++i) {
-      if (memcmp(hash.data(), g_whitelist[i].public_key,
-                 crypto::kSHA256Length) != 0) {
-        continue;
-      }
-      const SHA256HashValue leaf_hash =
-          X509Certificate::CalculateFingerprint256(cert.os_cert_handle());
-      void* result = bsearch(
-          &leaf_hash, g_whitelist[i].whitelist, g_whitelist[i].whitelist_size,
-          crypto::kSHA256Length, CompareSHA256HashValueToRawHash);
-      if (result == nullptr)
-        return true;  // Hash was not found on the public key whitelist.
-      break;
-    }
   }
   return false;
 }
 
-void SetCertificateWhitelistForTesting(const PublicKeyWhitelist* whitelist,
-                                       size_t whitelist_size) {
-  if (whitelist == nullptr || whitelist_size == 0) {
-    g_whitelist = kBuiltinWhitelist;
-    g_whitelist_size = kBuiltinWhitelistSize;
-    return;
-  }
-
-  g_whitelist = whitelist;
-  g_whitelist_size = whitelist_size;
-}
-
 }  // namespace net
diff --git a/net/cert/cert_verify_proc_whitelist.h b/net/cert/cert_verify_proc_whitelist.h
index f1582c9..6456320 100644
--- a/net/cert/cert_verify_proc_whitelist.h
+++ b/net/cert/cert_verify_proc_whitelist.h
@@ -16,15 +16,6 @@
 
 class X509Certificate;
 
-// PublicKeyWhitelist contains a SHA-256 SPKI hash and a pointer to an array
-// of SHA-256 certificate hashes that have been publicly disclosed and
-// whitelisted.
-struct PublicKeyWhitelist {
-  uint8_t public_key[crypto::kSHA256Length];
-  const uint8_t (*whitelist)[crypto::kSHA256Length];
-  size_t whitelist_size;
-};
-
 // Returns true if |cert| has been issued by a CA that is constrained from
 // issuing new certificates and |cert| is not within the whitelist of
 // existing certificates. Returns false if |cert| was issued by an
@@ -36,12 +27,6 @@
 IsNonWhitelistedCertificate(const X509Certificate& cert,
                             const HashValueVector& public_key_hashes);
 
-// Sets the certificate whitelist for testing. Supply nullptr/0 to reset to
-// the built-in whitelist.
-void NET_EXPORT_PRIVATE
-SetCertificateWhitelistForTesting(const PublicKeyWhitelist* whitelist,
-                                  size_t whitelist_size);
-
 }  // namespace net
 
 #endif  // NET_CERT_CERT_VERIFY_PROC_WHITELIST_H_
diff --git a/net/cert/cert_verify_proc_whitelist_unittest.cc b/net/cert/cert_verify_proc_whitelist_unittest.cc
index 7919573..2732035 100644
--- a/net/cert/cert_verify_proc_whitelist_unittest.cc
+++ b/net/cert/cert_verify_proc_whitelist_unittest.cc
@@ -14,176 +14,6 @@
 
 namespace {
 
-HashValue GetTestHashValue(uint8_t label, HashValueTag tag) {
-  HashValue hash_value(tag);
-  memset(hash_value.data(), label, hash_value.size());
-  return hash_value;
-}
-
-HashValueVector GetFakeHashValues() {
-  HashValueVector public_key_hashes;
-
-  // Fake "root" hash
-  public_key_hashes.push_back(GetTestHashValue(0x00, HASH_VALUE_SHA256));
-  public_key_hashes.push_back(GetTestHashValue(0x01, HASH_VALUE_SHA1));
-  // Fake "intermediate" hash
-  public_key_hashes.push_back(GetTestHashValue(0x02, HASH_VALUE_SHA256));
-  public_key_hashes.push_back(GetTestHashValue(0x03, HASH_VALUE_SHA1));
-  // Fake "leaf" hash
-  public_key_hashes.push_back(GetTestHashValue(0x04, HASH_VALUE_SHA256));
-  public_key_hashes.push_back(GetTestHashValue(0x05, HASH_VALUE_SHA1));
-
-  return public_key_hashes;
-}
-
-// The SHA-256 hash of the leaf cert "ok_cert.pem"; obtainable either
-// via X509Certificate::CalculateFingerprint256 or
-// openssl x509 -inform pem -in ok_cert.pem -outform der | openssl
-//   dgst -sha256 -c
-const uint8_t kWhitelistCerts[][crypto::kSHA256Length] = {
-    /* clang-format off */
-  { 0xf4, 0x42, 0xdd, 0x66, 0xfa, 0x10, 0x70, 0x65,
-    0xd1, 0x7e, 0xd9, 0xbb, 0x7c, 0xa9, 0x3c, 0x79,
-    0x63, 0xbe, 0x01, 0xa7, 0x54, 0x18, 0xab, 0x2f,
-    0xc3, 0x9a, 0x14, 0x53, 0xc3, 0x83, 0xa0, 0x5a },
-    /* clang-format on */
-};
-
-TEST(CertVerifyProcWhitelistTest, AcceptsWhitelistedEEByRoot) {
-  scoped_refptr<X509Certificate> cert =
-      ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
-  ASSERT_TRUE(cert);
-
-  // clang-format off
-  const PublicKeyWhitelist kWhitelist[] = {
-      { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
-        kWhitelistCerts, arraysize(kWhitelistCerts)
-      },
-  };
-  // clang-format on
-
-  SetCertificateWhitelistForTesting(kWhitelist, arraysize(kWhitelist));
-
-  HashValueVector public_key_hashes = GetFakeHashValues();
-
-  // Should return false, indicating this cert is acceptable because of
-  // it being whitelisted.
-  EXPECT_FALSE(IsNonWhitelistedCertificate(*cert, public_key_hashes));
-
-  SetCertificateWhitelistForTesting(nullptr, 0);
-}
-
-TEST(CertVerifyProcWhitelistTest, AcceptsWhitelistedEEByIntermediate) {
-  scoped_refptr<X509Certificate> cert =
-      ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
-  ASSERT_TRUE(cert);
-
-  // clang-format off
-  const PublicKeyWhitelist kWhitelist[] = {
-      { { 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-          0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-          0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-          0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02 },
-        kWhitelistCerts, arraysize(kWhitelistCerts)
-      },
-  };
-  // clang-format on
-
-  SetCertificateWhitelistForTesting(kWhitelist, arraysize(kWhitelist));
-
-  HashValueVector public_key_hashes = GetFakeHashValues();
-
-  // Should return false, indicating this cert is acceptable because of
-  // it being whitelisted.
-  EXPECT_FALSE(IsNonWhitelistedCertificate(*cert, public_key_hashes));
-
-  SetCertificateWhitelistForTesting(nullptr, 0);
-}
-
-TEST(CertVerifyProcWhitelistTest, RejectsNonWhitelistedEE) {
-  scoped_refptr<X509Certificate> cert =
-      ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem");
-  ASSERT_TRUE(cert);
-
-  // clang-format off
-  const PublicKeyWhitelist kWhitelist[] = {
-      { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
-        kWhitelistCerts, arraysize(kWhitelistCerts)
-      },
-  };
-  // clang-format on
-
-  SetCertificateWhitelistForTesting(kWhitelist, arraysize(kWhitelist));
-
-  HashValueVector public_key_hashes = GetFakeHashValues();
-
-  // Should return true, indicating this certificate chains to a constrained
-  // root and is not whitelisted.
-  EXPECT_TRUE(IsNonWhitelistedCertificate(*cert, public_key_hashes));
-
-  SetCertificateWhitelistForTesting(nullptr, 0);
-}
-
-TEST(CertVerifyProcWhitelistTest, RejectsNonWhitelistedEEByIntermediate) {
-  scoped_refptr<X509Certificate> cert =
-      ImportCertFromFile(GetTestCertsDirectory(), "expired_cert.pem");
-  ASSERT_TRUE(cert);
-
-  // clang-format off
-  const PublicKeyWhitelist kWhitelist[] = {
-      { { 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-          0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-          0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-          0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02 },
-        kWhitelistCerts, arraysize(kWhitelistCerts)
-      },
-  };
-  // clang-format on
-
-  SetCertificateWhitelistForTesting(kWhitelist, arraysize(kWhitelist));
-
-  HashValueVector public_key_hashes = GetFakeHashValues();
-
-  // Should return true, indicating this certificate chains to a constrained
-  // root and is not whitelisted.
-  EXPECT_TRUE(IsNonWhitelistedCertificate(*cert, public_key_hashes));
-
-  SetCertificateWhitelistForTesting(nullptr, 0);
-}
-
-TEST(CertVerifyProcWhitelistTest, AcceptsUnconstrainedLeaf) {
-  scoped_refptr<X509Certificate> cert =
-      ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
-  ASSERT_TRUE(cert);
-
-  // clang-format off
-  const PublicKeyWhitelist kWhitelist[] = {
-      { { 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
-          0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
-          0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
-          0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 },
-        kWhitelistCerts, arraysize(kWhitelistCerts)
-      },
-  };
-  // clang-format on
-
-  SetCertificateWhitelistForTesting(kWhitelist, arraysize(kWhitelist));
-
-  HashValueVector public_key_hashes = GetFakeHashValues();
-
-  // Should return false, because the chain (as indicated by
-  // public_key_hashes) is not constrained.
-  EXPECT_FALSE(IsNonWhitelistedCertificate(*cert, public_key_hashes));
-
-  SetCertificateWhitelistForTesting(nullptr, 0);
-}
-
 TEST(CertVerifyProcWhitelistTest, HandlesWosignCerts) {
   scoped_refptr<X509Certificate> cert =
       ImportCertFromFile(GetTestCertsDirectory(), "wosign_before_oct_21.pem");
diff --git a/net/cert/cert_verify_proc_win.cc b/net/cert/cert_verify_proc_win.cc
index b17fc0c..a13117a7 100644
--- a/net/cert/cert_verify_proc_win.cc
+++ b/net/cert/cert_verify_proc_win.cc
@@ -8,16 +8,12 @@
 #include <string>
 #include <vector>
 
-#include "base/debug/crash_logging.h"
-#include "base/debug/dump_without_crashing.h"
 #include "base/memory/free_deleter.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/sha1.h"
-#include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/threading/thread_local.h"
-#include "base/time/time.h"
 #include "crypto/capi_util.h"
 #include "crypto/scoped_capi_types.h"
 #include "crypto/sha2.h"
@@ -899,47 +895,6 @@
   ~ScopedThreadLocalCRLSet() { g_revocation_injector.Get().SetCRLSet(nullptr); }
 };
 
-// Sends a crash dump (without actually crashing) when the system time
-// falls within the validity period of every certificate in
-// |verified_cert|'s chain. This is to investigate reports of odd
-// certificate errors that report ERR_CERT_DATE_INVALID when the
-// certificate chain's dates appear to be valid.
-//
-// TODO(estark): remove this after obtaining diagnostic data from
-// Canary. https://crbug.com/672906
-void MaybeDumpCertificateDateError(
-    const scoped_refptr<X509Certificate>& verified_cert,
-    DWORD error_status,
-    DWORD info_status) {
-  const base::Time now = base::Time::NowFromSystemTime();
-  // If the leaf certificate is expired or not yet valid, nothing is odd.
-  if (now >= verified_cert->valid_expiry() ||
-      now <= verified_cert->valid_start()) {
-    return;
-  }
-  // Repeat the check for the rest of the certificates in the chain; if
-  // any of them is expired or not yet valid, nothing is odd.
-  X509Certificate::OSCertHandles intermediates =
-      verified_cert->GetIntermediateCertificates();
-  for (const auto& intermediate : intermediates) {
-    base::Time valid_start =
-        base::Time::FromFileTime(intermediate->pCertInfo->NotBefore);
-    base::Time valid_expiry =
-        base::Time::FromFileTime(intermediate->pCertInfo->NotAfter);
-    if (now >= valid_expiry || now <= valid_start)
-      return;
-  }
-  // None of the certificates in the chain appear to be expired or
-  // not-yet-valid, so send a crash dump for diagnostics.
-  base::debug::ScopedCrashKey error_status_crash_key(
-      "cert_verify_proc_win_date_error_error_status",
-      base::IntToString(error_status));
-  base::debug::ScopedCrashKey info_status_crash_key(
-      "cert_verify_proc_win_date_error_info_status",
-      base::IntToString(info_status));
-  base::debug::DumpWithoutCrashing();
-}
-
 }  // namespace
 
 CertVerifyProcWin::CertVerifyProcWin() {}
@@ -1215,17 +1170,6 @@
   verify_result->cert_status |= MapCertChainErrorStatusToCertStatus(
       chain_context->TrustStatus.dwErrorStatus);
 
-  // Send some diagnostic data in the event of certificate date errors
-  // that occur on chains with validity periods that are valid according
-  // to the system clock.
-  // TODO(estark): remove this after obtaining diagnostic data from
-  // Canary. https://crbug.com/672906
-  if (verify_result->cert_status & CERT_STATUS_DATE_INVALID) {
-    MaybeDumpCertificateDateError(verify_result->verified_cert,
-                                  chain_context->TrustStatus.dwErrorStatus,
-                                  chain_context->TrustStatus.dwInfoStatus);
-  }
-
   // Flag certificates that have a Subject common name with a NULL character.
   if (CertSubjectCommonNameHasNull(cert_handle))
     verify_result->cert_status |= CERT_STATUS_INVALID;
diff --git a/net/data/ssl/blacklist/1c01c6f4dbb2fefc22558b2bca32563f49844acfc32b7be4b0ff599f9e8c7af7.pem b/net/data/ssl/blacklist/1c01c6f4dbb2fefc22558b2bca32563f49844acfc32b7be4b0ff599f9e8c7af7.pem
new file mode 100644
index 0000000..b5e4f9a
--- /dev/null
+++ b/net/data/ssl/blacklist/1c01c6f4dbb2fefc22558b2bca32563f49844acfc32b7be4b0ff599f9e8c7af7.pem
@@ -0,0 +1,24 @@
+-----BEGIN CERTIFICATE-----
+MIID9zCCAt+gAwIBAgIESJ8AATANBgkqhkiG9w0BAQUFADCBijELMAkGA1UEBhMC
+Q04xMjAwBgNVBAoMKUNoaW5hIEludGVybmV0IE5ldHdvcmsgSW5mb3JtYXRpb24g
+Q2VudGVyMUcwRQYDVQQDDD5DaGluYSBJbnRlcm5ldCBOZXR3b3JrIEluZm9ybWF0
+aW9uIENlbnRlciBFViBDZXJ0aWZpY2F0ZXMgUm9vdDAeFw0xMDA4MzEwNzExMjVa
+Fw0zMDA4MzEwNzExMjVaMIGKMQswCQYDVQQGEwJDTjEyMDAGA1UECgwpQ2hpbmEg
+SW50ZXJuZXQgTmV0d29yayBJbmZvcm1hdGlvbiBDZW50ZXIxRzBFBgNVBAMMPkNo
+aW5hIEludGVybmV0IE5ldHdvcmsgSW5mb3JtYXRpb24gQ2VudGVyIEVWIENlcnRp
+ZmljYXRlcyBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm35z
+7r07eKpkQ0H1UN+U8i6yjUqORlTSIRLIOTJCBumD1Z9S7eVnAztUwYyZmczpwA//
+DdmEEbK40ctb3B75aDFk4Zv6dOtouSCV98YPjUesWgbdYavi7NifFy2cyjw1l1Vx
+zUOFsUcW9SxTgHbP0wBkvUCZ3czY28Sf1hNfQYOL+Q2HklY0bBoQCxfVWhyXWIQ8
+hBouXJE0bhlffxdpxWXvayHG1VA6v2G5BY3vbzQ6sm8UY78WO5upKv23KzhmBsUs
+4qpnHkWnjQRmQvaPK++IIGmPMowUc9orhpFjIpryp9vOiYurXccUwVswah+xt54u
+gQEC7c+WXmPbqOY4twIDAQABo2MwYTAfBgNVHSMEGDAWgBR8cks5x8DbYqVPm6oY
+NJKiyoOCWTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4E
+FgQUfHJLOcfA22KlT5uqGDSSosqDglkwDQYJKoZIhvcNAQEFBQADggEBACrDx0M3
+j92tpLIM7twUbY8opJhJywyA6vPtI2Z1fcXTIWd50XPFtQO3WKwMVC/GVhMPMdoG
+52U7HW8228gd+f2ABsqjPWYWqJ1MFn3AlUa1UeTiH9fqBk1jjZaM7+czV0I664zB
+echNdn3e9rG3geCg+aF4RhcaVpjwTj2rHO3sOdwHSPdj/gauwqRcalsyiMXHM4Ws
+ZkJHwlgkmeHlPuV1LI5D1l08eB6olYIpUNHRFrrvwb562bTYzB5MRuF3sTGrvSrI
+zo9uoV1/A3U05K2JRVRevq4opbs/eHnrc7MKDf2+yfdWrPa37S+bISnHOLaVxATy
+wy39FCqQmbkHzJ8=
+-----END CERTIFICATE-----
diff --git a/net/data/ssl/blacklist/README.md b/net/data/ssl/blacklist/README.md
index 332bd47..937390a2 100644
--- a/net/data/ssl/blacklist/README.md
+++ b/net/data/ssl/blacklist/README.md
@@ -8,6 +8,17 @@
 
 ## Compromises & Misissuances
 
+### China Internet Network Information Center (CNNIC)
+
+For details, see <https://security.googleblog.com/2015/03/maintaining-digital-certificate-security.html>
+
+As a result of misissuance of a sub-CA certificate, CNNIC end-entity
+certificates were temporarily whitelisted, and then trust in the root fully
+removed.
+
+  * [1c01c6f4dbb2fefc22558b2bca32563f49844acfc32b7be4b0ff599f9e8c7af7.pem](1c01c6f4dbb2fefc22558b2bca32563f49844acfc32b7be4b0ff599f9e8c7af7.pem)
+  * [e28393773da845a679f2080cc7fb44a3b7a1c3792cb7eb7729fdcb6a8d99aea7.pem](e28393773da845a679f2080cc7fb44a3b7a1c3792cb7eb7729fdcb6a8d99aea7.pem)
+
 ### Comodo
 
 For details, see <https://www.comodo.com/Comodo-Fraud-Incident-2011-03-23.html>,
diff --git a/net/data/ssl/blacklist/e28393773da845a679f2080cc7fb44a3b7a1c3792cb7eb7729fdcb6a8d99aea7.pem b/net/data/ssl/blacklist/e28393773da845a679f2080cc7fb44a3b7a1c3792cb7eb7729fdcb6a8d99aea7.pem
new file mode 100644
index 0000000..c81744b
--- /dev/null
+++ b/net/data/ssl/blacklist/e28393773da845a679f2080cc7fb44a3b7a1c3792cb7eb7729fdcb6a8d99aea7.pem
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDVTCCAj2gAwIBAgIESTMAATANBgkqhkiG9w0BAQUFADAyMQswCQYDVQQGEwJD
+TjEOMAwGA1UEChMFQ05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1QwHhcNMDcwNDE2
+MDcwOTE0WhcNMjcwNDE2MDcwOTE0WjAyMQswCQYDVQQGEwJDTjEOMAwGA1UEChMF
+Q05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1QwggEiMA0GCSqGSIb3DQEBAQUAA4IB
+DwAwggEKAoIBAQDTNfc/c3et6FtzF8LRb+1VvG7q6KR5smzDo+/hn7E7SIX1mlwh
+IhAsxYLO2uOabjfhhyzcuQxauohV3/2q2x8x6gHx3zkBwRP9SFIhxFXf2tizVHa6
+dLG3fdfA6PZZxU3Iva0fFNrfWEQlMhkqx35+jq44sDB7R3IJMfAw28Mbdim7aXZO
+V/kbZKKTVrdvmW7bCgScEeOAH8tjlBAKqeFkgjH5jCftppkA9nCTGPihNIaj3XrC
+GHn2emU1z5DrvTOTn1OrczvmmzQgLx3vqR1jGqCA2wMv+SYahtKNu6m+UjqHZ0gN
+v7Sg2Ca+I19zN38m5pIEo3/PIKe38zrKy5nLAgMBAAGjczBxMBEGCWCGSAGG+EIB
+AQQEAwIABzAfBgNVHSMEGDAWgBRl8jGtKvf33VKWCscCwQ7vptU7ETAPBgNVHRMB
+Af8EBTADAQH/MAsGA1UdDwQEAwIB/jAdBgNVHQ4EFgQUZfIxrSr3991SlgrHAsEO
+76bVOxEwDQYJKoZIhvcNAQEFBQADggEBAEs17szkrr/Dbq2flTtLP1se31cpolnK
+OOK5Gv+e5m4y3R6u6jW39ZORTtpC4cMXYFDy0VwmuYK36m3knITnA3kXr5g9lNvH
+ugDnuL8BV8F3RTIMO/G0HAiw/VGgod2aHRM2mm23xzy54cXZF/qD1T0VoDy7Hgvi
+yJA/qIYM/PmLXoXLT1tLYhFHxUV8BS9BsZ4QaRuZluBVeftOhpm4lNqGOGqTo+fL
+buXf6iFViZx9fX+Y9QCJ7uOEwFyWtcVG6kbghVW2G8kS1sHNzYDzAgE8yGnLRUhj
+2JTQ7IUOO04RZfSCjKY9ri4ilAnIXOo8gV0WKgOXFlUJ24pBgp5mmxE=
+-----END CERTIFICATE-----
diff --git a/net/data/ssl/certificates/README b/net/data/ssl/certificates/README
index 962978b..4645ec8 100644
--- a/net/data/ssl/certificates/README
+++ b/net/data/ssl/certificates/README
@@ -246,6 +246,14 @@
 - client_4.key
 - client_4.pk8
 - client_4_ca.pem
+- client_5.pem
+- client_5.key
+- client_5.pk8
+- client_5_ca.pem
+- client_6.pem
+- client_6.key
+- client_6.pk8
+- client_6_ca.pem
 - client_root_ca.pem
      This is a set of files used to unit test SSL client certificate
      authentication.
@@ -263,6 +271,10 @@
        Alternative Name fields recognized by Chrome OS.
      - client_4.pem is similar to client_2.pem but is a P-256 ECDSA key rather
        than RSA.
+     - client_5.pem is similar to client_2.pem but is a P-384 ECDSA key rather
+       than RSA.
+     - client_6.pem is similar to client_2.pem but is a P-521 ECDSA key rather
+       than RSA.
      - client_root_ca.pem is the CA certificate which signed client_*_ca.pem.
 
 ===== From net/data/ssl/scripts/generate-bad-eku-certs.sh
diff --git a/net/data/ssl/certificates/client_1.key b/net/data/ssl/certificates/client_1.key
index ea61cc8..0389e2208 100644
--- a/net/data/ssl/certificates/client_1.key
+++ b/net/data/ssl/certificates/client_1.key
@@ -1,27 +1,27 @@
 -----BEGIN RSA PRIVATE KEY-----
-MIIEpAIBAAKCAQEAm6YXgn7EzskCJawNsyffHz5P/wgyL9LkkYDzyFXqSGl2Rs66
-YlPkfBQVHAJXXcRMZL6GJ0qi32cpWgEsbXSk1zAiySVDayNej+jXNsQRoa9HE1lG
-6SvH5ojlGhiRV9r9c2a55L6HePnG3B9BTU1nPT01fGqnYpaUxVDxqwMHeG1xdfvx
-SEvrDsKWjYOSxVgbXGGDTwhMhA1rF1X+e9yimag0UxsB1IhNxd5YCJVRyaVTnxM+
-KmUe0OUYAXuKMGFGeT0W99M7YA3v6o2ZbPy3LZ07lwuP8w6egk5pjDo8v81FCUZn
-Vhv/xHVr/1JH98X+heE6eCq4yC+NXrdLiLGzywIDAQABAoIBACa5VuYHhg1wYxFe
-UfY9uDw8s4he0KWnUWiF7aDtByHG4z9QlXx7JMBd+raCOpxAh0UVRakm34i3UMls
-u1HsEErdVfo3RCO2pAMnyct9UmmogwVkU8kVNGG9s0ofzKFQAXihmSQ45tmJQxlm
-yUdjN4k73j+7BTP5BMBmmAmU8lnadWGIX97WG6hbB5mjfzIGlZM11kUlaIFnm9/f
-UbrazpB6CdTeS5eML4ikLYfSoM/5r6r1gT01B8q16ZDEW5/mSmAgTPvyEY4XdKpZ
-te2KOJFs9EfPn1VgSpN5ebnwRVnXKEYM6VRi2Ssn5YwQs8zS1+Fd95VBANVwS+yj
-rehgaqECgYEAzK6Ru/iCJj4ecSXiuIN15H9mAcAG6WQmuPCLUc0eyvUZ0Mj57yjg
-irJjflScLcotR/YdBUfUX+//XDBiQ9lVWCmFtHwWoynMBC4p+mBcVbId1LEk/kn4
-Oyx2Zkp7ccIpOe5JU8788GSroZzvQs9Ic2AI3hz/vC+igokNQJiUd5ECgYEAwqxZ
-x2tLz1vNLDlfXhaFkhpttJoUV+rQteV9SsEqcAOBLgBqk49hwFTInQELpEtrzfo9
-3IW1C7C/e378OOlw+fBnBtmkTDfPy9XJd6b+VQWHsk/t1g2D2qYO0htrfwNpIe5V
-Ns15MGiMV7kA8KELx+gAokSUws90StTqtJFG35sCgYEAxMSRr23w2IjhRQ8RzSX8
-AQWEb+xF+LriCuqcVLBniN9lyPRcadEXQ97IjRsT5WU2cLamIXxzKyOSjvKolOdr
-B00rj123eXXl/qLOkjdurKeFzAHcOWWs8F4HGMFDuRHaBioQbjRPr15oLP6seMLC
-uL+65qRkKWp1xR2yEsZb/DECgYAbwLRf4KUDH8RFPLyizjUmmgvvxlOGIRy2Acx1
-3sntBCLjav3GoZc+8xdSgralKndo+vbcvFcOHpl9wqG0f1sy1pnpeReaIg7GsWiy
-XSU++7XXrttqO60De877FxuhFNxlEPQnBu3y/8SaMO64X00tp56Hg51tlGOw01/O
-dDOVZwKBgQCKvxUHZPD6Q+M5HI/HmFxsHj9SsSl2sACErQMk7ru/aimuz9YPBXks
-KeMzjIeRqtJadK9KQCBeGWmOFTLezgt+mceXn92nfNYMfdSkLzlyKZM2FW9Kk1Z/
-7YduboDUCiGg2PMn/qZPUiko3vkR6B3es/G+VC16mCrh9GksfsGHVg==
+MIIEpQIBAAKCAQEAyYDjdJs5t0m2REDwka5GhFCGi8cPzDTgEKaqZj3wzRX/T8m/
+/jIRTK1ZfHxuzT61GnGOiut8XSw28a7/WY0/1/cc3nTGm0PuvKmBjrilQCZ9Y8kb
+LC+lEQaD1y/TMErQN9W5/dE/bU91Cg0zIXJgX9a0pGyWeM7C87q9DRky/WwbN6eS
+89fAsRNPILn7fDiSB8X3d27fv/mfWgw9pz0lew3hY4nppOulvBdaRKgxJKX8KTBS
+cy3osDwkB+urQLamGsP/7igjIGy5yKOw8nXsnf1Gq+GDhS0E4Ca6seNEAOiXaAGC
+W7wfNyBP+aVHj0CNvDPN147I/PfGKG1ZSvdipwIDAQABAoIBAQCXSQF8pp4qklkZ
+3XfAqIuhA6RAhW/C7V/coIUGxjJoh79r9BkFjCmY2/13jSTTS+VEuUU/35U7jtqh
+kbV9UqNATfOKwTnrkJFJbCotMUxAYaV6qZ6RCiRwJ+gMQ4fXlhPGF9zQR63LMAC7
+TzW4QttAmT5+xFgk03di7izKDMVPpedFlbpBPClBvf5nFiQAGY8jIhyyT0rKuoTN
+iowciprIKeDg32vFCJAiIWgV687tTByjknpxYkH7H00kWctXklTKV44hSB07ayC7
+dMkskH+X2LHxxFj/YP6goYjlN3c+cW7SDnwoRyZUNuhU7N8Xo62Rp94axhvKekJ0
+t58nLwehAoGBAP/CXyZmyPWOfcrxO7OgpM/MQuGqF7etS57t6EphLhyTQOWCGK5Z
+OS8Zun9/JOKxLPpjxQJpETfSBg1Q7KFRpzpnkd7db2GFP1+gz3bbeO3hsR6pfcQs
+DxlUx/GHvX+i7c3wHfVgoBYG+cUugt44CzjYulLF/O5OZORGhujtxog1AoGBAMmx
+cXb7naEgwa1dkRP7+OfbEN+gyJKN0D0bn/TRhaRaAoFUTGRqnvpbGMTsU5o9eOnh
+pNhwBX1U/t/7nd9TcgCEqPBCKGAGOou29hq9rZ6whEvAF/rZXdzigaMGJF7MRq3l
+XtNPC4+B9BJmoVxEu/l6dAI0HYwYaNFdEk9SZjLrAoGBANRABp7j5hqDKjnlgNpN
+kvkwVsDYW95+3qcCYSh5Bb+JJO5SzRDD0wUXoQJ2DbJjvyP88F5Tu4pLreIXKomm
+LdX2ZcRCmFCiODmwRvwon28rQcZkeo720YEALv5u3AC0wg2KHBKrIa+mElplgw3Q
+DOAcXGSdEo7iWDBpp0RfL8eRAoGAI5kU7KomPR0Z8e5Uv9E2Mj3g8YdgPzWWbmKk
+zcH5M3PLg2YMgaCr5IYVjhQkAVIeODFiNe03mtJYldHEIHmK4nqHkrgqhiAzTxuA
+vmGB9kMzZmdGFDkvLuAvf0WDP9QQGXslTGhkIvUNzf2dNzrObo7lUMo/+M0KGwGx
+TJy/evcCgYEA2rvXrdrpTMq9RwmjZejX5FjKvCTME1n5RE/I7kOgr3J4FShhDRyU
+1wlVvQe7C6W59MVGF+9OAhth/lPDagv3WsBK0r6luabm3QwakAZLQqjpbD7Anw+Q
+0+KEtl2M7PI8gwY8lrdFSEC2tJYp8iu/ahniyVxZjf5mEic6BnqIx/4=
 -----END RSA PRIVATE KEY-----
diff --git a/net/data/ssl/certificates/client_1.pem b/net/data/ssl/certificates/client_1.pem
index 33573d3..9e52061 100644
--- a/net/data/ssl/certificates/client_1.pem
+++ b/net/data/ssl/certificates/client_1.pem
@@ -5,31 +5,31 @@
     Signature Algorithm: sha256WithRSAEncryption
         Issuer: CN=B CA
         Validity
-            Not Before: Oct  4 18:53:24 2016 GMT
-            Not After : Oct  2 18:53:24 2026 GMT
+            Not Before: Dec  9 20:18:57 2016 GMT
+            Not After : Dec  7 20:18:57 2026 GMT
         Subject: CN=Client Cert A
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
                 Public-Key: (2048 bit)
                 Modulus:
-                    00:9b:a6:17:82:7e:c4:ce:c9:02:25:ac:0d:b3:27:
-                    df:1f:3e:4f:ff:08:32:2f:d2:e4:91:80:f3:c8:55:
-                    ea:48:69:76:46:ce:ba:62:53:e4:7c:14:15:1c:02:
-                    57:5d:c4:4c:64:be:86:27:4a:a2:df:67:29:5a:01:
-                    2c:6d:74:a4:d7:30:22:c9:25:43:6b:23:5e:8f:e8:
-                    d7:36:c4:11:a1:af:47:13:59:46:e9:2b:c7:e6:88:
-                    e5:1a:18:91:57:da:fd:73:66:b9:e4:be:87:78:f9:
-                    c6:dc:1f:41:4d:4d:67:3d:3d:35:7c:6a:a7:62:96:
-                    94:c5:50:f1:ab:03:07:78:6d:71:75:fb:f1:48:4b:
-                    eb:0e:c2:96:8d:83:92:c5:58:1b:5c:61:83:4f:08:
-                    4c:84:0d:6b:17:55:fe:7b:dc:a2:99:a8:34:53:1b:
-                    01:d4:88:4d:c5:de:58:08:95:51:c9:a5:53:9f:13:
-                    3e:2a:65:1e:d0:e5:18:01:7b:8a:30:61:46:79:3d:
-                    16:f7:d3:3b:60:0d:ef:ea:8d:99:6c:fc:b7:2d:9d:
-                    3b:97:0b:8f:f3:0e:9e:82:4e:69:8c:3a:3c:bf:cd:
-                    45:09:46:67:56:1b:ff:c4:75:6b:ff:52:47:f7:c5:
-                    fe:85:e1:3a:78:2a:b8:c8:2f:8d:5e:b7:4b:88:b1:
-                    b3:cb
+                    00:c9:80:e3:74:9b:39:b7:49:b6:44:40:f0:91:ae:
+                    46:84:50:86:8b:c7:0f:cc:34:e0:10:a6:aa:66:3d:
+                    f0:cd:15:ff:4f:c9:bf:fe:32:11:4c:ad:59:7c:7c:
+                    6e:cd:3e:b5:1a:71:8e:8a:eb:7c:5d:2c:36:f1:ae:
+                    ff:59:8d:3f:d7:f7:1c:de:74:c6:9b:43:ee:bc:a9:
+                    81:8e:b8:a5:40:26:7d:63:c9:1b:2c:2f:a5:11:06:
+                    83:d7:2f:d3:30:4a:d0:37:d5:b9:fd:d1:3f:6d:4f:
+                    75:0a:0d:33:21:72:60:5f:d6:b4:a4:6c:96:78:ce:
+                    c2:f3:ba:bd:0d:19:32:fd:6c:1b:37:a7:92:f3:d7:
+                    c0:b1:13:4f:20:b9:fb:7c:38:92:07:c5:f7:77:6e:
+                    df:bf:f9:9f:5a:0c:3d:a7:3d:25:7b:0d:e1:63:89:
+                    e9:a4:eb:a5:bc:17:5a:44:a8:31:24:a5:fc:29:30:
+                    52:73:2d:e8:b0:3c:24:07:eb:ab:40:b6:a6:1a:c3:
+                    ff:ee:28:23:20:6c:b9:c8:a3:b0:f2:75:ec:9d:fd:
+                    46:ab:e1:83:85:2d:04:e0:26:ba:b1:e3:44:00:e8:
+                    97:68:01:82:5b:bc:1f:37:20:4f:f9:a5:47:8f:40:
+                    8d:bc:33:cd:d7:8e:c8:fc:f7:c6:28:6d:59:4a:f7:
+                    62:a7
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Basic Constraints: critical
@@ -37,36 +37,36 @@
             X509v3 Extended Key Usage: 
                 TLS Web Server Authentication, TLS Web Client Authentication
     Signature Algorithm: sha256WithRSAEncryption
-         19:9b:41:39:61:cf:f8:0f:62:98:43:1a:a4:fb:0b:71:f2:f0:
-         c4:b5:39:bb:dc:d1:d7:33:44:89:66:13:ff:0a:5a:66:02:74:
-         6a:8d:8a:dc:a0:e0:d0:cc:8d:5f:1c:c0:34:c6:58:02:76:3b:
-         b5:1a:81:a5:a7:a1:c5:81:14:52:0f:21:37:06:2d:dc:dc:9c:
-         d0:d1:98:03:ac:d3:b5:12:0b:f8:b4:84:d8:bc:be:4d:27:fa:
-         df:16:6e:dd:0a:33:b7:87:50:7e:fe:c6:8d:84:b2:2d:7f:58:
-         88:21:af:09:64:5e:4a:2d:f0:56:d4:3e:a3:dc:4c:aa:92:41:
-         04:c1:6e:56:46:d5:36:69:0d:2a:f6:f0:29:d3:7c:ac:b7:cf:
-         7f:18:bc:76:fa:8c:5a:76:81:67:db:b2:91:97:05:7d:14:da:
-         26:d5:67:fe:c5:d2:6a:2c:5f:f4:96:3a:e4:0e:f5:15:95:05:
-         57:de:b5:e5:96:b2:10:99:4a:b2:3a:ac:d2:ae:64:30:31:54:
-         f0:b9:9f:1d:56:e8:da:e9:4e:42:e3:26:3d:f7:8c:3e:9c:dd:
-         42:77:9d:0c:67:52:73:94:c4:73:42:c2:b7:96:a4:44:4a:d5:
-         e9:3d:b1:46:aa:38:0b:1f:7f:ae:01:c6:07:da:40:3b:c0:22:
-         61:c4:cb:80
+         1f:ef:f9:19:b9:64:e7:15:e2:7f:4f:e0:9e:66:f0:2a:b8:8f:
+         4e:63:0c:7c:d5:a0:37:68:d2:c8:c2:9a:7b:e1:bd:13:31:c8:
+         ca:ce:96:c0:13:0a:bd:5e:f2:3c:8a:4d:0a:82:61:7e:35:0b:
+         fc:07:83:82:6e:cc:97:18:ff:32:68:08:5b:1a:34:35:ca:f0:
+         d2:19:d0:f0:35:66:c8:0b:44:ac:94:75:28:d8:cc:c1:b7:32:
+         df:93:cb:94:48:43:c7:cc:06:d3:b8:6c:6a:b2:c0:9f:f7:ef:
+         dd:36:c0:81:f9:e8:f0:7f:1c:d9:c5:92:31:91:de:88:a6:8d:
+         0c:9e:e5:bf:a9:91:69:09:24:b1:5b:70:45:10:e1:8c:38:99:
+         c3:06:95:da:6a:c5:02:20:f8:25:e2:0c:b2:76:e5:01:1c:4b:
+         0b:77:5a:ec:ff:99:37:fc:38:ff:17:cb:42:1d:c2:2f:2f:1f:
+         d1:be:d5:c6:22:89:e9:73:9c:ff:a9:03:77:cb:28:e5:e8:7e:
+         0d:80:d4:75:88:ab:79:0b:bc:e3:98:1f:6e:0b:44:e2:c4:8a:
+         e6:6c:1d:74:30:6a:84:a7:2d:84:96:c4:7c:a9:25:39:8e:c8:
+         50:df:0f:41:3f:4b:cb:92:c9:92:ed:2a:73:f1:7d:c3:cf:60:
+         a7:af:ab:85
 -----BEGIN CERTIFICATE-----
 MIIC0jCCAbqgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEQiBD
-QTAeFw0xNjEwMDQxODUzMjRaFw0yNjEwMDIxODUzMjRaMBgxFjAUBgNVBAMMDUNs
-aWVudCBDZXJ0IEEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCbpheC
-fsTOyQIlrA2zJ98fPk//CDIv0uSRgPPIVepIaXZGzrpiU+R8FBUcAlddxExkvoYn
-SqLfZylaASxtdKTXMCLJJUNrI16P6Nc2xBGhr0cTWUbpK8fmiOUaGJFX2v1zZrnk
-vod4+cbcH0FNTWc9PTV8aqdilpTFUPGrAwd4bXF1+/FIS+sOwpaNg5LFWBtcYYNP
-CEyEDWsXVf573KKZqDRTGwHUiE3F3lgIlVHJpVOfEz4qZR7Q5RgBe4owYUZ5PRb3
-0ztgDe/qjZls/LctnTuXC4/zDp6CTmmMOjy/zUUJRmdWG//EdWv/Ukf3xf6F4Tp4
-KrjIL41et0uIsbPLAgMBAAGjLzAtMAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYwFAYI
-KwYBBQUHAwEGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQAZm0E5Yc/4D2KY
-Qxqk+wtx8vDEtTm73NHXM0SJZhP/ClpmAnRqjYrcoODQzI1fHMA0xlgCdju1GoGl
-p6HFgRRSDyE3Bi3c3JzQ0ZgDrNO1Egv4tITYvL5NJ/rfFm7dCjO3h1B+/saNhLIt
-f1iIIa8JZF5KLfBW1D6j3EyqkkEEwW5WRtU2aQ0q9vAp03yst89/GLx2+oxadoFn
-27KRlwV9FNom1Wf+xdJqLF/0ljrkDvUVlQVX3rXllrIQmUqyOqzSrmQwMVTwuZ8d
-Vuja6U5C4yY994w+nN1Cd50MZ1JzlMRzQsK3lqREStXpPbFGqjgLH3+uAcYH2kA7
-wCJhxMuA
+QTAeFw0xNjEyMDkyMDE4NTdaFw0yNjEyMDcyMDE4NTdaMBgxFjAUBgNVBAMMDUNs
+aWVudCBDZXJ0IEEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDJgON0
+mzm3SbZEQPCRrkaEUIaLxw/MNOAQpqpmPfDNFf9Pyb/+MhFMrVl8fG7NPrUacY6K
+63xdLDbxrv9ZjT/X9xzedMabQ+68qYGOuKVAJn1jyRssL6URBoPXL9MwStA31bn9
+0T9tT3UKDTMhcmBf1rSkbJZ4zsLzur0NGTL9bBs3p5Lz18CxE08guft8OJIHxfd3
+bt+/+Z9aDD2nPSV7DeFjiemk66W8F1pEqDEkpfwpMFJzLeiwPCQH66tAtqYaw//u
+KCMgbLnIo7Dydeyd/Uar4YOFLQTgJrqx40QA6JdoAYJbvB83IE/5pUePQI28M83X
+jsj898YobVlK92KnAgMBAAGjLzAtMAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYwFAYI
+KwYBBQUHAwEGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQAf7/kZuWTnFeJ/
+T+CeZvAquI9OYwx81aA3aNLIwpp74b0TMcjKzpbAEwq9XvI8ik0KgmF+NQv8B4OC
+bsyXGP8yaAhbGjQ1yvDSGdDwNWbIC0SslHUo2MzBtzLfk8uUSEPHzAbTuGxqssCf
+9+/dNsCB+ejwfxzZxZIxkd6Ipo0MnuW/qZFpCSSxW3BFEOGMOJnDBpXaasUCIPgl
+4gyyduUBHEsLd1rs/5k3/Dj/F8tCHcIvLx/RvtXGIonpc5z/qQN3yyjl6H4NgNR1
+iKt5C7zjmB9uC0TixIrmbB10MGqEpy2ElsR8qSU5jshQ3w9BP0vLksmS7Spz8X3D
+z2Cnr6uF
 -----END CERTIFICATE-----
diff --git a/net/data/ssl/certificates/client_1.pk8 b/net/data/ssl/certificates/client_1.pk8
index 19db6db3..12bf489c 100644
--- a/net/data/ssl/certificates/client_1.pk8
+++ b/net/data/ssl/certificates/client_1.pk8
Binary files differ
diff --git a/net/data/ssl/certificates/client_1_ca.pem b/net/data/ssl/certificates/client_1_ca.pem
index 88723ce6..9d61c0a 100644
--- a/net/data/ssl/certificates/client_1_ca.pem
+++ b/net/data/ssl/certificates/client_1_ca.pem
@@ -5,31 +5,31 @@
     Signature Algorithm: sha256WithRSAEncryption
         Issuer: CN=C Root CA
         Validity
-            Not Before: Oct  4 18:53:24 2016 GMT
-            Not After : Oct  2 18:53:24 2026 GMT
+            Not Before: Dec  9 20:18:57 2016 GMT
+            Not After : Dec  7 20:18:57 2026 GMT
         Subject: CN=B CA
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
                 Public-Key: (2048 bit)
                 Modulus:
-                    00:a5:56:c7:9d:32:e7:3d:17:ac:59:ca:f4:07:65:
-                    25:3e:65:7c:d9:3d:f4:0e:73:eb:b9:0b:a1:7b:4b:
-                    69:ab:ee:a3:50:49:2f:25:33:4d:2d:ac:00:32:17:
-                    34:0d:c9:bf:83:7d:b4:e5:d5:82:89:6f:ad:41:78:
-                    56:1d:05:bc:48:cc:0c:43:95:81:e3:e8:12:2d:67:
-                    74:68:12:61:8e:03:24:88:2c:57:28:8e:3d:10:77:
-                    da:dc:78:b6:b4:72:92:56:0e:4a:0c:c6:f7:0a:44:
-                    f5:56:5d:72:7a:a8:1d:bc:16:e8:95:25:4d:50:b6:
-                    2e:22:05:fd:d5:20:47:a4:32:37:52:38:61:90:9a:
-                    aa:40:a8:db:91:80:00:89:e6:2c:17:5d:7c:5f:6f:
-                    2d:b2:b7:cf:71:a1:55:11:d8:fd:3b:9b:61:8f:1c:
-                    80:dd:da:90:8c:82:04:63:36:7c:b1:28:38:56:bc:
-                    6e:c0:b3:b9:4e:96:2b:3f:62:2a:e5:5f:f1:73:3c:
-                    53:a8:5f:03:d0:63:31:36:ac:00:61:30:ab:ad:d9:
-                    aa:ab:5d:22:83:28:cc:f1:f7:88:f5:9a:be:57:c5:
-                    e1:46:da:a3:88:55:a7:3c:f9:1c:17:bb:72:01:1d:
-                    dd:8e:a0:b0:a3:d1:91:74:ae:94:58:c0:f5:30:63:
-                    5c:91
+                    00:b3:87:98:77:4f:45:bb:de:87:86:1f:8b:1e:b2:
+                    26:cb:56:a3:d3:10:85:5e:95:ed:aa:c3:87:17:f4:
+                    40:86:bf:d7:e0:4a:ea:43:95:ce:b9:22:2a:c4:90:
+                    f0:24:34:81:f2:5b:58:47:d3:d8:9b:eb:fc:90:4b:
+                    54:41:6d:6a:c0:5d:82:56:49:47:c4:ab:29:48:a4:
+                    23:05:fa:4f:a3:9e:83:65:5a:fd:57:c2:5a:4c:13:
+                    bf:eb:75:ff:4d:f9:c1:5b:65:32:7d:bb:0d:e3:20:
+                    6a:4c:b3:28:fc:01:11:68:c0:9c:4b:f6:a5:df:68:
+                    0e:b2:c1:6f:b3:69:5f:53:35:2c:b9:3b:f8:c2:48:
+                    3b:3f:8f:d1:9f:76:b1:3a:1a:22:7f:fd:28:e6:6e:
+                    1c:96:95:c3:37:6f:c4:5a:24:28:25:5b:f6:a0:85:
+                    f0:47:33:fa:9d:3b:38:cf:b1:d1:c9:06:d8:25:03:
+                    bc:00:50:fe:08:dc:0d:d8:b1:87:94:8e:dc:74:ac:
+                    2c:53:44:91:4c:67:0a:71:5e:d3:df:c6:58:ee:00:
+                    fe:96:fd:2f:96:f8:9f:35:5a:4e:be:ca:c1:5a:55:
+                    f8:4d:85:77:3d:a9:d6:aa:75:0f:b9:82:07:c4:89:
+                    9e:9a:e6:39:f8:39:d2:be:62:cd:ca:43:a2:55:bf:
+                    0b:81
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Basic Constraints: critical
@@ -37,35 +37,35 @@
             X509v3 Key Usage: critical
                 Certificate Sign, CRL Sign
     Signature Algorithm: sha256WithRSAEncryption
-         41:1f:59:af:b3:83:87:87:bc:b3:2d:62:66:35:76:21:f2:bb:
-         e5:d4:87:23:a3:ab:4f:2b:ef:d0:ee:53:6f:17:b0:d4:6a:93:
-         8e:74:71:7b:c5:36:f4:7b:87:3a:ab:84:b0:40:c5:3b:a0:e7:
-         a1:18:e6:3f:8d:8d:a8:49:b5:da:c7:4b:26:e4:ea:b9:2d:85:
-         b2:1d:01:70:bb:78:08:a6:c7:11:6b:0a:6f:5d:b0:d7:b5:72:
-         ec:51:46:26:bc:7e:e1:bd:1e:5e:d6:44:cf:d0:1b:55:ef:a9:
-         5e:16:73:05:59:9f:ff:00:2e:5b:4e:29:7b:c4:2e:5c:46:9c:
-         56:0a:78:d9:0b:10:83:9e:ff:8a:e3:57:ec:f1:d1:a3:85:26:
-         2f:97:e6:d0:6f:5e:c8:cb:53:e7:28:64:ab:27:14:f4:b2:4b:
-         52:80:e2:d1:ef:50:ba:db:34:5c:95:a4:3f:ac:5b:eb:15:c5:
-         d6:cb:4b:76:fb:f6:cd:2f:d9:ef:d4:cb:1c:85:52:8b:f2:2b:
-         1b:ce:e3:0f:ed:07:44:11:8b:d8:b8:5c:41:ab:e1:36:0d:7e:
-         3f:86:ff:0c:0f:f5:5e:ff:f6:b8:0a:ac:f0:3b:5d:c5:b7:ef:
-         f1:80:7c:26:b9:a2:ee:17:a8:e7:cb:c4:f4:5c:51:ff:57:53:
-         ee:a2:d3:66
+         99:1e:ab:d0:ab:f7:27:85:ed:91:bc:b0:3e:af:57:a8:31:1d:
+         8e:e8:4b:bc:3e:b4:82:c9:6c:62:3a:8d:48:be:a1:0a:42:27:
+         11:18:ef:47:53:b2:46:5f:d0:de:31:4e:c3:de:e8:c5:f6:24:
+         09:69:25:c9:e6:f8:1e:1a:b1:27:63:ff:07:8b:7b:e9:80:b5:
+         68:d4:94:54:b6:fe:c6:a6:3b:61:01:f9:89:a2:50:f2:9b:a0:
+         02:2a:85:bd:13:5a:43:45:a7:b7:7c:eb:1a:69:95:04:dc:c0:
+         17:13:da:c8:73:fd:0b:94:a2:fe:af:e7:18:b4:b1:90:21:99:
+         ad:f8:06:9a:6d:c1:e1:3b:f4:85:69:91:6d:68:84:9f:e9:09:
+         30:08:f6:11:87:99:67:8f:16:cc:59:43:38:95:5e:fa:9d:c5:
+         4a:2d:55:f2:3d:1a:49:5c:12:66:ea:40:2d:a1:de:08:40:a4:
+         b3:dc:19:8a:23:04:a6:cf:a6:9b:2e:d0:2a:3c:5f:fa:4c:bb:
+         5a:62:d0:0b:a4:f6:8c:06:42:54:b4:c6:63:e0:f1:f0:11:a8:
+         ec:57:3d:93:6c:0c:67:a5:5a:8a:52:c5:37:b6:c3:7e:54:05:
+         b0:82:d9:32:8a:a7:12:83:39:d9:bc:81:ce:db:e9:ad:e9:b7:
+         5d:1d:6d:3a
 -----BEGIN CERTIFICATE-----
 MIICwjCCAaqgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwFDESMBAGA1UEAwwJQyBS
-b290IENBMB4XDTE2MTAwNDE4NTMyNFoXDTI2MTAwMjE4NTMyNFowDzENMAsGA1UE
-AwwEQiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKVWx50y5z0X
-rFnK9AdlJT5lfNk99A5z67kLoXtLaavuo1BJLyUzTS2sADIXNA3Jv4N9tOXVgolv
-rUF4Vh0FvEjMDEOVgePoEi1ndGgSYY4DJIgsVyiOPRB32tx4trRyklYOSgzG9wpE
-9VZdcnqoHbwW6JUlTVC2LiIF/dUgR6QyN1I4YZCaqkCo25GAAInmLBddfF9vLbK3
-z3GhVRHY/TubYY8cgN3akIyCBGM2fLEoOFa8bsCzuU6WKz9iKuVf8XM8U6hfA9Bj
-MTasAGEwq63ZqqtdIoMozPH3iPWavlfF4Ubao4hVpzz5HBe7cgEd3Y6gsKPRkXSu
-lFjA9TBjXJECAwEAAaMjMCEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
-AQYwDQYJKoZIhvcNAQELBQADggEBAEEfWa+zg4eHvLMtYmY1diHyu+XUhyOjq08r
-79DuU28XsNRqk450cXvFNvR7hzqrhLBAxTug56EY5j+NjahJtdrHSybk6rkthbId
-AXC7eAimxxFrCm9dsNe1cuxRRia8fuG9Hl7WRM/QG1XvqV4WcwVZn/8ALltOKXvE
-LlxGnFYKeNkLEIOe/4rjV+zx0aOFJi+X5tBvXsjLU+coZKsnFPSyS1KA4tHvULrb
-NFyVpD+sW+sVxdbLS3b79s0v2e/UyxyFUovyKxvO4w/tB0QRi9i4XEGr4TYNfj+G
-/wwP9V7/9rgKrPA7XcW37/GAfCa5ou4XqOfLxPRcUf9XU+6i02Y=
+b290IENBMB4XDTE2MTIwOTIwMTg1N1oXDTI2MTIwNzIwMTg1N1owDzENMAsGA1UE
+AwwEQiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALOHmHdPRbve
+h4Yfix6yJstWo9MQhV6V7arDhxf0QIa/1+BK6kOVzrkiKsSQ8CQ0gfJbWEfT2Jvr
+/JBLVEFtasBdglZJR8SrKUikIwX6T6Oeg2Va/VfCWkwTv+t1/035wVtlMn27DeMg
+akyzKPwBEWjAnEv2pd9oDrLBb7NpX1M1LLk7+MJIOz+P0Z92sToaIn/9KOZuHJaV
+wzdvxFokKCVb9qCF8Ecz+p07OM+x0ckG2CUDvABQ/gjcDdixh5SO3HSsLFNEkUxn
+CnFe09/GWO4A/pb9L5b4nzVaTr7KwVpV+E2Fdz2p1qp1D7mCB8SJnprmOfg50r5i
+zcpDolW/C4ECAwEAAaMjMCEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
+AQYwDQYJKoZIhvcNAQELBQADggEBAJkeq9Cr9yeF7ZG8sD6vV6gxHY7oS7w+tILJ
+bGI6jUi+oQpCJxEY70dTskZf0N4xTsPe6MX2JAlpJcnm+B4asSdj/weLe+mAtWjU
+lFS2/samO2EB+YmiUPKboAIqhb0TWkNFp7d86xpplQTcwBcT2shz/QuUov6v5xi0
+sZAhma34BpptweE79IVpkW1ohJ/pCTAI9hGHmWePFsxZQziVXvqdxUotVfI9Gklc
+EmbqQC2h3ghApLPcGYojBKbPppsu0Co8X/pMu1pi0Auk9owGQlS0xmPg8fARqOxX
+PZNsDGelWopSxTe2w35UBbCC2TKKpxKDOdm8gc7b6a3pt10dbTo=
 -----END CERTIFICATE-----
diff --git a/net/data/ssl/certificates/client_2.key b/net/data/ssl/certificates/client_2.key
index e10b152..92cae727 100644
--- a/net/data/ssl/certificates/client_2.key
+++ b/net/data/ssl/certificates/client_2.key
@@ -1,27 +1,27 @@
 -----BEGIN RSA PRIVATE KEY-----
-MIIEowIBAAKCAQEA68lLXfm1qfzrGYiXtXmYfa/gwbcSGLTcu3VTD9Cow2A465PP
-wp6bs6Qu3eFgwr7mceQ72pU410+zEwxo1bqHorcc1qhemDBLEaL5cu1KEyw3GN97
-kJTxOMR4zahR8IvDpnYRzjTtmZOuLUpZ7Lo3oOouLDQ6OpoOw9mLu2I7RtVc8cQC
-iyOnQVWKeSbDQ/+or/m3DUbQq+Wyg9TTjDWAAbqxu3mP5Jf8nd8I/xAbRxe0jBSW
-8hiZ++Yxjo/kLVkI+s4TBFVV3dau2b5oHGMsFoBFCaTIyE+4KZAKZAdptvxuh1ic
-F/GhSZy3+H1w122uYmq7KA7pG32sBaQUl0iwnQIDAQABAoIBAGNOKlHwI9TuUs40
-O0ERb2owMwcjZZnGQtko9szIYuu2kQKXBH/BcW5djeehTrF22XPKXnMXOhNk29T/
-+v9ZSlr7qEe4Le8HF/bbnxgKXJJqouH07gPc1yPDi+WCKNCY7NQlEia5IAD4s/kb
-QXh0jY1WVBAGByg7TlCqRTGsk66myy3qA7Ii65Y1upiGFfDczpQL5mUKaBTjz3HC
-/DMr4GRuFOw5NkhELu9SOENZGSwuzpk6gNDVYDXJ+uo9bvH9EIB9S1KIoAoa+yr2
-L9LUcG9vwOuMNh7qN66nAGxGzoI8qh6kHVgfyTcF11NwaFutSIsGQTRKeANxiq2I
-IkbT3EECgYEA/QGxkv9iC/oJfe9gWlUeEFJsqlmLp2ii0HrH9KnywT5sgicd0//3
-eCU1KI8LygABbHb3hmFQRAwf2gFq0u1MBqXQQ4nVsrNtPVzNGGOkfk5T9DIu4vBN
-L9Qw29ULYDbaHaC1BFymwnMsOOsKctiMmsiklhyCWBczcHmE+gn+6ykCgYEA7pNx
-on/qgrCp9P8mMdBqjOmc5740Pbqu5JShYJkja1fv7IVLhGEuifdwGWge6ZfjaXPV
-wq7P7mbXa2Dreqc0LkxUrdAffZitsXckhNswSDToZzf7JB9GAnkcMKlLcJHbO0Kf
-jJALGpPknLg8XbpqsT+/GAS1GBNbL4Rz/MovPFUCgYBkJEt494SDYRBovFrS5mXj
-5/wC4TaZqJzpD/AdMzdWrbKdQYZY5zO4ZmHID/aGmcH2gJAwrEvs4y+oRm9V1X8G
-EpOAaAohlUtjwlubj7UIGVC5kzNjt+GVUNOV75l1F8D1gSqk81c+GAAk90NHedcN
-XOVoVRhybZx6pF6x6UrxIQKBgDc8EbIClYO+bQrYy7n6u8B2Eaqhoays/PLU6mvX
-6Jhgmp6S2cIDUegFToHDVmzUioUOmW3iVSenzbYBkWMrNOyHJY+8QJ4ubABLSjws
-FwiQn0HOdymMyAOokHs/psSgMDaPHStI6hk0JliWWvuEPlFdJdvksxyo1pKwwr3C
-/Z6lAoGBAIr0S/O5rYrEHchJ6yr+YtJa6vIowOSUvijG2L4ghVY63v/Ke5vzwmOZ
-wuPh0D6atpKPIq5p3eGlgq12cJHGwaybVP9C3C9vD+MlhMttOy7Ez9aVFILE9nt/
-hSrOTRwYYXLs0txl7K40Ja2hjIRXw1TQU37V4wADNa+GhPpUfg9y
+MIIEpAIBAAKCAQEA4IzClfxmgklkJHuaB4JlLIR6Z8ehIjoJ868C8YA5I23PDxHI
+G6W+l3F98IFAaO41q4VU/IimBRMIRiGZOkHgBi/NQS1nu11IQKxl1azljs2zvzLC
+V9j220CNyDqvsxv13/26W+rbjsZ+0VdIN+lh6RY9AhhDcA5BvN6vjZOFR02ypIin
+oSOKnhZOMLRVsosPuKS1qlaXCrWD8Z7n1tD4koZ6+9YiYCVgZ7pKNTIS8kR8b3Pj
+pm+8Q+FVR+HZWoYySE1n/w6vDmK47TUUI2vdBHpnKbis//DjVHrsDQ1ZqqvxRwDS
+FLtIoMwuMyO3rWuqsa2FnvgJbvA9XD4Pv3F3jwIDAQABAoIBAQCTe2ACarhZMiLX
+42aTMA2LY6eRqggnFr+akYP5YiIlJuYsG522qvG3Pg9de0b2pB4T/YqIIqgIBSwW
+A9ND9ChTZ+oDuPK8mNPvxktMQDa1yF0aYxhJ4nKgJpH4xLLJjL+80kUoQeTarXx1
+ukHwlxR7puODELSaUILUrd3XuuB6p06I3KBIzkGx0BqVRFmCk/nAaCZLA8WJcUmD
+rfYFPTc/2Jm7xH+Wzhd86evT1yIpTCu7VNdXuzFHLFesxeFSb49cRrJLlKEWT3B8
+7jRjhqclZvJ2jTvMEx8I48vIW40jrs5dGWFqzYRo0rbelI/BRwDQsGEDyHLwZdRG
+qAg158bhAoGBAPLAr2sGQhI0+v5GWMuqELgCJlqmDP9gP/6pU2E8CkmTefu8MsVx
+UzFaAN+WFr0wqpVuCTVczSZSF10/SwM4mNsTb6vc9CQ9uK655vTIiFLR8NTZOxAK
+sVyJKCRB0Ejf9nufSJaLZetW3QQTxWLmrhmVjKPjJOYsKLHfye3Oz7VLAoGBAOzN
+xt1Fgi2XgnASI+D3e7hwa/9obfCPdwB1kdyPq8A2sZBTzGdnixY5IcbwQmK4Ekuj
+d9gnaRqg/WKUoR/5PduYvxo1JErBh+itu/mdSpSd71465Do/Q5mQbV+MAnyWTPak
+mtBKs6W22Sk1+NSuoA4mX+oC8m29uDho8b+bIdBNAoGAWXTmcAM7X+hEQmX8HPmL
+9bNdHPSqP4Xhr2AIyQFOLTT6s+jzsM0FQl+PiNWPhaKkijKllBOhyihgUc2cQBCg
+S8NK2MOw+JYCM+lwEe7ARfz1ygpPeKboG1i0AUB7mA9ojr/xCQFPyr0U74a1q6+k
+our4jACNvYCycnIswMUAyCcCgYBh/vJKBYbOuUFogYlJgwE3HYcD5kKA5832abEY
+FnicDcZDlPok3KupYbFBs5G1arlfheGFmSGcvHy/fASFx846fyaugMlpClflCWid
+7uK7R/SUCUkDdcTS2vr4LGenCUgGVa4ffpqDfHy32jcERNPFp0nP/LI4ieefqIZK
+pbdDjQKBgQCEqdGn6ZB+dg3i2RK544RfNqQaVmDw0czmxl3xRnUEfElA7ZSmE4Lt
+Dx9bmXoXYAjMz3Elh3+3pIq4BjlKsPK18zZPAGQnVxoSnUtW9tVI+bc/yFk2irfo
+UtSDxMR8dcUd4vjE2WHIgBnJEbGj+PkMqjMimMZqQDhr4UI2OTe7Zw==
 -----END RSA PRIVATE KEY-----
diff --git a/net/data/ssl/certificates/client_2.pem b/net/data/ssl/certificates/client_2.pem
index 1f7a03a..abc9dde 100644
--- a/net/data/ssl/certificates/client_2.pem
+++ b/net/data/ssl/certificates/client_2.pem
@@ -5,31 +5,31 @@
     Signature Algorithm: sha256WithRSAEncryption
         Issuer: CN=E CA
         Validity
-            Not Before: Oct  4 18:53:24 2016 GMT
-            Not After : Oct  2 18:53:24 2026 GMT
+            Not Before: Dec  9 20:18:57 2016 GMT
+            Not After : Dec  7 20:18:57 2026 GMT
         Subject: CN=Client Cert D
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
                 Public-Key: (2048 bit)
                 Modulus:
-                    00:eb:c9:4b:5d:f9:b5:a9:fc:eb:19:88:97:b5:79:
-                    98:7d:af:e0:c1:b7:12:18:b4:dc:bb:75:53:0f:d0:
-                    a8:c3:60:38:eb:93:cf:c2:9e:9b:b3:a4:2e:dd:e1:
-                    60:c2:be:e6:71:e4:3b:da:95:38:d7:4f:b3:13:0c:
-                    68:d5:ba:87:a2:b7:1c:d6:a8:5e:98:30:4b:11:a2:
-                    f9:72:ed:4a:13:2c:37:18:df:7b:90:94:f1:38:c4:
-                    78:cd:a8:51:f0:8b:c3:a6:76:11:ce:34:ed:99:93:
-                    ae:2d:4a:59:ec:ba:37:a0:ea:2e:2c:34:3a:3a:9a:
-                    0e:c3:d9:8b:bb:62:3b:46:d5:5c:f1:c4:02:8b:23:
-                    a7:41:55:8a:79:26:c3:43:ff:a8:af:f9:b7:0d:46:
-                    d0:ab:e5:b2:83:d4:d3:8c:35:80:01:ba:b1:bb:79:
-                    8f:e4:97:fc:9d:df:08:ff:10:1b:47:17:b4:8c:14:
-                    96:f2:18:99:fb:e6:31:8e:8f:e4:2d:59:08:fa:ce:
-                    13:04:55:55:dd:d6:ae:d9:be:68:1c:63:2c:16:80:
-                    45:09:a4:c8:c8:4f:b8:29:90:0a:64:07:69:b6:fc:
-                    6e:87:58:9c:17:f1:a1:49:9c:b7:f8:7d:70:d7:6d:
-                    ae:62:6a:bb:28:0e:e9:1b:7d:ac:05:a4:14:97:48:
-                    b0:9d
+                    00:e0:8c:c2:95:fc:66:82:49:64:24:7b:9a:07:82:
+                    65:2c:84:7a:67:c7:a1:22:3a:09:f3:af:02:f1:80:
+                    39:23:6d:cf:0f:11:c8:1b:a5:be:97:71:7d:f0:81:
+                    40:68:ee:35:ab:85:54:fc:88:a6:05:13:08:46:21:
+                    99:3a:41:e0:06:2f:cd:41:2d:67:bb:5d:48:40:ac:
+                    65:d5:ac:e5:8e:cd:b3:bf:32:c2:57:d8:f6:db:40:
+                    8d:c8:3a:af:b3:1b:f5:df:fd:ba:5b:ea:db:8e:c6:
+                    7e:d1:57:48:37:e9:61:e9:16:3d:02:18:43:70:0e:
+                    41:bc:de:af:8d:93:85:47:4d:b2:a4:88:a7:a1:23:
+                    8a:9e:16:4e:30:b4:55:b2:8b:0f:b8:a4:b5:aa:56:
+                    97:0a:b5:83:f1:9e:e7:d6:d0:f8:92:86:7a:fb:d6:
+                    22:60:25:60:67:ba:4a:35:32:12:f2:44:7c:6f:73:
+                    e3:a6:6f:bc:43:e1:55:47:e1:d9:5a:86:32:48:4d:
+                    67:ff:0e:af:0e:62:b8:ed:35:14:23:6b:dd:04:7a:
+                    67:29:b8:ac:ff:f0:e3:54:7a:ec:0d:0d:59:aa:ab:
+                    f1:47:00:d2:14:bb:48:a0:cc:2e:33:23:b7:ad:6b:
+                    aa:b1:ad:85:9e:f8:09:6e:f0:3d:5c:3e:0f:bf:71:
+                    77:8f
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Basic Constraints: critical
@@ -37,36 +37,36 @@
             X509v3 Extended Key Usage: 
                 TLS Web Server Authentication, TLS Web Client Authentication
     Signature Algorithm: sha256WithRSAEncryption
-         9f:d0:6e:8b:08:58:16:b5:78:3f:05:bb:59:bc:cf:74:1c:88:
-         b0:7e:10:c5:71:9d:b5:08:05:59:ca:f0:c8:64:49:96:82:8b:
-         14:0c:da:9d:be:a2:8b:37:df:e1:69:bc:8e:f4:be:80:3f:f9:
-         8a:1d:7a:70:37:3c:18:a0:92:27:10:e3:74:ca:fa:b8:db:f2:
-         c6:a5:32:66:85:88:29:3a:4e:64:95:85:b4:43:37:8a:6d:48:
-         f4:12:2f:b2:d0:66:c9:b7:88:ad:b8:a7:1f:97:59:bf:d9:0d:
-         d6:ce:ff:5f:75:2f:d2:e0:69:c8:d6:17:b9:fd:3c:ed:fd:1f:
-         47:14:f8:ef:0b:33:2a:1c:14:25:d1:82:90:d3:67:1b:ea:b0:
-         f7:5b:78:a9:9d:28:1b:d3:cd:8d:bd:30:c2:7e:12:32:dd:83:
-         cc:57:47:b3:e7:0c:79:b5:f8:a0:f4:f0:d8:29:1b:9b:fb:2f:
-         a9:1c:cb:a9:84:14:29:c7:23:b8:85:88:d9:78:5f:c7:a4:c6:
-         1b:bd:6e:70:2e:a2:be:31:98:c7:9c:35:1d:44:59:f8:31:83:
-         87:ee:a9:c7:ab:f5:6f:e6:8a:cc:49:5f:23:fd:7c:a4:61:01:
-         9b:51:d8:b0:85:9a:bf:1d:9d:62:3e:b0:7c:e0:5e:57:ed:69:
-         3c:f3:8c:54
+         95:de:33:2f:e2:11:c2:6d:64:4a:5f:98:69:cb:a3:c6:bd:a1:
+         0f:00:9c:32:c8:83:c7:05:14:21:e3:ab:fa:7a:f8:43:36:95:
+         6c:85:8b:b5:ee:2c:fc:4b:77:95:8a:bf:2f:89:c1:cc:c2:21:
+         99:40:c4:01:be:2a:4a:5b:d9:61:06:16:b0:5d:3f:27:ad:e3:
+         57:5c:41:89:fb:3b:dc:73:45:ac:05:e2:dd:89:95:74:09:30:
+         68:3c:3f:e8:bc:e6:94:4a:ed:4c:74:90:ad:a0:a4:97:c0:04:
+         9b:13:81:a5:24:76:db:4c:49:8f:80:f9:7c:7f:8b:f9:de:45:
+         65:5d:03:b2:c7:99:3b:56:b1:f8:29:7e:b4:69:fe:f9:29:b3:
+         b6:59:bd:51:b1:02:97:5b:db:29:5e:9a:b5:1f:75:42:0f:7e:
+         58:bc:e3:3f:39:ea:7b:12:c7:68:06:c0:e4:78:f4:e9:b4:9b:
+         4c:fc:94:06:a3:1a:37:8b:3d:cd:67:f9:f4:e9:87:20:6c:07:
+         71:62:85:78:35:96:9c:ef:98:59:33:50:83:7a:32:ad:22:01:
+         3a:20:05:05:05:b0:62:9d:4e:20:94:1b:05:cc:7d:bb:ba:98:
+         a0:51:d2:50:b5:cb:d8:97:0f:42:13:65:2a:14:b8:cd:f2:24:
+         5f:0e:6e:6b
 -----BEGIN CERTIFICATE-----
 MIIC0jCCAbqgAwIBAgICEAIwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwERSBD
-QTAeFw0xNjEwMDQxODUzMjRaFw0yNjEwMDIxODUzMjRaMBgxFjAUBgNVBAMMDUNs
-aWVudCBDZXJ0IEQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDryUtd
-+bWp/OsZiJe1eZh9r+DBtxIYtNy7dVMP0KjDYDjrk8/CnpuzpC7d4WDCvuZx5Dva
-lTjXT7MTDGjVuoeitxzWqF6YMEsRovly7UoTLDcY33uQlPE4xHjNqFHwi8OmdhHO
-NO2Zk64tSlnsujeg6i4sNDo6mg7D2Yu7YjtG1VzxxAKLI6dBVYp5JsND/6iv+bcN
-RtCr5bKD1NOMNYABurG7eY/kl/yd3wj/EBtHF7SMFJbyGJn75jGOj+QtWQj6zhME
-VVXd1q7ZvmgcYywWgEUJpMjIT7gpkApkB2m2/G6HWJwX8aFJnLf4fXDXba5iarso
-DukbfawFpBSXSLCdAgMBAAGjLzAtMAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYwFAYI
-KwYBBQUHAwEGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQCf0G6LCFgWtXg/
-BbtZvM90HIiwfhDFcZ21CAVZyvDIZEmWgosUDNqdvqKLN9/habyO9L6AP/mKHXpw
-NzwYoJInEON0yvq42/LGpTJmhYgpOk5klYW0QzeKbUj0Ei+y0GbJt4ituKcfl1m/
-2Q3Wzv9fdS/S4GnI1he5/Tzt/R9HFPjvCzMqHBQl0YKQ02cb6rD3W3ipnSgb082N
-vTDCfhIy3YPMV0ez5wx5tfig9PDYKRub+y+pHMuphBQpxyO4hYjZeF/HpMYbvW5w
-LqK+MZjHnDUdRFn4MYOH7qnHq/Vv5orMSV8j/XykYQGbUdiwhZq/HZ1iPrB84F5X
-7Wk884xU
+QTAeFw0xNjEyMDkyMDE4NTdaFw0yNjEyMDcyMDE4NTdaMBgxFjAUBgNVBAMMDUNs
+aWVudCBDZXJ0IEQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDgjMKV
+/GaCSWQke5oHgmUshHpnx6EiOgnzrwLxgDkjbc8PEcgbpb6XcX3wgUBo7jWrhVT8
+iKYFEwhGIZk6QeAGL81BLWe7XUhArGXVrOWOzbO/MsJX2PbbQI3IOq+zG/Xf/bpb
+6tuOxn7RV0g36WHpFj0CGENwDkG83q+Nk4VHTbKkiKehI4qeFk4wtFWyiw+4pLWq
+VpcKtYPxnufW0PiShnr71iJgJWBnuko1MhLyRHxvc+Omb7xD4VVH4dlahjJITWf/
+Dq8OYrjtNRQja90EemcpuKz/8ONUeuwNDVmqq/FHANIUu0igzC4zI7eta6qxrYWe
++Alu8D1cPg+/cXePAgMBAAGjLzAtMAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYwFAYI
+KwYBBQUHAwEGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQCV3jMv4hHCbWRK
+X5hpy6PGvaEPAJwyyIPHBRQh46v6evhDNpVshYu17iz8S3eVir8vicHMwiGZQMQB
+vipKW9lhBhawXT8nreNXXEGJ+zvcc0WsBeLdiZV0CTBoPD/ovOaUSu1MdJCtoKSX
+wASbE4GlJHbbTEmPgPl8f4v53kVlXQOyx5k7VrH4KX60af75KbO2Wb1RsQKXW9sp
+Xpq1H3VCD35YvOM/Oep7EsdoBsDkePTptJtM/JQGoxo3iz3NZ/n06YcgbAdxYoV4
+NZac75hZM1CDejKtIgE6IAUFBbBinU4glBsFzH27upigUdJQtcvYlw9CE2UqFLjN
+8iRfDm5r
 -----END CERTIFICATE-----
diff --git a/net/data/ssl/certificates/client_2.pk8 b/net/data/ssl/certificates/client_2.pk8
index 731e39c3..ad3ca5d5 100644
--- a/net/data/ssl/certificates/client_2.pk8
+++ b/net/data/ssl/certificates/client_2.pk8
Binary files differ
diff --git a/net/data/ssl/certificates/client_2_ca.pem b/net/data/ssl/certificates/client_2_ca.pem
index dd58ffa7..78080961 100644
--- a/net/data/ssl/certificates/client_2_ca.pem
+++ b/net/data/ssl/certificates/client_2_ca.pem
@@ -5,31 +5,31 @@
     Signature Algorithm: sha256WithRSAEncryption
         Issuer: CN=C Root CA
         Validity
-            Not Before: Oct  4 18:53:24 2016 GMT
-            Not After : Oct  2 18:53:24 2026 GMT
+            Not Before: Dec  9 20:18:57 2016 GMT
+            Not After : Dec  7 20:18:57 2026 GMT
         Subject: CN=E CA
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
                 Public-Key: (2048 bit)
                 Modulus:
-                    00:a2:7e:a3:fd:c1:d7:78:cd:57:ac:67:54:37:69:
-                    fb:72:6f:1d:8f:d0:47:0f:11:14:ab:42:d8:3d:6a:
-                    34:2b:d6:38:07:df:16:1d:c6:62:eb:d7:12:e1:86:
-                    83:f2:dd:8f:97:09:94:8f:1b:ff:3b:84:9b:48:e5:
-                    0d:43:6b:ae:bb:75:88:1c:c6:3a:7f:d8:12:d9:7c:
-                    12:18:6d:e2:f0:88:d4:3e:5a:93:b3:af:c1:79:a1:
-                    b6:a3:f7:56:46:21:e6:7d:6e:36:ea:ba:4b:52:f7:
-                    a9:45:0b:83:09:2c:09:22:8a:67:5a:8f:88:60:b0:
-                    11:07:25:9b:c2:6a:3c:63:4c:0e:69:45:ce:9d:ba:
-                    c9:d4:01:fb:78:56:38:08:8f:e5:d6:ff:ac:e4:04:
-                    fa:26:cf:d2:05:33:57:a3:8e:80:c0:b6:40:d5:d3:
-                    ca:85:17:30:b2:24:f4:19:af:c5:48:a4:ed:c0:49:
-                    c1:a4:b7:89:29:ba:e5:2d:37:78:1c:d6:3e:9b:03:
-                    fa:bc:7b:e2:76:a6:70:f3:1b:9d:b2:4b:fc:72:7b:
-                    77:89:50:bb:88:2f:b5:b6:a2:c7:33:27:b7:d1:1a:
-                    7c:d4:58:e3:5e:88:ca:f8:49:c3:cd:cc:0f:93:4b:
-                    3c:fd:75:c3:7b:6f:bf:d3:db:ba:2e:31:7b:a7:a5:
-                    42:c5
+                    00:c3:39:c3:5a:8e:ff:f2:1d:cc:26:91:5d:15:9e:
+                    ca:e0:fb:cf:99:5f:13:3d:c6:37:59:8b:ce:cc:76:
+                    0e:1c:9f:b6:49:5b:09:97:63:9d:e1:00:74:44:fb:
+                    2f:53:f3:d5:03:92:77:97:53:74:7e:d2:da:d3:a3:
+                    f4:c1:91:6a:83:ff:89:fe:73:46:56:ca:6d:51:0d:
+                    57:16:3d:3e:e8:fc:00:d9:4a:7a:7d:93:84:06:12:
+                    c5:ff:31:b3:a6:eb:96:18:71:b8:56:5c:2f:ab:78:
+                    e2:53:dd:15:d8:65:c8:f6:96:14:dc:15:cf:2a:39:
+                    ed:e1:08:1b:84:29:c7:1c:78:67:c8:e0:72:58:4e:
+                    33:7f:cb:ef:71:82:db:45:1d:7c:0c:d0:f5:4c:af:
+                    85:6b:14:61:50:87:34:42:fe:45:a3:3c:a3:53:57:
+                    1d:ac:11:c8:cf:2f:5e:cb:78:87:39:a1:41:3f:69:
+                    21:5c:1e:19:02:a3:6c:91:d3:1b:4e:50:fc:a4:b1:
+                    03:87:c0:58:b1:fe:cd:58:5e:53:ed:c9:d6:5d:9e:
+                    a3:fb:0d:e0:a0:8e:3d:c9:9e:9e:83:07:61:c7:30:
+                    5a:ca:29:93:04:af:5e:f3:57:2e:c2:d8:c8:ae:7f:
+                    5c:a4:27:fa:cd:55:a2:fd:89:d2:0b:87:24:6b:7b:
+                    fb:19
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Basic Constraints: critical
@@ -37,35 +37,35 @@
             X509v3 Key Usage: critical
                 Certificate Sign, CRL Sign
     Signature Algorithm: sha256WithRSAEncryption
-         92:8b:93:94:03:04:91:3f:4d:8b:f3:90:53:ee:73:b5:33:c7:
-         61:ea:0f:a5:59:9b:f0:0d:4f:7d:48:0d:5a:58:e7:1f:68:f6:
-         d6:58:75:33:a5:d2:b7:65:6a:28:40:bc:0e:1e:78:ee:9a:13:
-         3c:b0:8b:8f:98:72:86:50:3a:a3:bf:6d:f0:21:95:a8:73:d0:
-         dd:e5:0e:25:b1:62:76:65:69:1f:ee:26:82:ab:be:a4:a8:30:
-         a7:41:34:07:57:2f:8b:ab:25:af:cb:23:a5:79:cf:b2:a2:17:
-         02:a7:aa:50:92:6e:0d:9b:ff:c9:22:38:b4:0f:47:94:d2:80:
-         7f:92:30:00:ec:5b:22:e2:a6:71:5e:e8:8f:0d:2f:38:2c:29:
-         47:6a:7f:20:0a:e2:42:cb:b7:6e:2b:29:0f:03:55:94:84:5f:
-         e7:47:bf:ae:75:88:05:4e:42:ac:78:57:9d:9c:e2:77:d2:17:
-         42:55:ba:f8:77:ee:61:d6:e8:ec:aa:e0:7a:a6:65:c6:35:80:
-         08:3d:39:a6:70:8c:9e:6d:7a:ee:e7:cf:36:46:98:00:c8:7b:
-         b8:84:7f:9d:9f:bd:31:4f:99:25:6e:76:9a:5d:46:3e:40:70:
-         c6:a8:03:f3:98:9c:be:fb:f6:ad:c2:8d:e3:f9:7d:93:3a:78:
-         da:b3:d7:dc
+         67:d4:6c:cf:cd:54:81:67:2a:c2:c4:66:c7:76:9c:b0:8b:6b:
+         ef:b8:ae:a9:b3:d6:f8:47:91:d5:97:0b:bd:1a:87:21:8c:ce:
+         be:0c:80:d5:a5:25:0d:0a:c7:ed:be:cb:8c:6d:08:e8:de:a5:
+         33:89:e6:87:df:2b:f4:54:b3:c2:94:15:0d:36:5e:1a:aa:c0:
+         b0:03:3c:24:c6:a1:81:91:ca:fe:db:0f:59:1b:d6:4e:48:0b:
+         52:d3:e7:07:d7:b1:ca:b2:22:e4:d4:37:a4:3c:87:3c:0a:11:
+         a6:10:2a:ed:86:2a:bb:db:10:7e:f3:a5:fc:10:ab:80:5b:07:
+         58:7c:22:76:3e:9b:9c:72:79:0d:dc:85:f8:e7:c2:0f:17:aa:
+         01:dd:8e:24:27:77:4e:23:03:da:88:e0:df:e6:ca:b4:84:56:
+         a1:dc:9f:e0:93:94:97:d2:98:cd:32:6d:73:84:f9:3e:4c:96:
+         b3:51:07:b8:9f:66:32:d1:ac:53:0e:17:a9:6f:29:d1:7b:73:
+         b3:55:9b:cc:8f:8b:e5:49:fd:fd:f2:30:d6:d0:f7:03:06:12:
+         e3:66:2d:0d:a1:da:28:04:04:29:b8:40:6e:0e:6f:31:48:cb:
+         54:f7:e2:89:22:d8:05:e0:f5:7e:48:b3:96:ff:6b:ef:e7:fe:
+         71:1d:0b:77
 -----BEGIN CERTIFICATE-----
 MIICwjCCAaqgAwIBAgICEAIwDQYJKoZIhvcNAQELBQAwFDESMBAGA1UEAwwJQyBS
-b290IENBMB4XDTE2MTAwNDE4NTMyNFoXDTI2MTAwMjE4NTMyNFowDzENMAsGA1UE
-AwwERSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKJ+o/3B13jN
-V6xnVDdp+3JvHY/QRw8RFKtC2D1qNCvWOAffFh3GYuvXEuGGg/Ldj5cJlI8b/zuE
-m0jlDUNrrrt1iBzGOn/YEtl8Ehht4vCI1D5ak7OvwXmhtqP3VkYh5n1uNuq6S1L3
-qUULgwksCSKKZ1qPiGCwEQclm8JqPGNMDmlFzp26ydQB+3hWOAiP5db/rOQE+ibP
-0gUzV6OOgMC2QNXTyoUXMLIk9BmvxUik7cBJwaS3iSm65S03eBzWPpsD+rx74nam
-cPMbnbJL/HJ7d4lQu4gvtbaixzMnt9EafNRY416IyvhJw83MD5NLPP11w3tvv9Pb
-ui4xe6elQsUCAwEAAaMjMCEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
-AQYwDQYJKoZIhvcNAQELBQADggEBAJKLk5QDBJE/TYvzkFPuc7Uzx2HqD6VZm/AN
-T31IDVpY5x9o9tZYdTOl0rdlaihAvA4eeO6aEzywi4+YcoZQOqO/bfAhlahz0N3l
-DiWxYnZlaR/uJoKrvqSoMKdBNAdXL4urJa/LI6V5z7KiFwKnqlCSbg2b/8kiOLQP
-R5TSgH+SMADsWyLipnFe6I8NLzgsKUdqfyAK4kLLt24rKQ8DVZSEX+dHv651iAVO
-Qqx4V52c4nfSF0JVuvh37mHW6Oyq4HqmZcY1gAg9OaZwjJ5teu7nzzZGmADIe7iE
-f52fvTFPmSVudppdRj5AcMaoA/OYnL779q3CjeP5fZM6eNqz19w=
+b290IENBMB4XDTE2MTIwOTIwMTg1N1oXDTI2MTIwNzIwMTg1N1owDzENMAsGA1UE
+AwwERSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMM5w1qO//Id
+zCaRXRWeyuD7z5lfEz3GN1mLzsx2DhyftklbCZdjneEAdET7L1Pz1QOSd5dTdH7S
+2tOj9MGRaoP/if5zRlbKbVENVxY9Puj8ANlKen2ThAYSxf8xs6brlhhxuFZcL6t4
+4lPdFdhlyPaWFNwVzyo57eEIG4Qpxxx4Z8jgclhOM3/L73GC20UdfAzQ9UyvhWsU
+YVCHNEL+RaM8o1NXHawRyM8vXst4hzmhQT9pIVweGQKjbJHTG05Q/KSxA4fAWLH+
+zVheU+3J1l2eo/sN4KCOPcmenoMHYccwWsopkwSvXvNXLsLYyK5/XKQn+s1Vov2J
+0guHJGt7+xkCAwEAAaMjMCEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
+AQYwDQYJKoZIhvcNAQELBQADggEBAGfUbM/NVIFnKsLEZsd2nLCLa++4rqmz1vhH
+kdWXC70ahyGMzr4MgNWlJQ0Kx+2+y4xtCOjepTOJ5offK/RUs8KUFQ02XhqqwLAD
+PCTGoYGRyv7bD1kb1k5IC1LT5wfXscqyIuTUN6Q8hzwKEaYQKu2GKrvbEH7zpfwQ
+q4BbB1h8InY+m5xyeQ3chfjnwg8XqgHdjiQnd04jA9qI4N/myrSEVqHcn+CTlJfS
+mM0ybXOE+T5MlrNRB7ifZjLRrFMOF6lvKdF7c7NVm8yPi+VJ/f3yMNbQ9wMGEuNm
+LQ2h2igEBCm4QG4ObzFIy1T34oki2AXg9X5Is5b/a+/n/nEdC3c=
 -----END CERTIFICATE-----
diff --git a/net/data/ssl/certificates/client_3.key b/net/data/ssl/certificates/client_3.key
index 20498ba..c2b341fe 100644
--- a/net/data/ssl/certificates/client_3.key
+++ b/net/data/ssl/certificates/client_3.key
@@ -1,27 +1,27 @@
 -----BEGIN RSA PRIVATE KEY-----
-MIIEpAIBAAKCAQEAqblhT1L+ZDRTZ0fYWCIjgpdv0ILn9ws9204VFTjf3jU+66wZ
-m9iN2+j62y/68iBFkt/107YqA2so3o0kS6o7Izt+EQg+o5ZvvHM3fVSR/IGejHbt
-1fbk9o7oblbikOtRpfOQ2EXZ+h2RASE6YTE66lrE6RruAOaWYsoLpzepHDlOEj6t
-q+24LIalckzKOQNNYfwpuLzbMomVCmIaKNaObesGM5pbj+hz4S8ehCH7CzgnsYOg
-x/7tecyrV6XPW7OEDLm4GoyQIlnxvk1GDIVje6caSW+OzqL65SlkAwLcaN95tmub
-IgdZr6H/upzmXdRh3kCBLgKWAqpUJNSzxBjj/wIDAQABAoIBACvRiKYKL1N/jujj
-S5+1cKWOo3eZ1HmblWTBTAAmpuWfqZb+3720sytLgziDsq5AVrYMzFLUfRRU3kBX
-AD/ou0vlWC7dig6CEGb++ByLcQVYEa8CJXVQQNzHGIskM2pm1rWZpJOxtQ02BPHd
-ukzNgQBwXtYv9bKV1c27jDan0ClQ1nj14TK8k2LLCDYd3O9Zbfm+5fKqsJIjDFm6
-rPeltV8yFBsZPxBJAQUNTR0fnq5mYLrCm8ARWYbLxbbWSjInXStrwVuaG8P/T7Om
-sl6Jj7eRClM6HrCtJMukgAQ1f6Rg882MVKKv8sjVO0ZHIZrg+e3TLPLrngXYeLxP
-NgrJgUECgYEA2J5Ee5cVyvbJITD71dVHcZc8QcaBVFBsSCcw0ZQ4LgUmS/z3ERYq
-mpdXzU1bTAOOMujOjiv9qYXn800DqRiDML384/cQz9DNkUth2eSQjk2Ryp9x5z+Y
-CeeMrzTtPK+SRfbC12UnNkZqwg+OrVgQUswbgOt2tM/9Bx5ujo6kuDsCgYEAyJSX
-ouGtWU7wys3ffmrmYlc0G/hGXxvqunpD8YR61fxyIMb1M9FfqObbCWaD7tkboEfe
-u6l7+d+4eJO2Gv++68asqHPsNQeq0qqAVPVNVusD+Uw9DPK4yxfbtn0lbALikCAB
-VT4yudolYsZA0b6tHApSG2bZkr3lXSwLFmljCw0CgYEAtT3m6smE8Gb/7geADm/+
-8Omq/xXJy/PmRZCU5iXvw4GHg3jKd79mMiaCzkH1K2qmJa5odMgV2ysw4X8Emwzp
-Z3TvDQYBSP/Zn8HEw3zb/lSksTYrJWMuIMteCJJuFKKJ7oQCjhoSbvUICgreQ+c0
-8THZqUpZ7ftAKB6sPhbXd1UCgYEAsYjL+nBTtcOoX2j/U26dAhf7WHJVHyOfjHRh
-pOjErJhoD9jp+XZtfBrxbo2dYxApYqGaZHHr+MvrBFaBjb4lp5zO/76zKHDj4tjl
-A82nKbKUbtjrBIXlyGUSpKB6OfMHw9eANon57gRGqPmfL8bchAAiknxjQX3xAJnW
-Kn0XHBUCgYAnpq1dGwdknEcVnVMsoZQirc6UK39u8KIH6S7P2QhSzc6pXOeC8HGj
-H6zvc3LtddSj8tCWfGDGVWp4v9TIWHOZbmmg20iU93j7Xi53cL3zB6TaAa467tj9
-0JFgB4tk1zKLggwkF26Sf3m+kkPDGwm4+jmk8TfV7VZ9yCZQY5Onig==
+MIIEpQIBAAKCAQEAs1wyu8BIKDebRat4oOpyEyZdRu5xxCSc7ai2gTXXcroKrqlO
+IGESIuAAZ4BwvqzvA7LUsDr8xauFewRLYYV6F2xDNmcLGXx0uGXpHP3w30K8DP0J
+fk99OMBSceUrGYCCqmnCNmu3LQf0dGK/jpDtRxpkJKxMuNIq0J2GCMEYnj7eTxJc
+ZKQrhkMSgWcMjFbkFkY8Kc9OGOpPZl+01nNfHpOt38kGZczcQrrphkIIoaul/CLT
+I1eg2myA3sX5nMURZZyy3/PWyL2qr0Bm7c5fBEYX5pLqZMiz5CDL4EQJFR985OAH
+zSJ8vaAGZTXUPhwHYY8BUyIlhZN1c0LHwcASnwIDAQABAoIBAQCxZ/WKfdMhbHb5
+v3ROffadeGn0ue7vWmOaMzFpto7HHLtqLW5oWnts4XGk7ocWIsk7OExlj8Lr5g7e
+Mc45xKORvXTxv5Rb/h0ZMzwTgB4bRs/obPRR6l/qnVgu7cTmsZUM6BTAbWS+dsrV
+v8LHShRYKwN4vrAYc1EEDXtA93XZNp9OBsVRdHJbeV4PIXqdzr3lScbXHNNs+dSF
+i6pZ/VrCHWmp9H1NXQuicAHr5aTvRMvFpfNtFSpOo7xEX+4cbVTk2b5TwxBa5TTj
+oew8/h2IsU1OmytQ1zya9Xtpw9GIMOnWg5Ce2dAyoBIkmhQwYcJyYTMM34vul/eD
+k0u0cxFxAoGBAOPM4x1mjD6tuQHFYBivBySU1CpdI0taem3GCijCUj/7tHPA+7FZ
++DhtnYF4b9q/X9EHRoosCWY07/tImYZT7ziiEFITRZL/m/hA239M9zuop7+9Tp3W
+M2oTkTGQOn5qKNg8TplYinpHmpGD7VURUczsdmo28rgp9Ubu1h5CwHv3AoGBAMmQ
+Nz/wgVCPVnZ66AsHiwLcAZ99aZg5961XVgyUXpWSQ0wNYKYWsYwYhYCeVRmwImSA
+NavYq0+AxTgnZrwhXXkvKXYfkLhh6aePRqyPaT3AUfp4akNe/S24HW3zO9Z0BzG6
+Ca8+oERpQ6hZ92WB1yikVoUqIaw+oIn5mzjkouSZAoGBAJ7z/p4rSj0KN4gW06El
+sJREDW+qIdCYx8kFYV1jisT+u8HxrS7pmpy1UCxhf5th4lgW/Y+4fq6EzdfHpujm
+dIxN+ZlrvSZ/mbO2ffLsH6/PVY4jaFIWfzXLhYrSGx7OsMWB/05dS/NbN23GYrrz
+JOMbNN2UjfUXwgDG8z2WUn2tAoGAbzJzeH+7J3FcNtLJTsRjiTlMX+t1JLjeDa//
+1cLIh2WAYOWEazxbyLkCdZljw18rKhyc/2fx4lNc+gSqpaEWizNcgUEaus2xdHIT
+gEFBwwJld3OU1AQEUoOfILguS7oI+gLzMs2u5u7Xl3nChSpjQ5Wd8arzlq2aLWQZ
+oQJpZwkCgYEAt1rJPy0pThzwYvpYEiYS2HmVEa7PWvtD19qDPOC6AaoPJzmP3J4u
+KmJXdk6g01R8G/QMb52V9Uen9m8YcCRyZqTTjWUDH7fDpuS7M+OkeRX/ytp4TCL0
+WejDMpu98bDTWvUBXdzQfUhwAVb/CMpX4rLtRdLZt8JT14OCDbpgogE=
 -----END RSA PRIVATE KEY-----
diff --git a/net/data/ssl/certificates/client_3.pem b/net/data/ssl/certificates/client_3.pem
index 4f5ad24..ccd6022 100644
--- a/net/data/ssl/certificates/client_3.pem
+++ b/net/data/ssl/certificates/client_3.pem
@@ -5,66 +5,66 @@
     Signature Algorithm: sha256WithRSAEncryption
         Issuer: CN=E CA
         Validity
-            Not Before: Oct  4 18:53:24 2016 GMT
-            Not After : Oct  2 18:53:24 2026 GMT
+            Not Before: Dec  9 20:18:57 2016 GMT
+            Not After : Dec  7 20:18:57 2026 GMT
         Subject: CN=Client Cert F
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
                 Public-Key: (2048 bit)
                 Modulus:
-                    00:a9:b9:61:4f:52:fe:64:34:53:67:47:d8:58:22:
-                    23:82:97:6f:d0:82:e7:f7:0b:3d:db:4e:15:15:38:
-                    df:de:35:3e:eb:ac:19:9b:d8:8d:db:e8:fa:db:2f:
-                    fa:f2:20:45:92:df:f5:d3:b6:2a:03:6b:28:de:8d:
-                    24:4b:aa:3b:23:3b:7e:11:08:3e:a3:96:6f:bc:73:
-                    37:7d:54:91:fc:81:9e:8c:76:ed:d5:f6:e4:f6:8e:
-                    e8:6e:56:e2:90:eb:51:a5:f3:90:d8:45:d9:fa:1d:
-                    91:01:21:3a:61:31:3a:ea:5a:c4:e9:1a:ee:00:e6:
-                    96:62:ca:0b:a7:37:a9:1c:39:4e:12:3e:ad:ab:ed:
-                    b8:2c:86:a5:72:4c:ca:39:03:4d:61:fc:29:b8:bc:
-                    db:32:89:95:0a:62:1a:28:d6:8e:6d:eb:06:33:9a:
-                    5b:8f:e8:73:e1:2f:1e:84:21:fb:0b:38:27:b1:83:
-                    a0:c7:fe:ed:79:cc:ab:57:a5:cf:5b:b3:84:0c:b9:
-                    b8:1a:8c:90:22:59:f1:be:4d:46:0c:85:63:7b:a7:
-                    1a:49:6f:8e:ce:a2:fa:e5:29:64:03:02:dc:68:df:
-                    79:b6:6b:9b:22:07:59:af:a1:ff:ba:9c:e6:5d:d4:
-                    61:de:40:81:2e:02:96:02:aa:54:24:d4:b3:c4:18:
-                    e3:ff
+                    00:b3:5c:32:bb:c0:48:28:37:9b:45:ab:78:a0:ea:
+                    72:13:26:5d:46:ee:71:c4:24:9c:ed:a8:b6:81:35:
+                    d7:72:ba:0a:ae:a9:4e:20:61:12:22:e0:00:67:80:
+                    70:be:ac:ef:03:b2:d4:b0:3a:fc:c5:ab:85:7b:04:
+                    4b:61:85:7a:17:6c:43:36:67:0b:19:7c:74:b8:65:
+                    e9:1c:fd:f0:df:42:bc:0c:fd:09:7e:4f:7d:38:c0:
+                    52:71:e5:2b:19:80:82:aa:69:c2:36:6b:b7:2d:07:
+                    f4:74:62:bf:8e:90:ed:47:1a:64:24:ac:4c:b8:d2:
+                    2a:d0:9d:86:08:c1:18:9e:3e:de:4f:12:5c:64:a4:
+                    2b:86:43:12:81:67:0c:8c:56:e4:16:46:3c:29:cf:
+                    4e:18:ea:4f:66:5f:b4:d6:73:5f:1e:93:ad:df:c9:
+                    06:65:cc:dc:42:ba:e9:86:42:08:a1:ab:a5:fc:22:
+                    d3:23:57:a0:da:6c:80:de:c5:f9:9c:c5:11:65:9c:
+                    b2:df:f3:d6:c8:bd:aa:af:40:66:ed:ce:5f:04:46:
+                    17:e6:92:ea:64:c8:b3:e4:20:cb:e0:44:09:15:1f:
+                    7c:e4:e0:07:cd:22:7c:bd:a0:06:65:35:d4:3e:1c:
+                    07:61:8f:01:53:22:25:85:93:75:73:42:c7:c1:c0:
+                    12:9f
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Subject Alternative Name: 
                 email:santest@example.com, othername:<unsupported>
     Signature Algorithm: sha256WithRSAEncryption
-         5f:d8:99:71:11:d1:1f:ae:7e:4a:fa:85:ff:f6:18:60:e0:c3:
-         e8:8c:8d:7b:51:b9:ed:ea:26:e8:2b:ff:d8:5c:1e:98:cb:c6:
-         a5:e8:ef:21:af:e5:a8:f2:47:93:5e:36:66:21:7d:84:c7:b2:
-         2c:70:31:71:67:88:c4:a9:45:c1:20:1b:e1:47:df:75:d6:83:
-         a2:db:45:27:ca:fa:b1:11:b0:c2:33:bc:a7:2c:fb:bd:2b:06:
-         68:0d:95:4c:d4:2f:ab:2a:5b:f8:92:4e:9b:74:30:f2:8d:7c:
-         26:c7:f1:0f:0e:f7:f1:28:b6:84:90:db:ac:a0:1a:84:4c:3e:
-         0b:14:39:de:90:ca:58:2c:f8:16:a4:0e:4d:cd:ba:c5:1d:bb:
-         91:69:a6:55:83:96:20:ee:1f:33:58:8f:da:44:32:9b:84:1e:
-         99:d3:74:60:c9:10:67:5c:a9:03:11:74:e3:82:85:99:4c:aa:
-         4e:3d:ee:ac:91:7c:e8:b9:b1:64:08:45:48:6f:34:f4:52:8a:
-         68:f9:80:6b:5b:b2:af:83:cb:fc:77:fd:9f:d0:aa:69:3e:bd:
-         f7:ca:05:17:f8:f4:39:d3:58:9a:04:81:43:a8:b3:66:90:9e:
-         b6:27:b3:1c:25:ad:8f:8c:c6:45:a4:f6:02:60:3a:0b:5e:6f:
-         6b:e6:1b:3f
+         98:4b:03:9b:ef:b9:8b:47:81:42:9c:5b:a0:49:54:2e:e1:95:
+         51:87:9c:5c:83:b1:3c:ab:21:29:7e:e0:de:11:92:ad:75:5e:
+         9d:e2:51:70:0e:95:e3:68:3f:2e:ad:69:50:31:57:6b:6d:7b:
+         6c:d2:c5:4b:e5:a7:a1:20:ba:bf:1a:8e:86:47:94:72:35:34:
+         07:5f:1a:cf:3f:13:ad:53:7f:6b:db:ef:d8:00:a2:5c:e9:5c:
+         20:47:5a:9e:f6:91:c5:9b:05:69:f3:25:05:e2:8b:dd:d8:41:
+         99:64:44:ed:74:e2:eb:f7:42:2c:b5:d0:f1:ac:64:c0:f4:87:
+         e9:3e:51:52:41:a3:c2:4e:58:c2:ee:fe:b4:25:37:b9:3d:c2:
+         f0:cf:c0:90:7f:f6:02:b2:38:88:92:2a:e0:d4:db:87:5c:b2:
+         02:a6:60:b4:da:ab:53:d2:b2:7d:64:d5:d3:b6:35:66:96:f0:
+         ec:fb:9c:8d:35:40:e1:4a:7e:52:98:1f:1b:a2:e3:e4:35:70:
+         ec:33:ad:e8:a4:ed:a4:26:7d:07:a5:03:92:ac:11:81:4f:0f:
+         b3:c7:97:7f:29:d8:09:d1:28:11:f6:8d:9a:e0:5f:26:b9:7f:
+         74:77:e7:74:b1:5b:0f:7c:ae:13:d1:75:bc:ad:49:51:05:39:
+         06:53:6d:5c
 -----BEGIN CERTIFICATE-----
 MIIC8jCCAdqgAwIBAgICEAMwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwERSBD
-QTAeFw0xNjEwMDQxODUzMjRaFw0yNjEwMDIxODUzMjRaMBgxFjAUBgNVBAMMDUNs
-aWVudCBDZXJ0IEYwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCpuWFP
-Uv5kNFNnR9hYIiOCl2/Qguf3Cz3bThUVON/eNT7rrBmb2I3b6PrbL/ryIEWS3/XT
-tioDayjejSRLqjsjO34RCD6jlm+8czd9VJH8gZ6Mdu3V9uT2juhuVuKQ61Gl85DY
-Rdn6HZEBITphMTrqWsTpGu4A5pZiygunN6kcOU4SPq2r7bgshqVyTMo5A01h/Cm4
-vNsyiZUKYhoo1o5t6wYzmluP6HPhLx6EIfsLOCexg6DH/u15zKtXpc9bs4QMubga
-jJAiWfG+TUYMhWN7pxpJb47OovrlKWQDAtxo33m2a5siB1mvof+6nOZd1GHeQIEu
-ApYCqlQk1LPEGOP/AgMBAAGjTzBNMEsGA1UdEQREMEKBE3NhbnRlc3RAZXhhbXBs
+QTAeFw0xNjEyMDkyMDE4NTdaFw0yNjEyMDcyMDE4NTdaMBgxFjAUBgNVBAMMDUNs
+aWVudCBDZXJ0IEYwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCzXDK7
+wEgoN5tFq3ig6nITJl1G7nHEJJztqLaBNddyugquqU4gYRIi4ABngHC+rO8DstSw
+OvzFq4V7BEthhXoXbEM2ZwsZfHS4Zekc/fDfQrwM/Ql+T304wFJx5SsZgIKqacI2
+a7ctB/R0Yr+OkO1HGmQkrEy40irQnYYIwRiePt5PElxkpCuGQxKBZwyMVuQWRjwp
+z04Y6k9mX7TWc18ek63fyQZlzNxCuumGQgihq6X8ItMjV6DabIDexfmcxRFlnLLf
+89bIvaqvQGbtzl8ERhfmkupkyLPkIMvgRAkVH3zk4AfNIny9oAZlNdQ+HAdhjwFT
+IiWFk3VzQsfBwBKfAgMBAAGjTzBNMEsGA1UdEQREMEKBE3NhbnRlc3RAZXhhbXBs
 ZS5jb22gKwYKKwYBBAGCNxQCA6AdDBtzYW50ZXN0QGFkLmNvcnAuZXhhbXBsZS5j
-b20wDQYJKoZIhvcNAQELBQADggEBAF/YmXER0R+ufkr6hf/2GGDgw+iMjXtRue3q
-Jugr/9hcHpjLxqXo7yGv5ajyR5NeNmYhfYTHsixwMXFniMSpRcEgG+FH33XWg6Lb
-RSfK+rERsMIzvKcs+70rBmgNlUzUL6sqW/iSTpt0MPKNfCbH8Q8O9/EotoSQ26yg
-GoRMPgsUOd6Qylgs+BakDk3NusUdu5FpplWDliDuHzNYj9pEMpuEHpnTdGDJEGdc
-qQMRdOOChZlMqk497qyRfOi5sWQIRUhvNPRSimj5gGtbsq+Dy/x3/Z/Qqmk+vffK
-BRf49DnTWJoEgUOos2aQnrYnsxwlrY+MxkWk9gJgOgteb2vmGz8=
+b20wDQYJKoZIhvcNAQELBQADggEBAJhLA5vvuYtHgUKcW6BJVC7hlVGHnFyDsTyr
+ISl+4N4Rkq11Xp3iUXAOleNoPy6taVAxV2tte2zSxUvlp6Egur8ajoZHlHI1NAdf
+Gs8/E61Tf2vb79gAolzpXCBHWp72kcWbBWnzJQXii93YQZlkRO104uv3Qiy10PGs
+ZMD0h+k+UVJBo8JOWMLu/rQlN7k9wvDPwJB/9gKyOIiSKuDU24dcsgKmYLTaq1PS
+sn1k1dO2NWaW8Oz7nI01QOFKflKYHxui4+Q1cOwzreik7aQmfQelA5KsEYFPD7PH
+l38p2AnRKBH2jZrgXya5f3R353SxWw98rhPRdbytSVEFOQZTbVw=
 -----END CERTIFICATE-----
diff --git a/net/data/ssl/certificates/client_3.pk8 b/net/data/ssl/certificates/client_3.pk8
index 68f019a..2ffcdb2 100644
--- a/net/data/ssl/certificates/client_3.pk8
+++ b/net/data/ssl/certificates/client_3.pk8
Binary files differ
diff --git a/net/data/ssl/certificates/client_3_ca.pem b/net/data/ssl/certificates/client_3_ca.pem
index dd58ffa7..78080961 100644
--- a/net/data/ssl/certificates/client_3_ca.pem
+++ b/net/data/ssl/certificates/client_3_ca.pem
@@ -5,31 +5,31 @@
     Signature Algorithm: sha256WithRSAEncryption
         Issuer: CN=C Root CA
         Validity
-            Not Before: Oct  4 18:53:24 2016 GMT
-            Not After : Oct  2 18:53:24 2026 GMT
+            Not Before: Dec  9 20:18:57 2016 GMT
+            Not After : Dec  7 20:18:57 2026 GMT
         Subject: CN=E CA
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
                 Public-Key: (2048 bit)
                 Modulus:
-                    00:a2:7e:a3:fd:c1:d7:78:cd:57:ac:67:54:37:69:
-                    fb:72:6f:1d:8f:d0:47:0f:11:14:ab:42:d8:3d:6a:
-                    34:2b:d6:38:07:df:16:1d:c6:62:eb:d7:12:e1:86:
-                    83:f2:dd:8f:97:09:94:8f:1b:ff:3b:84:9b:48:e5:
-                    0d:43:6b:ae:bb:75:88:1c:c6:3a:7f:d8:12:d9:7c:
-                    12:18:6d:e2:f0:88:d4:3e:5a:93:b3:af:c1:79:a1:
-                    b6:a3:f7:56:46:21:e6:7d:6e:36:ea:ba:4b:52:f7:
-                    a9:45:0b:83:09:2c:09:22:8a:67:5a:8f:88:60:b0:
-                    11:07:25:9b:c2:6a:3c:63:4c:0e:69:45:ce:9d:ba:
-                    c9:d4:01:fb:78:56:38:08:8f:e5:d6:ff:ac:e4:04:
-                    fa:26:cf:d2:05:33:57:a3:8e:80:c0:b6:40:d5:d3:
-                    ca:85:17:30:b2:24:f4:19:af:c5:48:a4:ed:c0:49:
-                    c1:a4:b7:89:29:ba:e5:2d:37:78:1c:d6:3e:9b:03:
-                    fa:bc:7b:e2:76:a6:70:f3:1b:9d:b2:4b:fc:72:7b:
-                    77:89:50:bb:88:2f:b5:b6:a2:c7:33:27:b7:d1:1a:
-                    7c:d4:58:e3:5e:88:ca:f8:49:c3:cd:cc:0f:93:4b:
-                    3c:fd:75:c3:7b:6f:bf:d3:db:ba:2e:31:7b:a7:a5:
-                    42:c5
+                    00:c3:39:c3:5a:8e:ff:f2:1d:cc:26:91:5d:15:9e:
+                    ca:e0:fb:cf:99:5f:13:3d:c6:37:59:8b:ce:cc:76:
+                    0e:1c:9f:b6:49:5b:09:97:63:9d:e1:00:74:44:fb:
+                    2f:53:f3:d5:03:92:77:97:53:74:7e:d2:da:d3:a3:
+                    f4:c1:91:6a:83:ff:89:fe:73:46:56:ca:6d:51:0d:
+                    57:16:3d:3e:e8:fc:00:d9:4a:7a:7d:93:84:06:12:
+                    c5:ff:31:b3:a6:eb:96:18:71:b8:56:5c:2f:ab:78:
+                    e2:53:dd:15:d8:65:c8:f6:96:14:dc:15:cf:2a:39:
+                    ed:e1:08:1b:84:29:c7:1c:78:67:c8:e0:72:58:4e:
+                    33:7f:cb:ef:71:82:db:45:1d:7c:0c:d0:f5:4c:af:
+                    85:6b:14:61:50:87:34:42:fe:45:a3:3c:a3:53:57:
+                    1d:ac:11:c8:cf:2f:5e:cb:78:87:39:a1:41:3f:69:
+                    21:5c:1e:19:02:a3:6c:91:d3:1b:4e:50:fc:a4:b1:
+                    03:87:c0:58:b1:fe:cd:58:5e:53:ed:c9:d6:5d:9e:
+                    a3:fb:0d:e0:a0:8e:3d:c9:9e:9e:83:07:61:c7:30:
+                    5a:ca:29:93:04:af:5e:f3:57:2e:c2:d8:c8:ae:7f:
+                    5c:a4:27:fa:cd:55:a2:fd:89:d2:0b:87:24:6b:7b:
+                    fb:19
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Basic Constraints: critical
@@ -37,35 +37,35 @@
             X509v3 Key Usage: critical
                 Certificate Sign, CRL Sign
     Signature Algorithm: sha256WithRSAEncryption
-         92:8b:93:94:03:04:91:3f:4d:8b:f3:90:53:ee:73:b5:33:c7:
-         61:ea:0f:a5:59:9b:f0:0d:4f:7d:48:0d:5a:58:e7:1f:68:f6:
-         d6:58:75:33:a5:d2:b7:65:6a:28:40:bc:0e:1e:78:ee:9a:13:
-         3c:b0:8b:8f:98:72:86:50:3a:a3:bf:6d:f0:21:95:a8:73:d0:
-         dd:e5:0e:25:b1:62:76:65:69:1f:ee:26:82:ab:be:a4:a8:30:
-         a7:41:34:07:57:2f:8b:ab:25:af:cb:23:a5:79:cf:b2:a2:17:
-         02:a7:aa:50:92:6e:0d:9b:ff:c9:22:38:b4:0f:47:94:d2:80:
-         7f:92:30:00:ec:5b:22:e2:a6:71:5e:e8:8f:0d:2f:38:2c:29:
-         47:6a:7f:20:0a:e2:42:cb:b7:6e:2b:29:0f:03:55:94:84:5f:
-         e7:47:bf:ae:75:88:05:4e:42:ac:78:57:9d:9c:e2:77:d2:17:
-         42:55:ba:f8:77:ee:61:d6:e8:ec:aa:e0:7a:a6:65:c6:35:80:
-         08:3d:39:a6:70:8c:9e:6d:7a:ee:e7:cf:36:46:98:00:c8:7b:
-         b8:84:7f:9d:9f:bd:31:4f:99:25:6e:76:9a:5d:46:3e:40:70:
-         c6:a8:03:f3:98:9c:be:fb:f6:ad:c2:8d:e3:f9:7d:93:3a:78:
-         da:b3:d7:dc
+         67:d4:6c:cf:cd:54:81:67:2a:c2:c4:66:c7:76:9c:b0:8b:6b:
+         ef:b8:ae:a9:b3:d6:f8:47:91:d5:97:0b:bd:1a:87:21:8c:ce:
+         be:0c:80:d5:a5:25:0d:0a:c7:ed:be:cb:8c:6d:08:e8:de:a5:
+         33:89:e6:87:df:2b:f4:54:b3:c2:94:15:0d:36:5e:1a:aa:c0:
+         b0:03:3c:24:c6:a1:81:91:ca:fe:db:0f:59:1b:d6:4e:48:0b:
+         52:d3:e7:07:d7:b1:ca:b2:22:e4:d4:37:a4:3c:87:3c:0a:11:
+         a6:10:2a:ed:86:2a:bb:db:10:7e:f3:a5:fc:10:ab:80:5b:07:
+         58:7c:22:76:3e:9b:9c:72:79:0d:dc:85:f8:e7:c2:0f:17:aa:
+         01:dd:8e:24:27:77:4e:23:03:da:88:e0:df:e6:ca:b4:84:56:
+         a1:dc:9f:e0:93:94:97:d2:98:cd:32:6d:73:84:f9:3e:4c:96:
+         b3:51:07:b8:9f:66:32:d1:ac:53:0e:17:a9:6f:29:d1:7b:73:
+         b3:55:9b:cc:8f:8b:e5:49:fd:fd:f2:30:d6:d0:f7:03:06:12:
+         e3:66:2d:0d:a1:da:28:04:04:29:b8:40:6e:0e:6f:31:48:cb:
+         54:f7:e2:89:22:d8:05:e0:f5:7e:48:b3:96:ff:6b:ef:e7:fe:
+         71:1d:0b:77
 -----BEGIN CERTIFICATE-----
 MIICwjCCAaqgAwIBAgICEAIwDQYJKoZIhvcNAQELBQAwFDESMBAGA1UEAwwJQyBS
-b290IENBMB4XDTE2MTAwNDE4NTMyNFoXDTI2MTAwMjE4NTMyNFowDzENMAsGA1UE
-AwwERSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKJ+o/3B13jN
-V6xnVDdp+3JvHY/QRw8RFKtC2D1qNCvWOAffFh3GYuvXEuGGg/Ldj5cJlI8b/zuE
-m0jlDUNrrrt1iBzGOn/YEtl8Ehht4vCI1D5ak7OvwXmhtqP3VkYh5n1uNuq6S1L3
-qUULgwksCSKKZ1qPiGCwEQclm8JqPGNMDmlFzp26ydQB+3hWOAiP5db/rOQE+ibP
-0gUzV6OOgMC2QNXTyoUXMLIk9BmvxUik7cBJwaS3iSm65S03eBzWPpsD+rx74nam
-cPMbnbJL/HJ7d4lQu4gvtbaixzMnt9EafNRY416IyvhJw83MD5NLPP11w3tvv9Pb
-ui4xe6elQsUCAwEAAaMjMCEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
-AQYwDQYJKoZIhvcNAQELBQADggEBAJKLk5QDBJE/TYvzkFPuc7Uzx2HqD6VZm/AN
-T31IDVpY5x9o9tZYdTOl0rdlaihAvA4eeO6aEzywi4+YcoZQOqO/bfAhlahz0N3l
-DiWxYnZlaR/uJoKrvqSoMKdBNAdXL4urJa/LI6V5z7KiFwKnqlCSbg2b/8kiOLQP
-R5TSgH+SMADsWyLipnFe6I8NLzgsKUdqfyAK4kLLt24rKQ8DVZSEX+dHv651iAVO
-Qqx4V52c4nfSF0JVuvh37mHW6Oyq4HqmZcY1gAg9OaZwjJ5teu7nzzZGmADIe7iE
-f52fvTFPmSVudppdRj5AcMaoA/OYnL779q3CjeP5fZM6eNqz19w=
+b290IENBMB4XDTE2MTIwOTIwMTg1N1oXDTI2MTIwNzIwMTg1N1owDzENMAsGA1UE
+AwwERSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMM5w1qO//Id
+zCaRXRWeyuD7z5lfEz3GN1mLzsx2DhyftklbCZdjneEAdET7L1Pz1QOSd5dTdH7S
+2tOj9MGRaoP/if5zRlbKbVENVxY9Puj8ANlKen2ThAYSxf8xs6brlhhxuFZcL6t4
+4lPdFdhlyPaWFNwVzyo57eEIG4Qpxxx4Z8jgclhOM3/L73GC20UdfAzQ9UyvhWsU
+YVCHNEL+RaM8o1NXHawRyM8vXst4hzmhQT9pIVweGQKjbJHTG05Q/KSxA4fAWLH+
+zVheU+3J1l2eo/sN4KCOPcmenoMHYccwWsopkwSvXvNXLsLYyK5/XKQn+s1Vov2J
+0guHJGt7+xkCAwEAAaMjMCEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
+AQYwDQYJKoZIhvcNAQELBQADggEBAGfUbM/NVIFnKsLEZsd2nLCLa++4rqmz1vhH
+kdWXC70ahyGMzr4MgNWlJQ0Kx+2+y4xtCOjepTOJ5offK/RUs8KUFQ02XhqqwLAD
+PCTGoYGRyv7bD1kb1k5IC1LT5wfXscqyIuTUN6Q8hzwKEaYQKu2GKrvbEH7zpfwQ
+q4BbB1h8InY+m5xyeQ3chfjnwg8XqgHdjiQnd04jA9qI4N/myrSEVqHcn+CTlJfS
+mM0ybXOE+T5MlrNRB7ifZjLRrFMOF6lvKdF7c7NVm8yPi+VJ/f3yMNbQ9wMGEuNm
+LQ2h2igEBCm4QG4ObzFIy1T34oki2AXg9X5Is5b/a+/n/nEdC3c=
 -----END CERTIFICATE-----
diff --git a/net/data/ssl/certificates/client_4.key b/net/data/ssl/certificates/client_4.key
index b1e7e0f..43175e9 100644
--- a/net/data/ssl/certificates/client_4.key
+++ b/net/data/ssl/certificates/client_4.key
@@ -1,5 +1,5 @@
 -----BEGIN EC PRIVATE KEY-----
-MHcCAQEEILP75xbRvuB3x6CmLmO6dnAz4SzWM52MjX/ENrMfZWSEoAoGCCqGSM49
-AwEHoUQDQgAEeS7h2cVpnREfhVilcTyRzlg4kE1IhGT3MUl1BkvR5e1EgvkLapKA
-8lLte3NLOoH/gPKnhLDPmN5N2uTCEZhpzw==
+MHcCAQEEIMivPU8D2DOgGS1XWJ0SHOybwHGLYceOy0di/O3NTyfooAoGCCqGSM49
+AwEHoUQDQgAEicT32YPEOZz49vy8i2ZucO1QMh1i5zJMBmKPOCgzY1l9FmLhv61t
+3zRtxNZRllR1HFiAOIOIVcadhrfDZqF5Zw==
 -----END EC PRIVATE KEY-----
diff --git a/net/data/ssl/certificates/client_4.pem b/net/data/ssl/certificates/client_4.pem
index 3eeca24..914b453 100644
--- a/net/data/ssl/certificates/client_4.pem
+++ b/net/data/ssl/certificates/client_4.pem
@@ -5,18 +5,18 @@
     Signature Algorithm: sha256WithRSAEncryption
         Issuer: CN=E CA
         Validity
-            Not Before: Oct  4 18:53:24 2016 GMT
-            Not After : Oct  2 18:53:24 2026 GMT
+            Not Before: Dec  9 20:18:57 2016 GMT
+            Not After : Dec  7 20:18:57 2026 GMT
         Subject: CN=Client Cert G
         Subject Public Key Info:
             Public Key Algorithm: id-ecPublicKey
                 Public-Key: (256 bit)
                 pub: 
-                    04:79:2e:e1:d9:c5:69:9d:11:1f:85:58:a5:71:3c:
-                    91:ce:58:38:90:4d:48:84:64:f7:31:49:75:06:4b:
-                    d1:e5:ed:44:82:f9:0b:6a:92:80:f2:52:ed:7b:73:
-                    4b:3a:81:ff:80:f2:a7:84:b0:cf:98:de:4d:da:e4:
-                    c2:11:98:69:cf
+                    04:89:c4:f7:d9:83:c4:39:9c:f8:f6:fc:bc:8b:66:
+                    6e:70:ed:50:32:1d:62:e7:32:4c:06:62:8f:38:28:
+                    33:63:59:7d:16:62:e1:bf:ad:6d:df:34:6d:c4:d6:
+                    51:96:54:75:1c:58:80:38:83:88:55:c6:9d:86:b7:
+                    c3:66:a1:79:67
                 ASN1 OID: prime256v1
         X509v3 extensions:
             X509v3 Basic Constraints: critical
@@ -24,31 +24,31 @@
             X509v3 Extended Key Usage: 
                 TLS Web Server Authentication, TLS Web Client Authentication
     Signature Algorithm: sha256WithRSAEncryption
-         70:44:30:40:b7:d6:5b:09:e6:81:a1:a7:80:cd:bc:12:5d:e1:
-         45:7d:fb:04:5f:5f:21:b9:e5:a9:e0:79:52:5a:50:21:11:bb:
-         8c:25:08:e1:6d:19:e3:ba:e7:69:74:db:a6:b2:41:a4:f5:39:
-         63:18:e6:bc:ce:db:d8:3f:17:e1:90:9f:62:3a:d3:52:f4:c4:
-         01:4d:db:ad:16:ad:8b:31:51:fe:82:68:fd:34:c4:58:dc:4d:
-         6b:72:74:30:98:a6:03:4b:21:dd:54:1b:ed:e0:a5:3f:a9:5e:
-         1d:e6:57:3f:13:f4:e0:dc:d0:bf:90:68:dc:e1:e7:b5:81:b4:
-         f8:d5:45:96:95:b9:cd:83:15:c8:32:a6:20:2c:fc:b5:05:42:
-         1a:7e:26:4c:a1:9a:8b:26:2b:1b:72:c7:a5:38:f3:57:4c:b4:
-         7f:8e:dc:d9:52:0a:52:ac:e5:d9:18:0b:ae:91:b9:c5:e0:13:
-         cb:15:8d:19:3b:e9:60:1b:6b:31:0a:c7:22:4a:5a:ed:49:cf:
-         72:e1:dd:93:1e:43:a8:e0:3e:02:b6:06:ee:b9:a9:d3:d9:88:
-         2d:81:f6:96:cb:13:07:a8:51:81:89:8c:6b:28:d3:0c:22:8f:
-         e9:d7:92:1d:5a:2a:d6:c0:55:6b:86:2b:a7:f9:9e:35:88:5d:
-         bb:42:eb:b8
+         43:3c:6f:e4:e7:89:a9:fe:f8:d0:d6:a0:13:94:1b:a1:98:22:
+         26:0d:e1:3b:a1:91:41:f1:5e:88:38:cb:7d:f0:55:8c:c3:df:
+         a3:99:31:71:0c:d0:1f:23:86:89:d7:ca:9f:f0:c6:bc:d2:b8:
+         0b:4e:bc:bf:63:93:4e:c4:71:65:97:c0:f2:ea:35:34:9c:d5:
+         b5:8e:15:2e:bb:0b:63:ab:f6:fd:5d:2d:22:f7:00:e6:5a:88:
+         01:6f:f8:ef:8a:be:68:1d:95:b5:c9:b2:47:be:cd:98:bd:5a:
+         ae:a2:b9:a3:53:bc:9e:87:de:40:a6:17:b5:7c:bd:4d:35:f5:
+         29:72:22:a7:ee:2a:bc:4c:e2:b0:a6:98:47:1d:93:01:f8:53:
+         ee:af:e3:3a:1f:a2:e0:36:eb:67:28:7a:39:b8:89:95:44:57:
+         08:bb:20:8d:0b:27:36:15:ce:48:11:ae:32:07:ef:44:12:e5:
+         97:2e:92:56:c4:d6:93:0f:41:25:38:e5:52:0e:c3:f3:cc:9d:
+         de:b0:1d:4e:e3:51:79:63:0f:4c:58:ea:7c:e7:7a:ac:a8:f3:
+         c4:45:16:34:77:ba:6b:a7:49:9c:aa:62:d1:dd:81:6b:55:08:
+         38:39:11:23:a0:ec:50:ff:58:ca:22:d3:29:c8:2e:bc:35:62:
+         9b:cd:56:fb
 -----BEGIN CERTIFICATE-----
 MIICBjCB76ADAgECAgIQBDANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARFIENB
-MB4XDTE2MTAwNDE4NTMyNFoXDTI2MTAwMjE4NTMyNFowGDEWMBQGA1UEAwwNQ2xp
-ZW50IENlcnQgRzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABHku4dnFaZ0RH4VY
-pXE8kc5YOJBNSIRk9zFJdQZL0eXtRIL5C2qSgPJS7XtzSzqB/4Dyp4Swz5jeTdrk
-whGYac+jLzAtMAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsG
-AQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQBwRDBAt9ZbCeaBoaeAzbwSXeFFffsE
-X18hueWp4HlSWlAhEbuMJQjhbRnjuudpdNumskGk9TljGOa8ztvYPxfhkJ9iOtNS
-9MQBTdutFq2LMVH+gmj9NMRY3E1rcnQwmKYDSyHdVBvt4KU/qV4d5lc/E/Tg3NC/
-kGjc4ee1gbT41UWWlbnNgxXIMqYgLPy1BUIafiZMoZqLJisbcselOPNXTLR/jtzZ
-UgpSrOXZGAuukbnF4BPLFY0ZO+lgG2sxCsciSlrtSc9y4d2THkOo4D4CtgbuuanT
-2YgtgfaWyxMHqFGBiYxrKNMMIo/p15IdWirWwFVrhiun+Z41iF27Quu4
+MB4XDTE2MTIwOTIwMTg1N1oXDTI2MTIwNzIwMTg1N1owGDEWMBQGA1UEAwwNQ2xp
+ZW50IENlcnQgRzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABInE99mDxDmc+Pb8
+vItmbnDtUDIdYucyTAZijzgoM2NZfRZi4b+tbd80bcTWUZZUdRxYgDiDiFXGnYa3
+w2aheWejLzAtMAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsG
+AQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQBDPG/k54mp/vjQ1qATlBuhmCImDeE7
+oZFB8V6IOMt98FWMw9+jmTFxDNAfI4aJ18qf8Ma80rgLTry/Y5NOxHFll8Dy6jU0
+nNW1jhUuuwtjq/b9XS0i9wDmWogBb/jvir5oHZW1ybJHvs2YvVquormjU7yeh95A
+phe1fL1NNfUpciKn7iq8TOKwpphHHZMB+FPur+M6H6LgNutnKHo5uImVRFcIuyCN
+Cyc2Fc5IEa4yB+9EEuWXLpJWxNaTD0ElOOVSDsPzzJ3esB1O41F5Yw9MWOp853qs
+qPPERRY0d7prp0mcqmLR3YFrVQg4OREjoOxQ/1jKItMpyC68NWKbzVb7
 -----END CERTIFICATE-----
diff --git a/net/data/ssl/certificates/client_4.pk8 b/net/data/ssl/certificates/client_4.pk8
index 20ea5cfd..5f5f1580 100644
--- a/net/data/ssl/certificates/client_4.pk8
+++ b/net/data/ssl/certificates/client_4.pk8
Binary files differ
diff --git a/net/data/ssl/certificates/client_4_ca.pem b/net/data/ssl/certificates/client_4_ca.pem
index dd58ffa7..78080961 100644
--- a/net/data/ssl/certificates/client_4_ca.pem
+++ b/net/data/ssl/certificates/client_4_ca.pem
@@ -5,31 +5,31 @@
     Signature Algorithm: sha256WithRSAEncryption
         Issuer: CN=C Root CA
         Validity
-            Not Before: Oct  4 18:53:24 2016 GMT
-            Not After : Oct  2 18:53:24 2026 GMT
+            Not Before: Dec  9 20:18:57 2016 GMT
+            Not After : Dec  7 20:18:57 2026 GMT
         Subject: CN=E CA
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
                 Public-Key: (2048 bit)
                 Modulus:
-                    00:a2:7e:a3:fd:c1:d7:78:cd:57:ac:67:54:37:69:
-                    fb:72:6f:1d:8f:d0:47:0f:11:14:ab:42:d8:3d:6a:
-                    34:2b:d6:38:07:df:16:1d:c6:62:eb:d7:12:e1:86:
-                    83:f2:dd:8f:97:09:94:8f:1b:ff:3b:84:9b:48:e5:
-                    0d:43:6b:ae:bb:75:88:1c:c6:3a:7f:d8:12:d9:7c:
-                    12:18:6d:e2:f0:88:d4:3e:5a:93:b3:af:c1:79:a1:
-                    b6:a3:f7:56:46:21:e6:7d:6e:36:ea:ba:4b:52:f7:
-                    a9:45:0b:83:09:2c:09:22:8a:67:5a:8f:88:60:b0:
-                    11:07:25:9b:c2:6a:3c:63:4c:0e:69:45:ce:9d:ba:
-                    c9:d4:01:fb:78:56:38:08:8f:e5:d6:ff:ac:e4:04:
-                    fa:26:cf:d2:05:33:57:a3:8e:80:c0:b6:40:d5:d3:
-                    ca:85:17:30:b2:24:f4:19:af:c5:48:a4:ed:c0:49:
-                    c1:a4:b7:89:29:ba:e5:2d:37:78:1c:d6:3e:9b:03:
-                    fa:bc:7b:e2:76:a6:70:f3:1b:9d:b2:4b:fc:72:7b:
-                    77:89:50:bb:88:2f:b5:b6:a2:c7:33:27:b7:d1:1a:
-                    7c:d4:58:e3:5e:88:ca:f8:49:c3:cd:cc:0f:93:4b:
-                    3c:fd:75:c3:7b:6f:bf:d3:db:ba:2e:31:7b:a7:a5:
-                    42:c5
+                    00:c3:39:c3:5a:8e:ff:f2:1d:cc:26:91:5d:15:9e:
+                    ca:e0:fb:cf:99:5f:13:3d:c6:37:59:8b:ce:cc:76:
+                    0e:1c:9f:b6:49:5b:09:97:63:9d:e1:00:74:44:fb:
+                    2f:53:f3:d5:03:92:77:97:53:74:7e:d2:da:d3:a3:
+                    f4:c1:91:6a:83:ff:89:fe:73:46:56:ca:6d:51:0d:
+                    57:16:3d:3e:e8:fc:00:d9:4a:7a:7d:93:84:06:12:
+                    c5:ff:31:b3:a6:eb:96:18:71:b8:56:5c:2f:ab:78:
+                    e2:53:dd:15:d8:65:c8:f6:96:14:dc:15:cf:2a:39:
+                    ed:e1:08:1b:84:29:c7:1c:78:67:c8:e0:72:58:4e:
+                    33:7f:cb:ef:71:82:db:45:1d:7c:0c:d0:f5:4c:af:
+                    85:6b:14:61:50:87:34:42:fe:45:a3:3c:a3:53:57:
+                    1d:ac:11:c8:cf:2f:5e:cb:78:87:39:a1:41:3f:69:
+                    21:5c:1e:19:02:a3:6c:91:d3:1b:4e:50:fc:a4:b1:
+                    03:87:c0:58:b1:fe:cd:58:5e:53:ed:c9:d6:5d:9e:
+                    a3:fb:0d:e0:a0:8e:3d:c9:9e:9e:83:07:61:c7:30:
+                    5a:ca:29:93:04:af:5e:f3:57:2e:c2:d8:c8:ae:7f:
+                    5c:a4:27:fa:cd:55:a2:fd:89:d2:0b:87:24:6b:7b:
+                    fb:19
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Basic Constraints: critical
@@ -37,35 +37,35 @@
             X509v3 Key Usage: critical
                 Certificate Sign, CRL Sign
     Signature Algorithm: sha256WithRSAEncryption
-         92:8b:93:94:03:04:91:3f:4d:8b:f3:90:53:ee:73:b5:33:c7:
-         61:ea:0f:a5:59:9b:f0:0d:4f:7d:48:0d:5a:58:e7:1f:68:f6:
-         d6:58:75:33:a5:d2:b7:65:6a:28:40:bc:0e:1e:78:ee:9a:13:
-         3c:b0:8b:8f:98:72:86:50:3a:a3:bf:6d:f0:21:95:a8:73:d0:
-         dd:e5:0e:25:b1:62:76:65:69:1f:ee:26:82:ab:be:a4:a8:30:
-         a7:41:34:07:57:2f:8b:ab:25:af:cb:23:a5:79:cf:b2:a2:17:
-         02:a7:aa:50:92:6e:0d:9b:ff:c9:22:38:b4:0f:47:94:d2:80:
-         7f:92:30:00:ec:5b:22:e2:a6:71:5e:e8:8f:0d:2f:38:2c:29:
-         47:6a:7f:20:0a:e2:42:cb:b7:6e:2b:29:0f:03:55:94:84:5f:
-         e7:47:bf:ae:75:88:05:4e:42:ac:78:57:9d:9c:e2:77:d2:17:
-         42:55:ba:f8:77:ee:61:d6:e8:ec:aa:e0:7a:a6:65:c6:35:80:
-         08:3d:39:a6:70:8c:9e:6d:7a:ee:e7:cf:36:46:98:00:c8:7b:
-         b8:84:7f:9d:9f:bd:31:4f:99:25:6e:76:9a:5d:46:3e:40:70:
-         c6:a8:03:f3:98:9c:be:fb:f6:ad:c2:8d:e3:f9:7d:93:3a:78:
-         da:b3:d7:dc
+         67:d4:6c:cf:cd:54:81:67:2a:c2:c4:66:c7:76:9c:b0:8b:6b:
+         ef:b8:ae:a9:b3:d6:f8:47:91:d5:97:0b:bd:1a:87:21:8c:ce:
+         be:0c:80:d5:a5:25:0d:0a:c7:ed:be:cb:8c:6d:08:e8:de:a5:
+         33:89:e6:87:df:2b:f4:54:b3:c2:94:15:0d:36:5e:1a:aa:c0:
+         b0:03:3c:24:c6:a1:81:91:ca:fe:db:0f:59:1b:d6:4e:48:0b:
+         52:d3:e7:07:d7:b1:ca:b2:22:e4:d4:37:a4:3c:87:3c:0a:11:
+         a6:10:2a:ed:86:2a:bb:db:10:7e:f3:a5:fc:10:ab:80:5b:07:
+         58:7c:22:76:3e:9b:9c:72:79:0d:dc:85:f8:e7:c2:0f:17:aa:
+         01:dd:8e:24:27:77:4e:23:03:da:88:e0:df:e6:ca:b4:84:56:
+         a1:dc:9f:e0:93:94:97:d2:98:cd:32:6d:73:84:f9:3e:4c:96:
+         b3:51:07:b8:9f:66:32:d1:ac:53:0e:17:a9:6f:29:d1:7b:73:
+         b3:55:9b:cc:8f:8b:e5:49:fd:fd:f2:30:d6:d0:f7:03:06:12:
+         e3:66:2d:0d:a1:da:28:04:04:29:b8:40:6e:0e:6f:31:48:cb:
+         54:f7:e2:89:22:d8:05:e0:f5:7e:48:b3:96:ff:6b:ef:e7:fe:
+         71:1d:0b:77
 -----BEGIN CERTIFICATE-----
 MIICwjCCAaqgAwIBAgICEAIwDQYJKoZIhvcNAQELBQAwFDESMBAGA1UEAwwJQyBS
-b290IENBMB4XDTE2MTAwNDE4NTMyNFoXDTI2MTAwMjE4NTMyNFowDzENMAsGA1UE
-AwwERSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKJ+o/3B13jN
-V6xnVDdp+3JvHY/QRw8RFKtC2D1qNCvWOAffFh3GYuvXEuGGg/Ldj5cJlI8b/zuE
-m0jlDUNrrrt1iBzGOn/YEtl8Ehht4vCI1D5ak7OvwXmhtqP3VkYh5n1uNuq6S1L3
-qUULgwksCSKKZ1qPiGCwEQclm8JqPGNMDmlFzp26ydQB+3hWOAiP5db/rOQE+ibP
-0gUzV6OOgMC2QNXTyoUXMLIk9BmvxUik7cBJwaS3iSm65S03eBzWPpsD+rx74nam
-cPMbnbJL/HJ7d4lQu4gvtbaixzMnt9EafNRY416IyvhJw83MD5NLPP11w3tvv9Pb
-ui4xe6elQsUCAwEAAaMjMCEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
-AQYwDQYJKoZIhvcNAQELBQADggEBAJKLk5QDBJE/TYvzkFPuc7Uzx2HqD6VZm/AN
-T31IDVpY5x9o9tZYdTOl0rdlaihAvA4eeO6aEzywi4+YcoZQOqO/bfAhlahz0N3l
-DiWxYnZlaR/uJoKrvqSoMKdBNAdXL4urJa/LI6V5z7KiFwKnqlCSbg2b/8kiOLQP
-R5TSgH+SMADsWyLipnFe6I8NLzgsKUdqfyAK4kLLt24rKQ8DVZSEX+dHv651iAVO
-Qqx4V52c4nfSF0JVuvh37mHW6Oyq4HqmZcY1gAg9OaZwjJ5teu7nzzZGmADIe7iE
-f52fvTFPmSVudppdRj5AcMaoA/OYnL779q3CjeP5fZM6eNqz19w=
+b290IENBMB4XDTE2MTIwOTIwMTg1N1oXDTI2MTIwNzIwMTg1N1owDzENMAsGA1UE
+AwwERSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMM5w1qO//Id
+zCaRXRWeyuD7z5lfEz3GN1mLzsx2DhyftklbCZdjneEAdET7L1Pz1QOSd5dTdH7S
+2tOj9MGRaoP/if5zRlbKbVENVxY9Puj8ANlKen2ThAYSxf8xs6brlhhxuFZcL6t4
+4lPdFdhlyPaWFNwVzyo57eEIG4Qpxxx4Z8jgclhOM3/L73GC20UdfAzQ9UyvhWsU
+YVCHNEL+RaM8o1NXHawRyM8vXst4hzmhQT9pIVweGQKjbJHTG05Q/KSxA4fAWLH+
+zVheU+3J1l2eo/sN4KCOPcmenoMHYccwWsopkwSvXvNXLsLYyK5/XKQn+s1Vov2J
+0guHJGt7+xkCAwEAAaMjMCEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
+AQYwDQYJKoZIhvcNAQELBQADggEBAGfUbM/NVIFnKsLEZsd2nLCLa++4rqmz1vhH
+kdWXC70ahyGMzr4MgNWlJQ0Kx+2+y4xtCOjepTOJ5offK/RUs8KUFQ02XhqqwLAD
+PCTGoYGRyv7bD1kb1k5IC1LT5wfXscqyIuTUN6Q8hzwKEaYQKu2GKrvbEH7zpfwQ
+q4BbB1h8InY+m5xyeQ3chfjnwg8XqgHdjiQnd04jA9qI4N/myrSEVqHcn+CTlJfS
+mM0ybXOE+T5MlrNRB7ifZjLRrFMOF6lvKdF7c7NVm8yPi+VJ/f3yMNbQ9wMGEuNm
+LQ2h2igEBCm4QG4ObzFIy1T34oki2AXg9X5Is5b/a+/n/nEdC3c=
 -----END CERTIFICATE-----
diff --git a/net/data/ssl/certificates/client_5.key b/net/data/ssl/certificates/client_5.key
new file mode 100644
index 0000000..ab74e24
--- /dev/null
+++ b/net/data/ssl/certificates/client_5.key
@@ -0,0 +1,6 @@
+-----BEGIN EC PRIVATE KEY-----
+MIGkAgEBBDDIPJAB+fFVxe/nIqgAGt9Pff2OF9Ts6WOBW3RZbf5o3SZiuS1fhUh1
+ppZfdaRmjEygBwYFK4EEACKhZANiAARMBdRlPc2YnctgdjXBkdxS79SBGI4WBsRz
+jiYMjMkPGDVdN/kID0Gi5hkwXTZ6yhRmbqf7NdNsC5f2nH74BTfoqn//Aj0SroiI
+OalVGt2S2NW6ea690MvYnA/AM2B3L/Y=
+-----END EC PRIVATE KEY-----
diff --git a/net/data/ssl/certificates/client_5.pem b/net/data/ssl/certificates/client_5.pem
new file mode 100644
index 0000000..e984048
--- /dev/null
+++ b/net/data/ssl/certificates/client_5.pem
@@ -0,0 +1,57 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 4101 (0x1005)
+    Signature Algorithm: sha256WithRSAEncryption
+        Issuer: CN=E CA
+        Validity
+            Not Before: Dec  9 20:18:57 2016 GMT
+            Not After : Dec  7 20:18:57 2026 GMT
+        Subject: CN=Client Cert H
+        Subject Public Key Info:
+            Public Key Algorithm: id-ecPublicKey
+                Public-Key: (384 bit)
+                pub: 
+                    04:4c:05:d4:65:3d:cd:98:9d:cb:60:76:35:c1:91:
+                    dc:52:ef:d4:81:18:8e:16:06:c4:73:8e:26:0c:8c:
+                    c9:0f:18:35:5d:37:f9:08:0f:41:a2:e6:19:30:5d:
+                    36:7a:ca:14:66:6e:a7:fb:35:d3:6c:0b:97:f6:9c:
+                    7e:f8:05:37:e8:aa:7f:ff:02:3d:12:ae:88:88:39:
+                    a9:55:1a:dd:92:d8:d5:ba:79:ae:bd:d0:cb:d8:9c:
+                    0f:c0:33:60:77:2f:f6
+                ASN1 OID: secp384r1
+        X509v3 extensions:
+            X509v3 Basic Constraints: critical
+                CA:FALSE
+            X509v3 Extended Key Usage: 
+                TLS Web Server Authentication, TLS Web Client Authentication
+    Signature Algorithm: sha256WithRSAEncryption
+         b2:37:fc:b9:0c:90:27:fc:e3:3e:a7:6f:c6:94:95:2c:61:37:
+         46:25:64:55:ae:61:fe:00:58:0e:64:5f:9a:5b:bc:3a:b7:52:
+         e1:42:9a:8a:05:c2:b6:1d:cc:d7:47:a8:88:d5:78:1f:74:08:
+         db:52:e1:00:3c:aa:7c:80:73:b1:91:f9:75:6e:d3:53:28:ef:
+         af:5a:b7:1d:3e:38:a8:b8:1b:48:ed:20:18:a8:4a:de:60:97:
+         bb:3f:b6:b8:cc:d5:5b:bf:1c:97:06:d1:9a:25:b8:85:1c:36:
+         26:02:e0:78:47:e0:f5:07:a4:0a:6a:55:14:39:51:d6:f3:f2:
+         b9:d4:44:9d:78:c4:45:e5:39:6f:71:0e:bd:2a:7b:71:9e:c4:
+         12:f2:52:f0:ed:6a:78:47:48:df:ea:a0:44:eb:ce:f6:5c:50:
+         53:47:3d:a6:db:ca:ad:a7:62:d8:6d:06:56:9f:e2:1b:72:08:
+         b3:4a:cb:2d:e9:4a:62:9e:c1:7e:5e:bd:ce:08:2f:82:bd:2f:
+         6e:8b:55:e2:43:01:e6:30:40:b7:67:3c:0d:96:e1:9a:33:bd:
+         b8:c2:88:03:f5:87:68:4d:6d:49:7f:8e:94:f3:6a:41:2f:31:
+         19:b6:0d:33:61:24:41:33:16:d4:5b:ad:98:8e:05:f7:9c:a1:
+         13:dd:5f:7d
+-----BEGIN CERTIFICATE-----
+MIICJDCCAQygAwIBAgICEAUwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwERSBD
+QTAeFw0xNjEyMDkyMDE4NTdaFw0yNjEyMDcyMDE4NTdaMBgxFjAUBgNVBAMMDUNs
+aWVudCBDZXJ0IEgwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARMBdRlPc2YnctgdjXB
+kdxS79SBGI4WBsRzjiYMjMkPGDVdN/kID0Gi5hkwXTZ6yhRmbqf7NdNsC5f2nH74
+BTfoqn//Aj0SroiIOalVGt2S2NW6ea690MvYnA/AM2B3L/ajLzAtMAwGA1UdEwEB
+/wQCMAAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA0GCSqGSIb3DQEB
+CwUAA4IBAQCyN/y5DJAn/OM+p2/GlJUsYTdGJWRVrmH+AFgOZF+aW7w6t1LhQpqK
+BcK2HczXR6iI1XgfdAjbUuEAPKp8gHOxkfl1btNTKO+vWrcdPjiouBtI7SAYqEre
+YJe7P7a4zNVbvxyXBtGaJbiFHDYmAuB4R+D1B6QKalUUOVHW8/K51ESdeMRF5Tlv
+cQ69KntxnsQS8lLw7Wp4R0jf6qBE6872XFBTRz2m28qtp2LYbQZWn+IbcgizSsst
+6UpinsF+Xr3OCC+CvS9ui1XiQwHmMEC3ZzwNluGaM724wogD9YdoTW1Jf46U82pB
+LzEZtg0zYSRBMxbUW62YjgX3nKET3V99
+-----END CERTIFICATE-----
diff --git a/net/data/ssl/certificates/client_5.pk8 b/net/data/ssl/certificates/client_5.pk8
new file mode 100644
index 0000000..26da499
--- /dev/null
+++ b/net/data/ssl/certificates/client_5.pk8
Binary files differ
diff --git a/net/data/ssl/certificates/client_5_ca.pem b/net/data/ssl/certificates/client_5_ca.pem
new file mode 100644
index 0000000..78080961
--- /dev/null
+++ b/net/data/ssl/certificates/client_5_ca.pem
@@ -0,0 +1,71 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 4098 (0x1002)
+    Signature Algorithm: sha256WithRSAEncryption
+        Issuer: CN=C Root CA
+        Validity
+            Not Before: Dec  9 20:18:57 2016 GMT
+            Not After : Dec  7 20:18:57 2026 GMT
+        Subject: CN=E CA
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:c3:39:c3:5a:8e:ff:f2:1d:cc:26:91:5d:15:9e:
+                    ca:e0:fb:cf:99:5f:13:3d:c6:37:59:8b:ce:cc:76:
+                    0e:1c:9f:b6:49:5b:09:97:63:9d:e1:00:74:44:fb:
+                    2f:53:f3:d5:03:92:77:97:53:74:7e:d2:da:d3:a3:
+                    f4:c1:91:6a:83:ff:89:fe:73:46:56:ca:6d:51:0d:
+                    57:16:3d:3e:e8:fc:00:d9:4a:7a:7d:93:84:06:12:
+                    c5:ff:31:b3:a6:eb:96:18:71:b8:56:5c:2f:ab:78:
+                    e2:53:dd:15:d8:65:c8:f6:96:14:dc:15:cf:2a:39:
+                    ed:e1:08:1b:84:29:c7:1c:78:67:c8:e0:72:58:4e:
+                    33:7f:cb:ef:71:82:db:45:1d:7c:0c:d0:f5:4c:af:
+                    85:6b:14:61:50:87:34:42:fe:45:a3:3c:a3:53:57:
+                    1d:ac:11:c8:cf:2f:5e:cb:78:87:39:a1:41:3f:69:
+                    21:5c:1e:19:02:a3:6c:91:d3:1b:4e:50:fc:a4:b1:
+                    03:87:c0:58:b1:fe:cd:58:5e:53:ed:c9:d6:5d:9e:
+                    a3:fb:0d:e0:a0:8e:3d:c9:9e:9e:83:07:61:c7:30:
+                    5a:ca:29:93:04:af:5e:f3:57:2e:c2:d8:c8:ae:7f:
+                    5c:a4:27:fa:cd:55:a2:fd:89:d2:0b:87:24:6b:7b:
+                    fb:19
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: critical
+                CA:TRUE
+            X509v3 Key Usage: critical
+                Certificate Sign, CRL Sign
+    Signature Algorithm: sha256WithRSAEncryption
+         67:d4:6c:cf:cd:54:81:67:2a:c2:c4:66:c7:76:9c:b0:8b:6b:
+         ef:b8:ae:a9:b3:d6:f8:47:91:d5:97:0b:bd:1a:87:21:8c:ce:
+         be:0c:80:d5:a5:25:0d:0a:c7:ed:be:cb:8c:6d:08:e8:de:a5:
+         33:89:e6:87:df:2b:f4:54:b3:c2:94:15:0d:36:5e:1a:aa:c0:
+         b0:03:3c:24:c6:a1:81:91:ca:fe:db:0f:59:1b:d6:4e:48:0b:
+         52:d3:e7:07:d7:b1:ca:b2:22:e4:d4:37:a4:3c:87:3c:0a:11:
+         a6:10:2a:ed:86:2a:bb:db:10:7e:f3:a5:fc:10:ab:80:5b:07:
+         58:7c:22:76:3e:9b:9c:72:79:0d:dc:85:f8:e7:c2:0f:17:aa:
+         01:dd:8e:24:27:77:4e:23:03:da:88:e0:df:e6:ca:b4:84:56:
+         a1:dc:9f:e0:93:94:97:d2:98:cd:32:6d:73:84:f9:3e:4c:96:
+         b3:51:07:b8:9f:66:32:d1:ac:53:0e:17:a9:6f:29:d1:7b:73:
+         b3:55:9b:cc:8f:8b:e5:49:fd:fd:f2:30:d6:d0:f7:03:06:12:
+         e3:66:2d:0d:a1:da:28:04:04:29:b8:40:6e:0e:6f:31:48:cb:
+         54:f7:e2:89:22:d8:05:e0:f5:7e:48:b3:96:ff:6b:ef:e7:fe:
+         71:1d:0b:77
+-----BEGIN CERTIFICATE-----
+MIICwjCCAaqgAwIBAgICEAIwDQYJKoZIhvcNAQELBQAwFDESMBAGA1UEAwwJQyBS
+b290IENBMB4XDTE2MTIwOTIwMTg1N1oXDTI2MTIwNzIwMTg1N1owDzENMAsGA1UE
+AwwERSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMM5w1qO//Id
+zCaRXRWeyuD7z5lfEz3GN1mLzsx2DhyftklbCZdjneEAdET7L1Pz1QOSd5dTdH7S
+2tOj9MGRaoP/if5zRlbKbVENVxY9Puj8ANlKen2ThAYSxf8xs6brlhhxuFZcL6t4
+4lPdFdhlyPaWFNwVzyo57eEIG4Qpxxx4Z8jgclhOM3/L73GC20UdfAzQ9UyvhWsU
+YVCHNEL+RaM8o1NXHawRyM8vXst4hzmhQT9pIVweGQKjbJHTG05Q/KSxA4fAWLH+
+zVheU+3J1l2eo/sN4KCOPcmenoMHYccwWsopkwSvXvNXLsLYyK5/XKQn+s1Vov2J
+0guHJGt7+xkCAwEAAaMjMCEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
+AQYwDQYJKoZIhvcNAQELBQADggEBAGfUbM/NVIFnKsLEZsd2nLCLa++4rqmz1vhH
+kdWXC70ahyGMzr4MgNWlJQ0Kx+2+y4xtCOjepTOJ5offK/RUs8KUFQ02XhqqwLAD
+PCTGoYGRyv7bD1kb1k5IC1LT5wfXscqyIuTUN6Q8hzwKEaYQKu2GKrvbEH7zpfwQ
+q4BbB1h8InY+m5xyeQ3chfjnwg8XqgHdjiQnd04jA9qI4N/myrSEVqHcn+CTlJfS
+mM0ybXOE+T5MlrNRB7ifZjLRrFMOF6lvKdF7c7NVm8yPi+VJ/f3yMNbQ9wMGEuNm
+LQ2h2igEBCm4QG4ObzFIy1T34oki2AXg9X5Is5b/a+/n/nEdC3c=
+-----END CERTIFICATE-----
diff --git a/net/data/ssl/certificates/client_6.key b/net/data/ssl/certificates/client_6.key
new file mode 100644
index 0000000..289c2d7
--- /dev/null
+++ b/net/data/ssl/certificates/client_6.key
@@ -0,0 +1,7 @@
+-----BEGIN EC PRIVATE KEY-----
+MIHcAgEBBEIBp33i9oT0DV1aUcOE8av0Nt6ZCvsoVPPP/4kpU6T6d7wgLNwLK3uG
+vGCZX5AbdL1VvLA1rvfodqYug3pRnH0wSyigBwYFK4EEACOhgYkDgYYABACtf0oy
+HoxXTu/joG5I2fTeeYe6ZCEKlz2D5cMckF4bIkjRpue12TMhzs7FYp0cg+My3bxO
+A87t7os/vXJ3SZxGCwBFIQJc/vMSz7eOlaYHWXYY+vuD4Ab/j34lv1U+6LjtinWo
+I2WAbq/rxzSku9/NnLtKATbz3YgnYyzCEsmxQHfiKg==
+-----END EC PRIVATE KEY-----
diff --git a/net/data/ssl/certificates/client_6.pem b/net/data/ssl/certificates/client_6.pem
new file mode 100644
index 0000000..f90a4ca8
--- /dev/null
+++ b/net/data/ssl/certificates/client_6.pem
@@ -0,0 +1,60 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 4102 (0x1006)
+    Signature Algorithm: sha256WithRSAEncryption
+        Issuer: CN=E CA
+        Validity
+            Not Before: Dec  9 20:18:57 2016 GMT
+            Not After : Dec  7 20:18:57 2026 GMT
+        Subject: CN=Client Cert I
+        Subject Public Key Info:
+            Public Key Algorithm: id-ecPublicKey
+                Public-Key: (521 bit)
+                pub: 
+                    04:00:ad:7f:4a:32:1e:8c:57:4e:ef:e3:a0:6e:48:
+                    d9:f4:de:79:87:ba:64:21:0a:97:3d:83:e5:c3:1c:
+                    90:5e:1b:22:48:d1:a6:e7:b5:d9:33:21:ce:ce:c5:
+                    62:9d:1c:83:e3:32:dd:bc:4e:03:ce:ed:ee:8b:3f:
+                    bd:72:77:49:9c:46:0b:00:45:21:02:5c:fe:f3:12:
+                    cf:b7:8e:95:a6:07:59:76:18:fa:fb:83:e0:06:ff:
+                    8f:7e:25:bf:55:3e:e8:b8:ed:8a:75:a8:23:65:80:
+                    6e:af:eb:c7:34:a4:bb:df:cd:9c:bb:4a:01:36:f3:
+                    dd:88:27:63:2c:c2:12:c9:b1:40:77:e2:2a
+                ASN1 OID: secp521r1
+        X509v3 extensions:
+            X509v3 Basic Constraints: critical
+                CA:FALSE
+            X509v3 Extended Key Usage: 
+                TLS Web Server Authentication, TLS Web Client Authentication
+    Signature Algorithm: sha256WithRSAEncryption
+         8d:7b:44:61:33:92:ef:73:17:b7:b1:95:d8:f3:87:02:36:1c:
+         f7:d1:00:0d:2b:59:88:80:31:93:0b:ef:e8:c0:19:c6:bb:89:
+         26:3a:6e:47:90:0b:b2:99:d5:46:19:c4:cb:61:eb:51:6e:74:
+         f7:d0:87:4f:3b:08:fe:5a:48:a3:23:cc:b4:5d:a4:b6:0c:78:
+         f1:b2:f0:36:71:d7:c6:a7:e1:80:59:a6:67:b4:2a:ea:b5:1b:
+         9f:a2:bb:4d:01:36:e3:58:ed:19:bd:e6:b4:8e:d7:3c:b7:cc:
+         95:76:8b:e9:ec:78:c0:de:1b:09:04:d7:44:6c:2c:3c:c3:0e:
+         39:dc:be:3b:eb:ec:7d:b5:b9:3e:e6:eb:c0:ef:15:af:ca:96:
+         1d:f0:9e:ba:27:41:a2:7c:66:67:7d:37:65:0c:66:b7:aa:1b:
+         e8:88:55:f1:50:54:b9:36:e3:84:9c:27:a9:fa:8c:06:06:ce:
+         02:63:85:a6:70:dd:fc:78:1f:26:1f:13:01:aa:8d:34:54:80:
+         23:28:84:bf:90:a4:1a:61:e7:83:90:93:b7:0b:13:1d:c5:78:
+         7b:74:eb:5d:18:f1:b2:dd:6c:23:10:bc:80:1c:14:38:e6:76:
+         d5:78:b9:3a:0a:57:38:bd:fe:45:b0:68:a3:8c:1e:ae:25:84:
+         2f:dc:7a:b2
+-----BEGIN CERTIFICATE-----
+MIICSjCCATKgAwIBAgICEAYwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwERSBD
+QTAeFw0xNjEyMDkyMDE4NTdaFw0yNjEyMDcyMDE4NTdaMBgxFjAUBgNVBAMMDUNs
+aWVudCBDZXJ0IEkwgZswEAYHKoZIzj0CAQYFK4EEACMDgYYABACtf0oyHoxXTu/j
+oG5I2fTeeYe6ZCEKlz2D5cMckF4bIkjRpue12TMhzs7FYp0cg+My3bxOA87t7os/
+vXJ3SZxGCwBFIQJc/vMSz7eOlaYHWXYY+vuD4Ab/j34lv1U+6LjtinWoI2WAbq/r
+xzSku9/NnLtKATbz3YgnYyzCEsmxQHfiKqMvMC0wDAYDVR0TAQH/BAIwADAdBgNV
+HSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAI17
+RGEzku9zF7exldjzhwI2HPfRAA0rWYiAMZML7+jAGca7iSY6bkeQC7KZ1UYZxMth
+61FudPfQh087CP5aSKMjzLRdpLYMePGy8DZx18an4YBZpme0Kuq1G5+iu00BNuNY
+7Rm95rSO1zy3zJV2i+nseMDeGwkE10RsLDzDDjncvjvr7H21uT7m68DvFa/Klh3w
+nronQaJ8Zmd9N2UMZreqG+iIVfFQVLk244ScJ6n6jAYGzgJjhaZw3fx4HyYfEwGq
+jTRUgCMohL+QpBph54OQk7cLEx3FeHt0610Y8bLdbCMQvIAcFDjmdtV4uToKVzi9
+/kWwaKOMHq4lhC/cerI=
+-----END CERTIFICATE-----
diff --git a/net/data/ssl/certificates/client_6.pk8 b/net/data/ssl/certificates/client_6.pk8
new file mode 100644
index 0000000..62c42f4
--- /dev/null
+++ b/net/data/ssl/certificates/client_6.pk8
Binary files differ
diff --git a/net/data/ssl/certificates/client_6_ca.pem b/net/data/ssl/certificates/client_6_ca.pem
new file mode 100644
index 0000000..78080961
--- /dev/null
+++ b/net/data/ssl/certificates/client_6_ca.pem
@@ -0,0 +1,71 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 4098 (0x1002)
+    Signature Algorithm: sha256WithRSAEncryption
+        Issuer: CN=C Root CA
+        Validity
+            Not Before: Dec  9 20:18:57 2016 GMT
+            Not After : Dec  7 20:18:57 2026 GMT
+        Subject: CN=E CA
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:c3:39:c3:5a:8e:ff:f2:1d:cc:26:91:5d:15:9e:
+                    ca:e0:fb:cf:99:5f:13:3d:c6:37:59:8b:ce:cc:76:
+                    0e:1c:9f:b6:49:5b:09:97:63:9d:e1:00:74:44:fb:
+                    2f:53:f3:d5:03:92:77:97:53:74:7e:d2:da:d3:a3:
+                    f4:c1:91:6a:83:ff:89:fe:73:46:56:ca:6d:51:0d:
+                    57:16:3d:3e:e8:fc:00:d9:4a:7a:7d:93:84:06:12:
+                    c5:ff:31:b3:a6:eb:96:18:71:b8:56:5c:2f:ab:78:
+                    e2:53:dd:15:d8:65:c8:f6:96:14:dc:15:cf:2a:39:
+                    ed:e1:08:1b:84:29:c7:1c:78:67:c8:e0:72:58:4e:
+                    33:7f:cb:ef:71:82:db:45:1d:7c:0c:d0:f5:4c:af:
+                    85:6b:14:61:50:87:34:42:fe:45:a3:3c:a3:53:57:
+                    1d:ac:11:c8:cf:2f:5e:cb:78:87:39:a1:41:3f:69:
+                    21:5c:1e:19:02:a3:6c:91:d3:1b:4e:50:fc:a4:b1:
+                    03:87:c0:58:b1:fe:cd:58:5e:53:ed:c9:d6:5d:9e:
+                    a3:fb:0d:e0:a0:8e:3d:c9:9e:9e:83:07:61:c7:30:
+                    5a:ca:29:93:04:af:5e:f3:57:2e:c2:d8:c8:ae:7f:
+                    5c:a4:27:fa:cd:55:a2:fd:89:d2:0b:87:24:6b:7b:
+                    fb:19
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: critical
+                CA:TRUE
+            X509v3 Key Usage: critical
+                Certificate Sign, CRL Sign
+    Signature Algorithm: sha256WithRSAEncryption
+         67:d4:6c:cf:cd:54:81:67:2a:c2:c4:66:c7:76:9c:b0:8b:6b:
+         ef:b8:ae:a9:b3:d6:f8:47:91:d5:97:0b:bd:1a:87:21:8c:ce:
+         be:0c:80:d5:a5:25:0d:0a:c7:ed:be:cb:8c:6d:08:e8:de:a5:
+         33:89:e6:87:df:2b:f4:54:b3:c2:94:15:0d:36:5e:1a:aa:c0:
+         b0:03:3c:24:c6:a1:81:91:ca:fe:db:0f:59:1b:d6:4e:48:0b:
+         52:d3:e7:07:d7:b1:ca:b2:22:e4:d4:37:a4:3c:87:3c:0a:11:
+         a6:10:2a:ed:86:2a:bb:db:10:7e:f3:a5:fc:10:ab:80:5b:07:
+         58:7c:22:76:3e:9b:9c:72:79:0d:dc:85:f8:e7:c2:0f:17:aa:
+         01:dd:8e:24:27:77:4e:23:03:da:88:e0:df:e6:ca:b4:84:56:
+         a1:dc:9f:e0:93:94:97:d2:98:cd:32:6d:73:84:f9:3e:4c:96:
+         b3:51:07:b8:9f:66:32:d1:ac:53:0e:17:a9:6f:29:d1:7b:73:
+         b3:55:9b:cc:8f:8b:e5:49:fd:fd:f2:30:d6:d0:f7:03:06:12:
+         e3:66:2d:0d:a1:da:28:04:04:29:b8:40:6e:0e:6f:31:48:cb:
+         54:f7:e2:89:22:d8:05:e0:f5:7e:48:b3:96:ff:6b:ef:e7:fe:
+         71:1d:0b:77
+-----BEGIN CERTIFICATE-----
+MIICwjCCAaqgAwIBAgICEAIwDQYJKoZIhvcNAQELBQAwFDESMBAGA1UEAwwJQyBS
+b290IENBMB4XDTE2MTIwOTIwMTg1N1oXDTI2MTIwNzIwMTg1N1owDzENMAsGA1UE
+AwwERSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMM5w1qO//Id
+zCaRXRWeyuD7z5lfEz3GN1mLzsx2DhyftklbCZdjneEAdET7L1Pz1QOSd5dTdH7S
+2tOj9MGRaoP/if5zRlbKbVENVxY9Puj8ANlKen2ThAYSxf8xs6brlhhxuFZcL6t4
+4lPdFdhlyPaWFNwVzyo57eEIG4Qpxxx4Z8jgclhOM3/L73GC20UdfAzQ9UyvhWsU
+YVCHNEL+RaM8o1NXHawRyM8vXst4hzmhQT9pIVweGQKjbJHTG05Q/KSxA4fAWLH+
+zVheU+3J1l2eo/sN4KCOPcmenoMHYccwWsopkwSvXvNXLsLYyK5/XKQn+s1Vov2J
+0guHJGt7+xkCAwEAAaMjMCEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
+AQYwDQYJKoZIhvcNAQELBQADggEBAGfUbM/NVIFnKsLEZsd2nLCLa++4rqmz1vhH
+kdWXC70ahyGMzr4MgNWlJQ0Kx+2+y4xtCOjepTOJ5offK/RUs8KUFQ02XhqqwLAD
+PCTGoYGRyv7bD1kb1k5IC1LT5wfXscqyIuTUN6Q8hzwKEaYQKu2GKrvbEH7zpfwQ
+q4BbB1h8InY+m5xyeQ3chfjnwg8XqgHdjiQnd04jA9qI4N/myrSEVqHcn+CTlJfS
+mM0ybXOE+T5MlrNRB7ifZjLRrFMOF6lvKdF7c7NVm8yPi+VJ/f3yMNbQ9wMGEuNm
+LQ2h2igEBCm4QG4ObzFIy1T34oki2AXg9X5Is5b/a+/n/nEdC3c=
+-----END CERTIFICATE-----
diff --git a/net/data/ssl/certificates/client_root_ca.pem b/net/data/ssl/certificates/client_root_ca.pem
index b4048103..cb41907 100644
--- a/net/data/ssl/certificates/client_root_ca.pem
+++ b/net/data/ssl/certificates/client_root_ca.pem
@@ -1,18 +1,18 @@
 -----BEGIN CERTIFICATE-----
-MIICzjCCAbagAwIBAgIJAO+K/Ai3YiytMA0GCSqGSIb3DQEBCwUAMBQxEjAQBgNV
-BAMMCUMgUm9vdCBDQTAeFw0xNjEwMDQxODUzMjRaFw0yNjEwMDIxODUzMjRaMBQx
+MIICzjCCAbagAwIBAgIJAOlWtiy6ZPwFMA0GCSqGSIb3DQEBCwUAMBQxEjAQBgNV
+BAMMCUMgUm9vdCBDQTAeFw0xNjEyMDkyMDE4NTdaFw0yNjEyMDcyMDE4NTdaMBQx
 EjAQBgNVBAMMCUMgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
-ggEBALKU+gX11E3vQ6CHy5bNfePr5uiJMHX+P97/I8y8DCk117+0gGxlO4adwImE
-dgA6jFmMcphJU+BPfi1eDwO2WHQVa31NALMy3CbEzv4qV1gqTAfNJdICKZk7S87E
-GbZUBauHe8q443UwD3c+R49XTsGvUSoMjh3N7K0/kNeoLi4RLW6WOZvJh954Rj+I
-EHmCibJENDfzdYWfQtLZJEYrzJv01ZdWcigvOR7qQqLdX6f2WTBaWpjgSnP5QzO/
-8gkX+rVRRUpbD/lMNdXqO9AoBcSG07tWMx1MDRnDG8SzrCQ4sScSbcPnHQDEbdDv
-suCnGXzSerruQXCqVwcCHIEHRSMCAwEAAaMjMCEwDwYDVR0TAQH/BAUwAwEB/zAO
-BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAHL9wuInYSfItXwoO2jG
-W08CPjcPMN1Q7yulKFtND6jU4cWB/m2xQmpMjhrahrF1hYwwiOXfwB+bxHOoekmK
-Uf+WmsiFXUQ5q9IeBMnxrrKOqZ9X2S+WaTi9GosJ52IEX4JJT7w3JDEcNTh3h66g
-FHB9cXao0EDx5fkEvSCKhcSy+tWjWzUB+GszG3ApCe0ZxbcehUSRSZTcLYvlNlXF
-NMNvEH5C1BVzCQWAZlgT4gp4miEPCFTc4Vr90pgDzJ3eFWu4V0s6snyDOip0PD9A
-N6wOvSix25wUYni46xGHFc9ZZn3x35HdhW9+IMAgJI14hMsoIHQwAgzqF4neRYvY
-RT4=
+ggEBAMA+ZigXbDXCxJ4JCLXzWo/3dzVU/lQgToMmzXMAN7YLkYrpMHSh0+YgrtOv
+XA70wFaLPa6SYGqr9OU2FqTlob43GQU9uNmIOi/SNmz3WRudoJgqbYK0Gv4qRarR
+wrNqpPWgQXxP3T/slF7UVV0JRFWcscXPIxVIOQ64qGTtMpzjYP21g0V8e6pz30U9
+/9iil7FdSVIpjKc2RN42QGi2URIe2hYOIgCMADO/m5eUMVVX3wJ+ka4X619uTFrg
+BEexVhIMu5ZPwEXcyUBxebLzJqx+JTwe2P2/20UMGQBSqT9xsXcuW8Y3+5q7Vl0j
+7F5u9pE2PAZiVuDLWE3TXFSwVd8CAwEAAaMjMCEwDwYDVR0TAQH/BAUwAwEB/zAO
+BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAJE45oY5GAmSefzxBKI2
+mVfZj7TlUG/KQ1W7RrsoDeYb93PTA/S4XM56wQhT8vdz3imED83EZ1hoDFourhAV
+hNVCSSHBJ/Bgtj3Yt6bUZdx0dSK5PbnvfTYAnRxzx0o8d4pRXb0G225BT3kYNIOK
+E1M24xmnjP3OoeyqWzP7uyU7vxfA4oCloNgeMWMJ9zdfgRX8Qnj6XRHVuhMXdofn
+7vB9dpsbJI5ozXaFYuXMKZ8g97M1vUzWTQsbUWc/L3YaO+UZOQXg1gLHhZmwn9MC
+xZSldz7Z4QIDV+U03cJUKL5O4hQcMgrtug2d75vxMKVjETKkvqbzs56h62YmhEyw
+3Gg=
 -----END CERTIFICATE-----
diff --git a/net/data/ssl/scripts/generate-client-certificates.sh b/net/data/ssl/scripts/generate-client-certificates.sh
index e7c8c01..5e584b2 100755
--- a/net/data/ssl/scripts/generate-client-certificates.sh
+++ b/net/data/ssl/scripts/generate-client-certificates.sh
@@ -14,6 +14,8 @@
 #   2. D (end-entity) -> E -> C (self-signed root)
 #   3. F (end-entity) -> E -> C (self-signed root)
 #   4. G (end-entity, P-256) -> E -> C (self-signed root)
+#   5. H (end-entity, P-384) -> E -> C (self-signed root)
+#   6. I (end-entity, P-521) -> E -> C (self-signed root)
 #
 # In which the certificates all have distinct keypairs. The client
 # certificates share the same root, but are issued by different
@@ -45,6 +47,8 @@
 done
 
 try openssl ecparam -name prime256v1 -genkey -noout -out out/G.key
+try openssl ecparam -name secp384r1 -genkey -noout -out out/H.key
+try openssl ecparam -name secp521r1 -genkey -noout -out out/I.key
 
 echo Generate the C CSR
 COMMON_NAME="C Root CA" \
@@ -108,7 +112,7 @@
     -config client-certs.cnf
 
 echo Generate the leaf certs
-for id in A D F G
+for id in A D F G H I
 do
   COMMON_NAME="Client Cert $id" \
   ID=$id \
@@ -169,12 +173,36 @@
     -out out/G.pem \
     -config client-certs.cnf
 
+echo E signs H
+COMMON_NAME="E CA" \
+  CA_DIR=out \
+  ID=E \
+  try openssl ca \
+    -batch \
+    -extensions user_cert \
+    -in out/H.csr \
+    -out out/H.pem \
+    -config client-certs.cnf
+
+echo E signs I
+COMMON_NAME="E CA" \
+  CA_DIR=out \
+  ID=E \
+  try openssl ca \
+    -batch \
+    -extensions user_cert \
+    -in out/I.csr \
+    -out out/I.pem \
+    -config client-certs.cnf
+
 echo Package the client certs and private keys into PKCS12 files
 # This is done for easily importing all of the certs needed for clients.
 try /bin/sh -c "cat out/A.pem out/A.key out/B.pem out/C.pem > out/A-chain.pem"
 try /bin/sh -c "cat out/D.pem out/D.key out/E.pem out/C.pem > out/D-chain.pem"
 try /bin/sh -c "cat out/F.pem out/F.key out/E.pem out/C.pem > out/F-chain.pem"
 try /bin/sh -c "cat out/G.pem out/G.key out/E.pem out/C.pem > out/G-chain.pem"
+try /bin/sh -c "cat out/H.pem out/H.key out/E.pem out/C.pem > out/H-chain.pem"
+try /bin/sh -c "cat out/I.pem out/I.key out/E.pem out/C.pem > out/I-chain.pem"
 
 try openssl pkcs12 \
   -in out/A-chain.pem \
@@ -200,6 +228,18 @@
   -export \
   -passout pass:chrome
 
+try openssl pkcs12 \
+  -in out/H-chain.pem \
+  -out client_5.p12 \
+  -export \
+  -passout pass:chrome
+
+try openssl pkcs12 \
+  -in out/I-chain.pem \
+  -out client_6.p12 \
+  -export \
+  -passout pass:chrome
+
 echo Package the client certs for unit tests
 try cp out/A.pem ../certificates/client_1.pem
 try cp out/A.key ../certificates/client_1.key
@@ -221,4 +261,14 @@
 try cp out/G.pk8 ../certificates/client_4.pk8
 try cp out/E.pem ../certificates/client_4_ca.pem
 
+try cp out/H.pem ../certificates/client_5.pem
+try cp out/H.key ../certificates/client_5.key
+try cp out/H.pk8 ../certificates/client_5.pk8
+try cp out/E.pem ../certificates/client_5_ca.pem
+
+try cp out/I.pem ../certificates/client_6.pem
+try cp out/I.key ../certificates/client_6.key
+try cp out/I.pk8 ../certificates/client_6.pk8
+try cp out/E.pem ../certificates/client_6_ca.pem
+
 try cp out/C.pem ../certificates/client_root_ca.pem
diff --git a/net/docs/crash-course-in-net-internals.md b/net/docs/crash-course-in-net-internals.md
index 008a5755..9187f85 100644
--- a/net/docs/crash-course-in-net-internals.md
+++ b/net/docs/crash-course-in-net-internals.md
@@ -14,77 +14,138 @@
 For this reason, it lacks knowledge of tabs, navigation, frames, resource types,
 etc.
 
-The top level network stack object is the URLRequestContext.  The Events View
+The leftmost column presents a list of views.  Most debugging is done with the
+Events view, which will be all this document covers.
+
+The top level network stack object is the URLRequestContext.  The Events view
 has information for all Chrome URLRequestContexts that are hooked up to the
-single, global, ChromeNetLog object.  This includes both incognito and non-
-incognito profiles, among other things.  The Events view only shows events for
-the period that net-internals was open and running, and is incrementally updated
-as events occur.  The code attempts to add a top level event for URLRequests
-that were active when the tab was opened, to help debug hung requests, but
-that's best-effort only, and only includes requests for the current profile and
-the system URLRequestContext.
+single, global, ChromeNetLog object.  This includes both incognito and
+non-incognito profiles, among other things.  The Events view only shows events
+for the period that net-internals was open and running, and is incrementally
+updated as events occur.  The code attempts to add a top level event for
+URLRequests that were active when the about:net-internals tab was opened, to
+help debug hung requests, but that's best-effort only, and only includes
+requests for the current profile and the system URLRequestContext.
 
 The other views are all snapshots of the current state of the main
 URLRequestContext's components, and are updated on a 5 second timer.  These will
-show objects that were created before about:net-internals was opened.  Most
-debugging is done with the Events view (which will be all this document
-covers), but it's good to be aware of this distinction.
+show objects that were created before about:net-internals was opened.
 
 # Events vs Sources
 
-The Event View shows events logged by the NetLog.  The NetLog model is that
+The Events view shows events logged by the NetLog.  The NetLog model is that
 long-lived network stack objects, called sources, emit events over their
-lifetime.  When looking at the code, a "NetLogWithSource" object contains a source
-ID, and a pointer to the NetLog the source emits events to.  Some events have a
-beginning and end point (during which other subevents may occur), and some only
-occur at a single point in time.  Generally only one event can be occuring for a
-source at a time.  If there can be multiple events doing completely independent
-thing, the code often uses new sources to represent the parallelism.
+lifetime.  A NetLogWithSource object contains a source ID, a NetLogSourceType,
+and a pointer to the NetLog the source emits events to.
+
+The Events view has a list of sources in a column adjacent to the list of views.
+Sources that include an event with a net_error parameter with negative value
+(that is, some kind of ERR_) are shown with red background.  Sources whose
+opening event has not ended yet are shown with white background.  Other events
+have green background.  The search queries corresponding to the first two kinds
+are `is:error` and `is:active`.
+
+When one or more sources are selected, corresponding events show up in another
+column to the right, sorted by source, and by time within each source.  There
+are two time values: t is measured from some reference point common to all
+sources, and st is measured from the first event for each source.  Time is
+displayed in milliseconds.
+
+Since the network stack is asynchronous, events from different sources will
+often be interlaced in time, but Events view does not feature showing events from
+different sources ordered by time.  Large time gaps in the event list of a
+single source usually mean that time is spent in the context of another source.
+
+Some events come in pairs: a beginning and end event, between which other events
+may occur.  They are shown with + and - prefixes, respectively.  The begin event
+has a dt value which shows the duration.  If the end event was captured, then
+duration is calculated as the time difference between the begin and the end
+events.  Otherwise the time elapsed from the begin event until capturing
+was stopped is displayed (a lower bound for actual duration), followed by a +
+sign (for example, "dt=120+").
+
+If there are no other events in between the begin and end, and the end event has
+no parameters, then they are collapsed in a single line without a sign prefix.
+
+Some other events only occur at a single point in time, and will not have either
+a sign prefix, or a dt duration value.
+
+Generally only one event can be occuring for a source at a time.  If there can
+be multiple events doing completely independent things, the code often uses new
+sources to represent the parallelism.
+
+Most, but not all events correspond to a source.  Exceptions are global events,
+which have no source, and show up as individual entries in the source list.
+Examples of global events include NETWORK_CHANGED, DNS_CONFIG_CHANGED, and
+PROXY_CONFIG_CHANGED.
+
+# Common source types
 
 "Sources" correspond to certain net objects, however, multiple layers of net/
 will often log to a single source.  Here are the main source types and what they
-include (Excluding HTTP2 [SPDY]/QUIC):
+include (excluding HTTP2 [SPDY]/QUIC):
 
 * URL_REQUEST:  This corresponds to the URLRequest object.  It includes events
 from all the URLRequestJobs, HttpCache::Transactions, NetworkTransactions,
 HttpStreamFactoryImpl::Requests, HttpStream implementations, and
 HttpStreamParsers used to service a response.  If the URL_REQUEST follows HTTP
 redirects, it will include each redirect.  This is a lot of stuff, but generally
-only object is doing work at a time.  This event source includes the full URL
-and generally includes the request / response headers (Except when the cache
+only one object is doing work at a time.  This event source includes the full
+URL and generally includes the request / response headers (except when the cache
 handles the response).
 
-* HTTP_STREAM_JOB:  This corresponds to HttpStreamFactoryImpl::Job (Note that
+* HTTP_STREAM_JOB:  This corresponds to HttpStreamFactoryImpl::Job (note that
 one Request can have multiple Jobs).  It also includes its proxy and DNS
-lookups.  HTTP_STREAM_JOB log events are separate from URL_REQUEST because
-two stream jobs may be created and races against each other, in some cases -
-one for one for QUIC, and one for HTTP.  One of the final events of this source
-indicates how an HttpStream was created (Reusing an existing SOCKET /
-HTTP2_SESSION / QUIC_SESSION, or creating a new one).
+lookups.  HTTP_STREAM_JOB log events are separate from URL_REQUEST because two
+stream jobs may be created and races against each other, in some cases -- one
+for QUIC, and one for HTTP.
+
+    One of the final events of this source, before the
+    HTTP_STREAM_JOB_BOUND_TO_REQUEST event, indicates how an HttpStream was
+    created:
+
+    + A SOCKET_POOL_BOUND_TO_CONNECT_JOB event means that a new TCP socket was
+    created, whereas a SOCKET_POOL_REUSED_AN_EXISTING_SOCKET event indicates that
+    an existing TCP socket was reused for a non-HTTP/2 request.
+
+    + An HTTP2_SESSION_POOL_IMPORTED_SESSION_FROM_SOCKET event indicates that a
+    new HTTP/2 session was opened by this Job.
+
+    + An HTTP2_SESSION_POOL_FOUND_EXISTING_SESSION event indicates that the request
+    was served on a preexisting HTTP/2 session.
+
+    + An HTTP2_SESSION_POOL_FOUND_EXISTING_SESSION_FROM_IP_POOL event means that
+    the request was pooled to a preexisting HTTP/2 session which had a different
+    SpdySessionKey, but DNS resolution resulted in the same IP, and the
+    certificate matches.
+
+    + There are currently no events logged for opening new QUIC sessions or
+    reusing existing ones.
 
 * \*_CONNECT_JOB:  This corresponds to the ConnectJob subclasses that each socket
-pool uses.  A successful CONNECT_JOB return a SOCKET.  The events here vary a
+pool uses.  A successful CONNECT_JOB returns a SOCKET.  The events here vary a
 lot by job type.  Their main event is generally either to create a socket, or
-request a socket from another socket pool (Which creates another CONNECT_JOB)
-and then do some extra work on top of that - like establish an SSL connection on
+request a socket from another socket pool (which creates another CONNECT_JOB)
+and then do some extra work on top of that -- like establish an SSL connection on
 top of a TCP connection.
 
 * SOCKET:  These correspond to TCPSockets, but may also have other classes
-layered on top of them (Like an SSLClientSocket).  This is a bit different from
+layered on top of them (like an SSLClientSocket).  This is a bit different from
 the other classes, where the name corresponds to the topmost class, instead of
 the bottommost one.  This is largely an artifact of the fact the socket is
-created first, and then SSL (Or a proxy connection) is layered on top of it.
+created first, and then SSL (or a proxy connection) is layered on top of it.
 SOCKETs may be reused between multiple requests, and a request may end up
 getting a socket created for another request.
 
-* HOST_RESOLVER_IMPL_JOB:  These correspond to HostResolverImpl::Job.  The
+* HOST_RESOLVER_IMPL_JOB:  These correspond to HostResolverImpl::Job.  They
 include information about how long the lookup was queued, each DNS request that
-was attempted (With the platform or built-in resolver) and all the other sources
+was attempted (with the platform or built-in resolver) and all the other sources
 that are waiting on the job.
 
-When one source depends on another, the code generally logs an event with
-"source_dependency" value to both sources, which lets you jump between the two
-related events.
+When one source depends on another, the code generally logs an event at both
+sources with a `source_dependency` value pointing to the other source.  These
+are clickable in the UI, adding the referred source to the list of selected
+sources.
 
 # Debugging
 
@@ -96,9 +157,9 @@
 about the actual problem.  There are two filters in net-internals that can help
 in a lot of cases:
 
-* "type:URL_REQUEST is:error" will restrict the list to URL_REQUEST object with
-an error of some sort (red background).  Cache errors are often non-fatal, so
-you should generally ignore those, and look for a more interesting one.
+* "type:URL_REQUEST is:error" will restrict the source list to URL_REQUEST
+objects with an error of some sort.  Cache errors are often non-fatal, so you
+should generally ignore those, and look for a more interesting one.
 
 * "type:URL_REQUEST sort:duration" will show the longest-lived requests first.
 This is often useful in finding hung or slow requests.
@@ -107,14 +168,11 @@
 about:net-internals.
 
 Once you locate the problematic request, the next is to figure out where the
-problem is - it's often one of the last events, though it could also be related
-to response or request headers.  You can use "source_dependency" links to drill
-down into other related sources, or up from layers below URL_REQUEST.
-
-You can use the name of an event to search for the code responsible for that
-event, and try to deduce what went wrong before/after a particular event.  Note
-that the event names used in net-internals are not the entire string names, so
-you should not do an entire string match.
+problem is -- it's often one of the last events, though it could also be related
+to response or request headers.  You can use `source_dependency` links to
+navigate between related sources.  You can use the name of an event to search
+for the code responsible for that event, and try to deduce what went wrong
+before/after a particular event.
 
 Some things to look for while debugging:
 
@@ -122,8 +180,7 @@
 
 * Changing networks and entering / exiting suspend mode can have all sorts of
 fun and exciting effects on underway network activity.  Network changes log a
-top level NETWORK_CHANGED event with no source - the event itself is treated as
-its own source.  Suspend events are currently not logged.
+top level NETWORK_CHANGED event.  Suspend events are currently not logged.
 
 * URL_REQUEST_DELEGATE / DELEGATE_INFO events mean a URL_REQUEST is blocked on a
 URLRequest::Delegate or the NetworkDelegate, which are implemented outside the
@@ -136,7 +193,8 @@
 
 * Sockets are often reused between requests.  If a request is on a stale
 (reused) socket, what was the previous request that used the socket, how long
-ago was it made?
+ago was it made?  (Look at SOCKET_IN_USE events, and the HTTP_STREAM_JOBS they
+point to via the `source_dependency` value.)
 
 * SSL negotation is a process fraught with peril, particularly with broken
 proxies.  These will generally stall or fail in the SSL_CONNECT phase at the
@@ -146,15 +204,15 @@
 issued by the media and PDF code.
 
 * Late binding:  HTTP_STREAM_JOBs are not associated with any CONNECT_JOB until
-a CONNECT_JOB actually connects.  This is so the highest priority pending job
-gets the first available socket (Which may be a new socket, or an old one that's
-freed up).  For this reason, it can be a little tricky to relate hung
-HTTP_STREAM_JOBs to CONNECT_JOBs.
+a CONNECT_JOB actually connects.  This is so the highest priority pending
+HTTP_STREAM_JOB gets the first available socket (which may be a new socket, or
+an old one that's freed up).  For this reason, it can be a little tricky to
+relate hung HTTP_STREAM_JOBs to CONNECT_JOBs.
 
 * Each CONNECT_JOB belongs to a "group", which has a limit of 6 connections.  If
-all CONNECT_JOBs beling to a group (The CONNECT_JOB's description field) are
+all CONNECT_JOBs belonging to a group (the CONNECT_JOB's description field) are
 stalled waiting on an available socket, the group probably has 6 sockets that
-that are hung - either hung trying to connect, or used by stalled requests and
+that are hung -- either hung trying to connect, or used by stalled requests and
 thus outside the socket pool's control.
 
 * There's a limit on number of DNS resolutions that can be started at once.  If
diff --git a/net/http/http_server_properties_manager.cc b/net/http/http_server_properties_manager.cc
index 6f1b8a6a..0c4d2fe 100644
--- a/net/http/http_server_properties_manager.cc
+++ b/net/http/http_server_properties_manager.cc
@@ -100,7 +100,7 @@
   http_server_properties_impl_.reset(new HttpServerPropertiesImpl());
 
   network_prefs_update_timer_.reset(new base::OneShotTimer);
-
+  network_prefs_update_timer_->SetTaskRunner(network_task_runner_);
   pref_task_runner_->PostTask(
       FROM_HERE,
       base::Bind(&HttpServerPropertiesManager::UpdateCacheFromPrefsOnPrefThread,
diff --git a/net/http/http_server_properties_manager_unittest.cc b/net/http/http_server_properties_manager_unittest.cc
index 97b5a24..c88b296 100644
--- a/net/http/http_server_properties_manager_unittest.cc
+++ b/net/http/http_server_properties_manager_unittest.cc
@@ -16,6 +16,7 @@
 #include "base/single_thread_task_runner.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
+#include "base/test/test_mock_time_task_runner.h"
 #include "base/test/test_simple_task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/values.h"
@@ -29,6 +30,7 @@
 namespace {
 
 using base::StringPrintf;
+using base::TestMockTimeTaskRunner;
 using ::testing::_;
 using ::testing::Invoke;
 using ::testing::Mock;
@@ -149,14 +151,16 @@
 
 class HttpServerPropertiesManagerTest : public testing::TestWithParam<int> {
  protected:
-  HttpServerPropertiesManagerTest() {}
+  HttpServerPropertiesManagerTest()
+      : net_test_task_runner_(new TestMockTimeTaskRunner()) {}
 
   void SetUp() override {
     one_day_from_now_ = base::Time::Now() + base::TimeDelta::FromDays(1);
     pref_delegate_ = new MockPrefDelegate;
     http_server_props_manager_.reset(
         new StrictMock<TestingHttpServerPropertiesManager>(
-            pref_delegate_, base::ThreadTaskRunnerHandle::Get()));
+            pref_delegate_, net_test_task_runner_));
+
     ExpectCacheUpdate();
     base::RunLoop().RunUntilIdle();
   }
@@ -218,6 +222,7 @@
   std::unique_ptr<TestingHttpServerPropertiesManager>
       http_server_props_manager_;
   base::Time one_day_from_now_;
+  scoped_refptr<TestMockTimeTaskRunner> net_test_task_runner_;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(HttpServerPropertiesManagerTest);
@@ -357,6 +362,8 @@
   pref_delegate_->SetPrefs(http_server_properties_dict);
 
   base::RunLoop().RunUntilIdle();
+  net_test_task_runner_->FastForwardUntilNoTasksRemain();
+
   Mock::VerifyAndClearExpectations(http_server_props_manager_.get());
 
   // Verify SupportsSpdy.
@@ -447,7 +454,7 @@
 
 TEST_P(HttpServerPropertiesManagerTest, BadCachedHostPortPair) {
   ExpectCacheUpdate();
-  // The prefs are automaticalls updated in the case corruption is detected.
+  // The prefs are automatically updated in the case corruption is detected.
   ExpectPrefsUpdate();
   ExpectScheduleUpdatePrefsOnNetworkThread();
 
@@ -509,6 +516,8 @@
   pref_delegate_->SetPrefs(http_server_properties_dict);
 
   base::RunLoop().RunUntilIdle();
+  net_test_task_runner_->FastForwardUntilNoTasksRemain();
+
   Mock::VerifyAndClearExpectations(http_server_props_manager_.get());
 
   // Verify that nothing is set.
@@ -528,7 +537,7 @@
 
 TEST_P(HttpServerPropertiesManagerTest, BadCachedAltProtocolPort) {
   ExpectCacheUpdate();
-  // The prefs are automaticalls updated in the case corruption is detected.
+  // The prefs are automatically updated in the case corruption is detected.
   ExpectPrefsUpdate();
   ExpectScheduleUpdatePrefsOnNetworkThread();
 
@@ -573,6 +582,8 @@
   pref_delegate_->SetPrefs(http_server_properties_dict);
 
   base::RunLoop().RunUntilIdle();
+  net_test_task_runner_->FastForwardUntilNoTasksRemain();
+
   Mock::VerifyAndClearExpectations(http_server_props_manager_.get());
 
   // Verify alternative service is not set.
@@ -597,6 +608,7 @@
 
   // Run the task.
   base::RunLoop().RunUntilIdle();
+  net_test_task_runner_->FastForwardUntilNoTasksRemain();
 
   EXPECT_TRUE(http_server_props_manager_->SupportsRequestPriority(spdy_server));
   Mock::VerifyAndClearExpectations(http_server_props_manager_.get());
@@ -618,6 +630,8 @@
 
   // Run the task.
   base::RunLoop().RunUntilIdle();
+  net_test_task_runner_->FastForwardUntilNoTasksRemain();
+
   Mock::VerifyAndClearExpectations(http_server_props_manager_.get());
 
   AlternativeServiceVector alternative_service_vector =
@@ -649,6 +663,8 @@
 
   // Run the task.
   base::RunLoop().RunUntilIdle();
+  net_test_task_runner_->FastForwardUntilNoTasksRemain();
+
   Mock::VerifyAndClearExpectations(http_server_props_manager_.get());
 
   AlternativeServiceVector alternative_service_vector =
@@ -712,6 +728,8 @@
 
   // Run the task.
   base::RunLoop().RunUntilIdle();
+  net_test_task_runner_->FastForwardUntilNoTasksRemain();
+
   Mock::VerifyAndClearExpectations(http_server_props_manager_.get());
 
   EXPECT_FALSE(http_server_props_manager_->IsAlternativeServiceBroken(
@@ -734,6 +752,8 @@
 
   // Run the task.
   base::RunLoop().RunUntilIdle();
+  net_test_task_runner_->FastForwardUntilNoTasksRemain();
+
   Mock::VerifyAndClearExpectations(http_server_props_manager_.get());
 
   EXPECT_TRUE(http_server_props_manager_->GetSupportsQuic(&address));
@@ -756,6 +776,8 @@
 
   // Run the task.
   base::RunLoop().RunUntilIdle();
+  net_test_task_runner_->FastForwardUntilNoTasksRemain();
+
   Mock::VerifyAndClearExpectations(http_server_props_manager_.get());
 
   const ServerNetworkStats* stats2 =
@@ -779,6 +801,8 @@
 
   // Run the task.
   base::RunLoop().RunUntilIdle();
+  net_test_task_runner_->FastForwardUntilNoTasksRemain();
+
   Mock::VerifyAndClearExpectations(http_server_props_manager_.get());
 
   EXPECT_EQ(quic_server_info1, *http_server_props_manager_->GetQuicServerInfo(
@@ -807,6 +831,7 @@
 
   // Run the task.
   base::RunLoop().RunUntilIdle();
+  net_test_task_runner_->FastForwardUntilNoTasksRemain();
 
   EXPECT_TRUE(http_server_props_manager_->SupportsRequestPriority(spdy_server));
   EXPECT_TRUE(HasAlternativeService(spdy_server));
@@ -912,6 +937,8 @@
   pref_delegate_->SetPrefs(http_server_properties_dict);
 
   base::RunLoop().RunUntilIdle();
+  net_test_task_runner_->FastForwardUntilNoTasksRemain();
+
   Mock::VerifyAndClearExpectations(http_server_props_manager_.get());
 
   // Verify alternative service.
@@ -983,6 +1010,8 @@
   ExpectPrefsUpdate();
   ExpectCacheUpdate();
   http_server_props_manager_->ScheduleUpdateCacheOnPrefThread();
+
+  net_test_task_runner_->FastForwardUntilNoTasksRemain();
   base::RunLoop().RunUntilIdle();
 
   // Verify preferences.
@@ -1114,6 +1143,8 @@
   ExpectPrefsUpdate();
   ExpectCacheUpdate();
   http_server_props_manager_->ScheduleUpdateCacheOnPrefThread();
+
+  net_test_task_runner_->FastForwardUntilNoTasksRemain();
   base::RunLoop().RunUntilIdle();
 
   const base::DictionaryValue& pref_dict =
@@ -1241,7 +1272,9 @@
   // Shutdown comes before the task is executed.
   http_server_props_manager_->ShutdownOnPrefThread();
   // Run the task after shutdown, but before deletion.
+  net_test_task_runner_->FastForwardUntilNoTasksRemain();
   base::RunLoop().RunUntilIdle();
+
   Mock::VerifyAndClearExpectations(http_server_props_manager_.get());
   http_server_props_manager_.reset();
   base::RunLoop().RunUntilIdle();
diff --git a/net/net.gypi b/net/net.gypi
index 79e7e02..cb983a25 100644
--- a/net/net.gypi
+++ b/net/net.gypi
@@ -2400,6 +2400,14 @@
       'data/ssl/certificates/client_4.pem',
       'data/ssl/certificates/client_4.pk8',
       'data/ssl/certificates/client_4_ca.pem',
+      'data/ssl/certificates/client_5.key',
+      'data/ssl/certificates/client_5.pem',
+      'data/ssl/certificates/client_5.pk8',
+      'data/ssl/certificates/client_5_ca.pem',
+      'data/ssl/certificates/client_6.key',
+      'data/ssl/certificates/client_6.pem',
+      'data/ssl/certificates/client_6.pk8',
+      'data/ssl/certificates/client_6_ca.pem',
       'data/ssl/certificates/client_root_ca.pem',
       'data/ssl/certificates/comodo.chain.pem',
       'data/ssl/certificates/crit-codeSigning-chain.pem',
diff --git a/net/spdy/hpack/hpack_encoder.cc b/net/spdy/hpack/hpack_encoder.cc
index 7362bb1a..f186b6a4 100644
--- a/net/spdy/hpack/hpack_encoder.cc
+++ b/net/spdy/hpack/hpack_encoder.cc
@@ -82,7 +82,7 @@
       min_table_size_setting_received_(std::numeric_limits<size_t>::max()),
       listener_(NoOpListener),
       should_index_(DefaultPolicy),
-      allow_huffman_compression_(true),
+      enable_compression_(true),
       should_emit_table_size_(false) {}
 
 HpackEncoder::~HpackEncoder() {}
@@ -120,21 +120,6 @@
   return true;
 }
 
-bool HpackEncoder::EncodeHeaderSetWithoutCompression(
-    const SpdyHeaderBlock& header_set,
-    string* output) {
-  allow_huffman_compression_ = false;
-  MaybeEmitTableSize();
-  for (const auto& header : header_set) {
-    listener_(header.first, header.second);
-    // Note that cookies are not crumbled in this case.
-    EmitNonIndexedLiteral(header);
-  }
-  allow_huffman_compression_ = true;
-  output_stream_.TakeString(output);
-  return true;
-}
-
 void HpackEncoder::ApplyHeaderTableSizeSetting(size_t size_setting) {
   if (size_setting == header_table_.settings_size_bound()) {
     return;
@@ -153,12 +138,16 @@
   while (iter->HasNext()) {
     const auto header = iter->Next();
     listener_(header.first, header.second);
-    const HpackEntry* entry =
-        header_table_.GetByNameAndValue(header.first, header.second);
-    if (entry != nullptr) {
-      EmitIndex(entry);
-    } else if (should_index_(header.first, header.second)) {
-      EmitIndexedLiteral(header);
+    if (enable_compression_) {
+      const HpackEntry* entry =
+          header_table_.GetByNameAndValue(header.first, header.second);
+      if (entry != nullptr) {
+        EmitIndex(entry);
+      } else if (should_index_(header.first, header.second)) {
+        EmitIndexedLiteral(header);
+      } else {
+        EmitNonIndexedLiteral(header);
+      }
     } else {
       EmitNonIndexedLiteral(header);
     }
@@ -198,8 +187,7 @@
 
 void HpackEncoder::EmitString(StringPiece str) {
   size_t encoded_size =
-      (!allow_huffman_compression_ ? str.size()
-                                   : huffman_table_.EncodedSize(str));
+      enable_compression_ ? huffman_table_.EncodedSize(str) : str.size();
   if (encoded_size < str.size()) {
     output_stream_.AppendPrefix(kStringLiteralHuffmanEncoded);
     output_stream_.AppendUint32(encoded_size);
@@ -286,9 +274,7 @@
 // Iteratively encodes a SpdyHeaderBlock.
 class HpackEncoder::Encoderator : public ProgressiveEncoder {
  public:
-  Encoderator(const SpdyHeaderBlock& header_set,
-              HpackEncoder* encoder,
-              bool use_compression);
+  Encoderator(const SpdyHeaderBlock& header_set, HpackEncoder* encoder);
 
   // Encoderator is neither copyable nor movable.
   Encoderator(const Encoderator&) = delete;
@@ -307,29 +293,27 @@
   Representations pseudo_headers_;
   Representations regular_headers_;
   bool has_next_;
-  bool use_compression_;
 };
 
 HpackEncoder::Encoderator::Encoderator(const SpdyHeaderBlock& header_set,
-                                       HpackEncoder* encoder,
-                                       bool use_compression)
-    : encoder_(encoder), has_next_(true), use_compression_(use_compression) {
+                                       HpackEncoder* encoder)
+    : encoder_(encoder), has_next_(true) {
   // Separate header set into pseudo-headers and regular headers.
+  const bool use_compression = encoder_->enable_compression_;
   bool found_cookie = false;
   for (const auto& header : header_set) {
     if (!found_cookie && header.first == "cookie") {
       // Note that there can only be one "cookie" header, because header_set
       // is a map.
       found_cookie = true;
-      use_compression_ ? CookieToCrumbs(header, &regular_headers_)
-                       : GatherRepresentation(header, &regular_headers_);
+      CookieToCrumbs(header, &regular_headers_);
     } else if (!header.first.empty() &&
                header.first[0] == kPseudoHeaderPrefix) {
-      use_compression_ ? DecomposeRepresentation(header, &pseudo_headers_)
-                       : GatherRepresentation(header, &pseudo_headers_);
+      use_compression ? DecomposeRepresentation(header, &pseudo_headers_)
+                      : GatherRepresentation(header, &pseudo_headers_);
     } else {
-      use_compression_ ? DecomposeRepresentation(header, &regular_headers_)
-                       : GatherRepresentation(header, &regular_headers_);
+      use_compression ? DecomposeRepresentation(header, &regular_headers_)
+                      : GatherRepresentation(header, &regular_headers_);
     }
   }
   header_it_ = base::MakeUnique<RepresentationIterator>(pseudo_headers_,
@@ -341,13 +325,14 @@
 void HpackEncoder::Encoderator::Next(size_t max_encoded_bytes, string* output) {
   SPDY_BUG_IF(!has_next_)
       << "Encoderator::Next called with nothing left to encode.";
+  const bool use_compression = encoder_->enable_compression_;
 
   // Encode up to max_encoded_bytes of headers.
   while (header_it_->HasNext() &&
          encoder_->output_stream_.size() <= max_encoded_bytes) {
     const Representation header = header_it_->Next();
     encoder_->listener_(header.first, header.second);
-    if (use_compression_) {
+    if (use_compression) {
       const HpackEntry* entry = encoder_->header_table_.GetByNameAndValue(
           header.first, header.second);
       if (entry != nullptr) {
@@ -358,9 +343,7 @@
         encoder_->EmitNonIndexedLiteral(header);
       }
     } else {
-      encoder_->allow_huffman_compression_ = false;
       encoder_->EmitNonIndexedLiteral(header);
-      encoder_->allow_huffman_compression_ = true;
     }
   }
 
@@ -369,9 +352,8 @@
 }
 
 std::unique_ptr<HpackEncoder::ProgressiveEncoder> HpackEncoder::EncodeHeaderSet(
-    const SpdyHeaderBlock& header_set,
-    bool use_compression) {
-  return base::MakeUnique<Encoderator>(header_set, this, use_compression);
+    const SpdyHeaderBlock& header_set) {
+  return base::MakeUnique<Encoderator>(header_set, this);
 }
 
 }  // namespace net
diff --git a/net/spdy/hpack/hpack_encoder.h b/net/spdy/hpack/hpack_encoder.h
index b2778af..f2d95e3 100644
--- a/net/spdy/hpack/hpack_encoder.h
+++ b/net/spdy/hpack/hpack_encoder.h
@@ -60,12 +60,6 @@
   // whether or not the encoding was successful.
   bool EncodeHeaderSet(const SpdyHeaderBlock& header_set, std::string* output);
 
-  // Encodes the given header set into the given string. Only non-indexed
-  // literal representations are emitted, bypassing the header table. Huffman
-  // coding is also not used. Returns whether the encoding was successful.
-  bool EncodeHeaderSetWithoutCompression(const SpdyHeaderBlock& header_set,
-                                         std::string* output);
-
   class NET_EXPORT_PRIVATE ProgressiveEncoder {
    public:
     virtual ~ProgressiveEncoder() {}
@@ -81,8 +75,7 @@
   // Returns a ProgressiveEncoder which must be outlived by both the given
   // SpdyHeaderBlock and this object.
   std::unique_ptr<ProgressiveEncoder> EncodeHeaderSet(
-      const SpdyHeaderBlock& header_set,
-      bool use_compression);
+      const SpdyHeaderBlock& header_set);
 
   // Called upon a change to SETTINGS_HEADER_TABLE_SIZE. Specifically, this
   // is to be called after receiving (and sending an acknowledgement for) a
@@ -106,6 +99,8 @@
     header_table_.set_debug_visitor(std::move(visitor));
   }
 
+  void DisableCompression() { enable_compression_ = false; }
+
  private:
   friend class test::HpackEncoderPeer;
 
@@ -149,7 +144,7 @@
   size_t min_table_size_setting_received_;
   HeaderListener listener_;
   IndexingPolicy should_index_;
-  bool allow_huffman_compression_;
+  bool enable_compression_;
   bool should_emit_table_size_;
 
   DISALLOW_COPY_AND_ASSIGN(HpackEncoder);
diff --git a/net/spdy/hpack/hpack_encoder_test.cc b/net/spdy/hpack/hpack_encoder_test.cc
index fd4861c..c1db5b4c 100644
--- a/net/spdy/hpack/hpack_encoder_test.cc
+++ b/net/spdy/hpack/hpack_encoder_test.cc
@@ -9,6 +9,7 @@
 
 #include "base/rand_util.h"
 #include "net/base/arena.h"
+#include "net/spdy/hpack/hpack_huffman_table.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -41,10 +42,11 @@
 
   explicit HpackEncoderPeer(HpackEncoder* encoder) : encoder_(encoder) {}
 
+  bool compression_enabled() const { return encoder_->enable_compression_; }
   HpackHeaderTable* table() { return &encoder_->header_table_; }
   HpackHeaderTablePeer table_peer() { return HpackHeaderTablePeer(table()); }
-  void set_allow_huffman_compression(bool allow) {
-    encoder_->allow_huffman_compression_ = allow;
+  const HpackHuffmanTable& huffman_table() const {
+    return encoder_->huffman_table_;
   }
   void EmitString(StringPiece str) { encoder_->EmitString(str); }
   void TakeString(string* out) { encoder_->output_stream_.TakeString(out); }
@@ -75,23 +77,19 @@
   static bool EncodeHeaderSet(HpackEncoder* encoder,
                               const SpdyHeaderBlock& header_set,
                               string* output,
-                              bool use_compression,
                               bool use_incremental) {
     if (use_incremental) {
-      return EncodeIncremental(encoder, header_set, output, use_compression);
+      return EncodeIncremental(encoder, header_set, output);
     } else {
-      return use_compression ? encoder->EncodeHeaderSet(header_set, output)
-                             : encoder->EncodeHeaderSetWithoutCompression(
-                                   header_set, output);
+      return encoder->EncodeHeaderSet(header_set, output);
     }
   }
 
   static bool EncodeIncremental(HpackEncoder* encoder,
                                 const SpdyHeaderBlock& header_set,
-                                string* output,
-                                bool use_compression) {
+                                string* output) {
     std::unique_ptr<HpackEncoder::ProgressiveEncoder> encoderator =
-        encoder->EncodeHeaderSet(header_set, use_compression);
+        encoder->EncodeHeaderSet(header_set);
     string output_buffer;
     encoderator->Next(base::RandInt(0, 15), &output_buffer);
     while (encoderator->HasNext()) {
@@ -137,9 +135,6 @@
 
     // No further insertions may occur without evictions.
     peer_.table()->SetMaxSize(peer_.table()->size());
-
-    // Disable Huffman coding by default. Most tests don't care about it.
-    peer_.set_allow_huffman_compression(false);
   }
 
   void SaveHeaders(StringPiece name, StringPiece value) {
@@ -157,29 +152,34 @@
   void ExpectIndexedLiteral(const HpackEntry* key_entry, StringPiece value) {
     expected_.AppendPrefix(kLiteralIncrementalIndexOpcode);
     expected_.AppendUint32(IndexOf(key_entry));
-    expected_.AppendPrefix(kStringLiteralIdentityEncoded);
-    expected_.AppendUint32(value.size());
-    expected_.AppendBytes(value);
+    ExpectString(&expected_, value);
   }
   void ExpectIndexedLiteral(StringPiece name, StringPiece value) {
     expected_.AppendPrefix(kLiteralIncrementalIndexOpcode);
     expected_.AppendUint32(0);
-    expected_.AppendPrefix(kStringLiteralIdentityEncoded);
-    expected_.AppendUint32(name.size());
-    expected_.AppendBytes(name);
-    expected_.AppendPrefix(kStringLiteralIdentityEncoded);
-    expected_.AppendUint32(value.size());
-    expected_.AppendBytes(value);
+    ExpectString(&expected_, name);
+    ExpectString(&expected_, value);
   }
   void ExpectNonIndexedLiteral(StringPiece name, StringPiece value) {
     expected_.AppendPrefix(kLiteralNoIndexOpcode);
     expected_.AppendUint32(0);
-    expected_.AppendPrefix(kStringLiteralIdentityEncoded);
-    expected_.AppendUint32(name.size());
-    expected_.AppendBytes(name);
-    expected_.AppendPrefix(kStringLiteralIdentityEncoded);
-    expected_.AppendUint32(value.size());
-    expected_.AppendBytes(value);
+    ExpectString(&expected_, name);
+    ExpectString(&expected_, value);
+  }
+  void ExpectString(HpackOutputStream* stream, StringPiece str) {
+    const HpackHuffmanTable& huffman_table = peer_.huffman_table();
+    size_t encoded_size = peer_.compression_enabled()
+                              ? huffman_table.EncodedSize(str)
+                              : str.size();
+    if (encoded_size < str.size()) {
+      expected_.AppendPrefix(kStringLiteralHuffmanEncoded);
+      expected_.AppendUint32(encoded_size);
+      huffman_table.EncodeString(str, stream);
+    } else {
+      expected_.AppendPrefix(kStringLiteralIdentityEncoded);
+      expected_.AppendUint32(str.size());
+      expected_.AppendBytes(str);
+    }
   }
   void ExpectHeaderTableSizeUpdate(uint32_t size) {
     expected_.AppendPrefix(kHeaderTableSizeUpdateOpcode);
@@ -189,15 +189,7 @@
     string expected_out, actual_out;
     expected_.TakeString(&expected_out);
     EXPECT_TRUE(test::HpackEncoderPeer::EncodeHeaderSet(
-        &encoder_, header_set, &actual_out, true, use_incremental_));
-    EXPECT_EQ(expected_out, actual_out);
-  }
-  void CompareWithExpectedEncodingWithoutCompression(
-      const SpdyHeaderBlock& header_set) {
-    string expected_out, actual_out;
-    expected_.TakeString(&expected_out);
-    EXPECT_TRUE(test::HpackEncoderPeer::EncodeHeaderSet(
-        &encoder_, header_set, &actual_out, false, use_incremental_));
+        &encoder_, header_set, &actual_out, use_incremental_));
     EXPECT_EQ(expected_out, actual_out);
   }
   size_t IndexOf(const HpackEntry* entry) {
@@ -317,8 +309,6 @@
 }
 
 TEST_P(HpackEncoderTest, StringsDynamicallySelectHuffmanCoding) {
-  peer_.set_allow_huffman_compression(true);
-
   // Compactable string. Uses Huffman coding.
   peer_.EmitString("feedbeef");
   expected_.AppendPrefix(kStringLiteralHuffmanEncoded);
@@ -341,12 +331,11 @@
   encoder_.SetHeaderListener([this](StringPiece name, StringPiece value) {
     this->SaveHeaders(name, value);
   });
-
-  // Implementation should internally disable.
-  peer_.set_allow_huffman_compression(true);
+  encoder_.DisableCompression();
 
   ExpectNonIndexedLiteral(":path", "/index.html");
-  ExpectNonIndexedLiteral("cookie", "foo=bar; baz=bing");
+  ExpectNonIndexedLiteral("cookie", "foo=bar");
+  ExpectNonIndexedLiteral("cookie", "baz=bing");
   ExpectNonIndexedLiteral("hello", "goodbye");
 
   SpdyHeaderBlock headers;
@@ -354,12 +343,12 @@
   headers["cookie"] = "foo=bar; baz=bing";
   headers["hello"] = "goodbye";
 
-  CompareWithExpectedEncodingWithoutCompression(headers);
+  CompareWithExpectedEncoding(headers);
 
-  EXPECT_THAT(headers_observed_,
-              ElementsAre(Pair(":path", "/index.html"),
-                          Pair("cookie", "foo=bar; baz=bing"),
-                          Pair("hello", "goodbye")));
+  EXPECT_THAT(
+      headers_observed_,
+      ElementsAre(Pair(":path", "/index.html"), Pair("cookie", "foo=bar"),
+                  Pair("cookie", "baz=bing"), Pair("hello", "goodbye")));
 }
 
 TEST_P(HpackEncoderTest, MultipleEncodingPasses) {
diff --git a/net/spdy/spdy_framer.cc b/net/spdy/spdy_framer.cc
index 5d724f84..9f5140d 100644
--- a/net/spdy/spdy_framer.cc
+++ b/net/spdy/spdy_framer.cc
@@ -1783,8 +1783,8 @@
       debug_total_size_(0),
       is_first_frame_(true),
       has_next_frame_(true) {
-  encoder_ = framer_->GetHpackEncoder()->EncodeHeaderSet(
-      headers_ir_->header_block(), framer_->compression_enabled());
+  encoder_ =
+      framer_->GetHpackEncoder()->EncodeHeaderSet(headers_ir_->header_block());
 }
 
 SpdyFramer::SpdyHeaderFrameIterator::~SpdyHeaderFrameIterator() {}
@@ -2006,12 +2006,7 @@
   }
 
   string hpack_encoding;
-  if (compression_enabled()) {
-    GetHpackEncoder()->EncodeHeaderSet(headers.header_block(), &hpack_encoding);
-  } else {
-    GetHpackEncoder()->EncodeHeaderSetWithoutCompression(headers.header_block(),
-                                                         &hpack_encoding);
-  }
+  GetHpackEncoder()->EncodeHeaderSet(headers.header_block(), &hpack_encoding);
   size += hpack_encoding.size();
   if (size > kMaxControlFrameSize) {
     size += GetNumberRequiredContinuationFrames(size) *
@@ -2083,13 +2078,8 @@
   }
 
   string hpack_encoding;
-  if (compression_enabled()) {
-    GetHpackEncoder()->EncodeHeaderSet(push_promise.header_block(),
-                                       &hpack_encoding);
-  } else {
-    GetHpackEncoder()->EncodeHeaderSetWithoutCompression(
-        push_promise.header_block(), &hpack_encoding);
-  }
+  GetHpackEncoder()->EncodeHeaderSet(push_promise.header_block(),
+                                     &hpack_encoding);
   size += hpack_encoding.size();
   if (size > kMaxControlFrameSize) {
     size += GetNumberRequiredContinuationFrames(size) *
@@ -2367,6 +2357,9 @@
 HpackEncoder* SpdyFramer::GetHpackEncoder() {
   if (hpack_encoder_.get() == nullptr) {
     hpack_encoder_.reset(new HpackEncoder(ObtainHpackHuffmanTable()));
+    if (!compression_enabled()) {
+      hpack_encoder_->DisableCompression();
+    }
   }
   return hpack_encoder_.get();
 }
diff --git a/net/spdy/spdy_framer_test.cc b/net/spdy/spdy_framer_test.cc
index 470707d..4b0333b 100644
--- a/net/spdy/spdy_framer_test.cc
+++ b/net/spdy/spdy_framer_test.cc
@@ -1175,7 +1175,8 @@
   header_set["name"] = value;
   string buffer;
   HpackEncoder encoder(ObtainHpackHuffmanTable());
-  encoder.EncodeHeaderSetWithoutCompression(header_set, &buffer);
+  encoder.DisableCompression();
+  encoder.EncodeHeaderSet(header_set, &buffer);
   frame.WriteBytes(&buffer[0], buffer.size());
   // write the length
   frame.RewriteLength(framer);
@@ -2343,7 +2344,8 @@
   header_block["foo"] = "bar";
   auto buffer = base::MakeUnique<string>();
   HpackEncoder encoder(ObtainHpackHuffmanTable());
-  encoder.EncodeHeaderSetWithoutCompression(header_block, buffer.get());
+  encoder.DisableCompression();
+  encoder.EncodeHeaderSet(header_block, buffer.get());
 
   SpdyContinuationIR continuation(42);
   continuation.take_encoding(std::move(buffer));
diff --git a/net/spdy/spdy_protocol.h b/net/spdy/spdy_protocol.h
index f71d6b2c..bbd959a 100644
--- a/net/spdy/spdy_protocol.h
+++ b/net/spdy/spdy_protocol.h
@@ -38,6 +38,9 @@
 // flow control).
 const SpdyStreamId kSessionFlowControlStreamId = 0;
 
+// Max stream id.
+const SpdyStreamId kMaxStreamId = 0x7fffffff;
+
 // The maximum possible frame payload size allowed by the spec.
 const uint32_t kSpdyMaxFrameSizeLimit = (1 << 24) - 1;
 
diff --git a/net/ssl/ssl_client_session_cache.cc b/net/ssl/ssl_client_session_cache.cc
index 5fd3c48..19b9d55 100644
--- a/net/ssl/ssl_client_session_cache.cc
+++ b/net/ssl/ssl_client_session_cache.cc
@@ -98,31 +98,30 @@
     return;
   cache_dump = pmd->CreateAllocatorDump(absolute_name);
   base::AutoLock lock(lock_);
+  int total_serialized_cert_size = 0;
+  int total_cert_count = 0;
   for (const auto& pair : cache_) {
     auto entry = pair.second.get();
     auto cert_chain = entry->x509_chain;
     size_t cert_count = sk_X509_num(cert_chain);
-    base::trace_event::MemoryAllocatorDump* entry_dump =
-        pmd->CreateAllocatorDump(
-            base::StringPrintf("%s/entry_%p", absolute_name.c_str(), entry));
-    int cert_size = 0;
+    total_cert_count += cert_count;
     for (size_t i = 0; i < cert_count; ++i) {
       X509* cert = sk_X509_value(cert_chain, i);
-      cert_size += i2d_X509(cert, nullptr);
+      total_serialized_cert_size += i2d_X509(cert, nullptr);
     }
-    // This measures the lower bound of the serialized certificate. It doesn't
-    // measure the actual memory used, which is 4x this amount (see
-    // crbug.com/671420 for more details).
-    entry_dump->AddScalar("cert_size",
-                          base::trace_event::MemoryAllocatorDump::kUnitsBytes,
-                          cert_size);
-    entry_dump->AddScalar("serialized_cert_count",
-                          base::trace_event::MemoryAllocatorDump::kUnitsObjects,
-                          cert_count);
-    entry_dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize,
-                          base::trace_event::MemoryAllocatorDump::kUnitsBytes,
-                          cert_size);
   }
+  // This measures the lower bound of the serialized certificate. It doesn't
+  // measure the actual memory used, which is 4x this amount (see
+  // crbug.com/671420 for more details).
+  cache_dump->AddScalar("serialized_cert_size",
+                        base::trace_event::MemoryAllocatorDump::kUnitsBytes,
+                        total_serialized_cert_size);
+  cache_dump->AddScalar("cert_count",
+                        base::trace_event::MemoryAllocatorDump::kUnitsObjects,
+                        total_cert_count);
+  cache_dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize,
+                        base::trace_event::MemoryAllocatorDump::kUnitsBytes,
+                        total_serialized_cert_size);
 }
 
 void SSLClientSessionCache::FlushExpiredSessions() {
diff --git a/net/ssl/ssl_client_session_cache_unittest.cc b/net/ssl/ssl_client_session_cache_unittest.cc
index 2f14ae86..c9cf6f28c 100644
--- a/net/ssl/ssl_client_session_cache_unittest.cc
+++ b/net/ssl/ssl_client_session_cache_unittest.cc
@@ -11,6 +11,7 @@
 #include "base/time/time.h"
 #include "base/trace_event/memory_allocator_dump.h"
 #include "base/trace_event/process_memory_dump.h"
+#include "base/trace_event/trace_event_argument.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/boringssl/src/include/openssl/ssl.h"
 
@@ -325,16 +326,16 @@
       new base::trace_event::ProcessMemoryDump(nullptr, dump_args));
   cache.DumpMemoryStats(process_memory_dump.get());
 
-  const base::trace_event::ProcessMemoryDump::AllocatorDumpsMap&
-      allocator_dumps = process_memory_dump->allocator_dumps();
-
-  size_t num_entry_dump = 0;
-  for (const auto& pair : allocator_dumps) {
-    const std::string& dump_name = pair.first;
-    if (dump_name.find("net/ssl_session_cache/entry") != std::string::npos)
-      num_entry_dump++;
-  }
-  ASSERT_EQ(3u, num_entry_dump);
+  const base::trace_event::MemoryAllocatorDump* dump =
+      process_memory_dump->GetAllocatorDump("net/ssl_session_cache");
+  ASSERT_NE(nullptr, dump);
+  std::unique_ptr<base::Value> raw_attrs =
+      dump->attributes_for_testing()->ToBaseValue();
+  base::DictionaryValue* attrs;
+  ASSERT_TRUE(raw_attrs->GetAsDictionary(&attrs));
+  ASSERT_TRUE(attrs->HasKey("cert_count"));
+  ASSERT_TRUE(attrs->HasKey("serialized_cert_size"));
+  ASSERT_TRUE(attrs->HasKey(base::trace_event::MemoryAllocatorDump::kNameSize));
 }
 
 }  // namespace net
diff --git a/net/ssl/ssl_platform_key_android_unittest.cc b/net/ssl/ssl_platform_key_android_unittest.cc
index 118de12..3fb6800 100644
--- a/net/ssl/ssl_platform_key_android_unittest.cc
+++ b/net/ssl/ssl_platform_key_android_unittest.cc
@@ -35,14 +35,13 @@
 
 typedef base::android::ScopedJavaLocalRef<jobject> ScopedJava;
 
-// Resize a string to |size| bytes of data, then return its data buffer
-// address cast as an 'unsigned char*', as expected by OpenSSL functions.
+// Resize a string to |size| bytes of data, then return its data buffer address
+// cast as an 'uint8_t*', as expected by OpenSSL functions.
 // |str| the target string.
 // |size| the number of bytes to write into the string.
-// Return the string's new buffer in memory, as an 'unsigned char*'
-// pointer.
-unsigned char* OpenSSLWriteInto(std::string* str, size_t size) {
-  return reinterpret_cast<unsigned char*>(base::WriteInto(str, size + 1));
+// Return the string's new buffer in memory, as an 'uint8_t*' pointer.
+uint8_t* OpenSSLWriteInto(std::string* str, size_t size) {
+  return reinterpret_cast<uint8_t*>(base::WriteInto(str, size + 1));
 }
 
 bool ReadTestFile(const char* filename, std::string* pkcs8) {
@@ -51,45 +50,12 @@
   return base::ReadFileToString(file_path, pkcs8);
 }
 
-// Load a given private key file into an EVP_PKEY.
-// |filename| is the key file path.
-// Returns a new EVP_PKEY on success, NULL on failure.
-bssl::UniquePtr<EVP_PKEY> ImportPrivateKeyFile(const char* filename) {
-  std::string pkcs8;
-  if (!ReadTestFile(filename, &pkcs8))
-    return nullptr;
-
+// Parses a PKCS#8 key into an OpenSSL private key object.
+bssl::UniquePtr<EVP_PKEY> ImportPrivateKeyOpenSSL(const std::string& pkcs8) {
   crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
   CBS cbs;
   CBS_init(&cbs, reinterpret_cast<const uint8_t*>(pkcs8.data()), pkcs8.size());
-  bssl::UniquePtr<EVP_PKEY> pkey(EVP_parse_private_key(&cbs));
-  if (!pkey) {
-    LOG(ERROR) << "Could not load private key file: " << filename;
-    return nullptr;
-  }
-
-  return pkey;
-}
-
-// Imports the public key from the specified test certificate.
-bssl::UniquePtr<EVP_PKEY> ImportPublicKeyFromCertificateFile(
-    const char* filename) {
-  crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
-
-  scoped_refptr<X509Certificate> cert =
-      ImportCertFromFile(GetTestCertsDirectory(), filename);
-  if (!cert) {
-    LOG(ERROR) << "Could not open certificate file: " << filename;
-    return nullptr;
-  }
-
-  bssl::UniquePtr<EVP_PKEY> pkey(X509_get_pubkey(cert->os_cert_handle()));
-  if (!pkey) {
-    LOG(ERROR) << "Could not load public key from certificate: " << filename;
-    return nullptr;
-  }
-
-  return pkey;
+  return bssl::UniquePtr<EVP_PKEY>(EVP_parse_private_key(&cbs));
 }
 
 // Retrieve a JNI local ref from encoded PKCS#8 data.
@@ -107,140 +73,42 @@
   return key;
 }
 
-const char kTestRsaKeyFile[] = "client_1.pk8";
-const char kTestRsaCertificateFile[] = "client_1.pem";
-
-// Retrieve a JNI local ref for our test RSA key.
-ScopedJava GetRSATestKeyJava() {
-  std::string key;
-  if (!ReadTestFile(kTestRsaKeyFile, &key))
-    return ScopedJava();
-  return GetPKCS8PrivateKeyJava(android::PRIVATE_KEY_TYPE_RSA, key);
-}
-
-const char kTestEcdsaKeyFile[] = "client_4.pk8";
-const char kTestEcdsaCertificateFile[] = "client_4.pem";
-
-// Retrieve a JNI local ref for our test ECDSA key.
-ScopedJava GetECDSATestKeyJava() {
-  std::string key;
-  if (!ReadTestFile(kTestEcdsaKeyFile, &key))
-    return ScopedJava();
-  return GetPKCS8PrivateKeyJava(android::PRIVATE_KEY_TYPE_ECDSA, key);
-}
-
-// Call this function to verify that one message signed with our
-// test ECDSA private key is correct. Since ECDSA signing introduces
-// random elements in the signature, it is not possible to compare
-// signature bits directly. However, one can use the public key
-// to do the check.
-bool VerifyTestECDSASignature(const base::StringPiece& message,
-                              const base::StringPiece& signature) {
+bool VerifyWithOpenSSL(const EVP_MD* md,
+                       const base::StringPiece& digest,
+                       EVP_PKEY* key,
+                       const base::StringPiece& signature) {
   crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
 
-  bssl::UniquePtr<EVP_PKEY> pkey =
-      ImportPublicKeyFromCertificateFile(kTestEcdsaCertificateFile);
-  if (!pkey)
-    return false;
-
-  EC_KEY* pub_key = EVP_PKEY_get0_EC_KEY(pkey.get());
-  if (!pub_key) {
-    LOG(ERROR) << "Could not get ECDSA public key";
+  bssl::UniquePtr<EVP_PKEY_CTX> ctx(EVP_PKEY_CTX_new(key, nullptr));
+  if (!ctx || !EVP_PKEY_verify_init(ctx.get()) ||
+      !EVP_PKEY_CTX_set_signature_md(ctx.get(), md) ||
+      !EVP_PKEY_verify(
+          ctx.get(), reinterpret_cast<const uint8_t*>(signature.data()),
+          signature.size(), reinterpret_cast<const uint8_t*>(digest.data()),
+          digest.size())) {
     return false;
   }
 
-  const unsigned char* digest =
-      reinterpret_cast<const unsigned char*>(message.data());
-  int digest_len = static_cast<int>(message.size());
-  const unsigned char* sigbuf =
-      reinterpret_cast<const unsigned char*>(signature.data());
-  int siglen = static_cast<int>(signature.size());
-
-  if (!ECDSA_verify(0, digest, digest_len, sigbuf, siglen, pub_key)) {
-    LOG(ERROR) << "ECDSA_verify() failed";
-    return false;
-  }
   return true;
 }
 
-// Sign a message with OpenSSL, return the result as a string.
-// |message| is the message to be signed.
-// |openssl_key| is an OpenSSL EVP_PKEY to use.
-// |result| receives the result.
-// Returns true on success, false otherwise.
-bool SignWithOpenSSL(int hash_nid,
-                     const base::StringPiece& message,
-                     EVP_PKEY* openssl_key,
+bool SignWithOpenSSL(const EVP_MD* md,
+                     const base::StringPiece& digest,
+                     EVP_PKEY* key,
                      std::string* result) {
   crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
 
-  RSA* rsa = EVP_PKEY_get0_RSA(openssl_key);
-  if (!rsa) {
-    LOG(ERROR) << "Could not get RSA from EVP_PKEY";
+  size_t sig_len;
+  bssl::UniquePtr<EVP_PKEY_CTX> ctx(EVP_PKEY_CTX_new(key, nullptr));
+  if (!ctx || !EVP_PKEY_sign_init(ctx.get()) ||
+      !EVP_PKEY_CTX_set_signature_md(ctx.get(), md) ||
+      !EVP_PKEY_sign(ctx.get(), OpenSSLWriteInto(result, EVP_PKEY_size(key)),
+                     &sig_len, reinterpret_cast<const uint8_t*>(digest.data()),
+                     digest.size())) {
     return false;
   }
 
-  const unsigned char* digest =
-      reinterpret_cast<const unsigned char*>(message.data());
-  unsigned int digest_len = static_cast<unsigned int>(message.size());
-
-  // With RSA, the signature will always be RSA_size() bytes.
-  size_t max_signature_size = static_cast<size_t>(RSA_size(rsa));
-  std::string signature;
-  unsigned char* p = OpenSSLWriteInto(&signature, max_signature_size);
-  unsigned int p_len = 0;
-  if (!RSA_sign(hash_nid, digest, digest_len, p, &p_len, rsa)) {
-    LOG(ERROR) << "RSA_sign() failed";
-    return false;
-  }
-
-  size_t signature_size = static_cast<size_t>(p_len);
-  if (signature_size == 0) {
-    LOG(ERROR) << "Signature is empty!";
-    return false;
-  }
-  if (signature_size > max_signature_size) {
-    LOG(ERROR) << "Signature size mismatch, actual " << signature_size
-               << ", expected <= " << max_signature_size;
-    return false;
-  }
-  signature.resize(signature_size);
-  result->swap(signature);
-  return true;
-}
-
-// Check that a generated signature for a given message matches
-// OpenSSL output byte-by-byte.
-// |message| is the input message.
-// |signature| is the generated signature for the message.
-// |openssl_key| is a raw EVP_PKEY for the same private key than the
-// one which was used to generate the signature.
-// Returns true on success, false otherwise.
-bool CompareSignatureWithOpenSSL(int hash_nid,
-                                 const base::StringPiece& message,
-                                 const base::StringPiece& signature,
-                                 EVP_PKEY* openssl_key) {
-  std::string openssl_signature;
-  if (!SignWithOpenSSL(hash_nid, message, openssl_key, &openssl_signature))
-    return false;
-
-  if (signature.size() != openssl_signature.size()) {
-    LOG(ERROR) << "Signature size mismatch, actual " << signature.size()
-               << ", expected " << openssl_signature.size();
-    return false;
-  }
-  for (size_t n = 0; n < signature.size(); ++n) {
-    if (openssl_signature[n] != signature[n]) {
-      LOG(ERROR) << "Signature byte mismatch at index " << n << "actual "
-                 << signature[n] << ", expected " << openssl_signature[n];
-      LOG(ERROR) << "Actual signature  : "
-                 << base::HexEncode(signature.data(), signature.size());
-      LOG(ERROR) << "Expected signature: "
-                 << base::HexEncode(openssl_signature.data(),
-                                    openssl_signature.size());
-      return false;
-    }
-  }
+  result->resize(sig_len);
   return true;
 }
 
@@ -282,81 +150,84 @@
     {"SHA-512", NID_sha512, SSLPrivateKey::Hash::SHA512},
 };
 
+struct TestKey {
+  const char* cert_file;
+  const char* key_file;
+  android::PrivateKeyType android_key_type;
+  SSLPrivateKey::Type key_type;
+};
+
+static const TestKey kTestKeys[] = {
+    {"client_1.pem", "client_1.pk8", android::PRIVATE_KEY_TYPE_RSA,
+     SSLPrivateKey::Type::RSA},
+    {"client_4.pem", "client_4.pk8", android::PRIVATE_KEY_TYPE_ECDSA,
+     SSLPrivateKey::Type::ECDSA_P256},
+    {"client_5.pem", "client_5.pk8", android::PRIVATE_KEY_TYPE_ECDSA,
+     SSLPrivateKey::Type::ECDSA_P384},
+    {"client_6.pem", "client_6.pk8", android::PRIVATE_KEY_TYPE_ECDSA,
+     SSLPrivateKey::Type::ECDSA_P521},
+};
+
 }  // namespace
 
-TEST(SSLPlatformKeyAndroid, RSA) {
+class SSLPlatformKeyAndroidTest : public testing::TestWithParam<TestKey> {};
+
+TEST_P(SSLPlatformKeyAndroidTest, SignHashes) {
   crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
+  const TestKey& test_key = GetParam();
 
   scoped_refptr<X509Certificate> cert =
-      ImportCertFromFile(GetTestCertsDirectory(), kTestRsaCertificateFile);
+      ImportCertFromFile(GetTestCertsDirectory(), test_key.cert_file);
   ASSERT_TRUE(cert);
-  ScopedJava rsa_key = GetRSATestKeyJava();
-  ASSERT_FALSE(rsa_key.is_null());
+
+  std::string key_bytes;
+  ASSERT_TRUE(ReadTestFile(test_key.key_file, &key_bytes));
+  ScopedJava java_key =
+      GetPKCS8PrivateKeyJava(test_key.android_key_type, key_bytes);
+  ASSERT_FALSE(java_key.is_null());
 
   scoped_refptr<SSLPrivateKey> wrapper_key =
-      WrapJavaPrivateKey(cert.get(), rsa_key);
+      WrapJavaPrivateKey(cert.get(), java_key);
   ASSERT_TRUE(wrapper_key);
 
-  bssl::UniquePtr<EVP_PKEY> openssl_key = ImportPrivateKeyFile(kTestRsaKeyFile);
+  bssl::UniquePtr<EVP_PKEY> openssl_key = ImportPrivateKeyOpenSSL(key_bytes);
   ASSERT_TRUE(openssl_key);
 
   // Check that the wrapper key returns the correct length and type.
-  EXPECT_EQ(SSLPrivateKey::Type::RSA, wrapper_key->GetType());
+  EXPECT_EQ(test_key.key_type, wrapper_key->GetType());
   EXPECT_EQ(static_cast<size_t>(EVP_PKEY_size(openssl_key.get())),
             wrapper_key->GetMaxSignatureLengthInBytes());
 
   // Test signing against each hash.
   for (const auto& hash : kHashes) {
-    SCOPED_TRACE(hash.name);
-
-    const EVP_MD* md = EVP_get_digestbynid(hash.nid);
-    ASSERT_TRUE(md);
-    std::string digest(EVP_MD_size(md), 'a');
-
-    std::string signature;
-    DoKeySigningWithWrapper(wrapper_key.get(), hash.hash, digest, &signature);
-    ASSERT_TRUE(CompareSignatureWithOpenSSL(hash.nid, digest, signature,
-                                            openssl_key.get()));
-  }
-}
-
-TEST(SSLPlatformKeyAndroid, ECDSA) {
-  crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
-
-  scoped_refptr<X509Certificate> cert =
-      ImportCertFromFile(GetTestCertsDirectory(), kTestEcdsaCertificateFile);
-  ASSERT_TRUE(cert);
-  ScopedJava ecdsa_key = GetECDSATestKeyJava();
-  ASSERT_FALSE(ecdsa_key.is_null());
-
-  scoped_refptr<SSLPrivateKey> wrapper_key =
-      WrapJavaPrivateKey(cert.get(), ecdsa_key);
-  ASSERT_TRUE(wrapper_key);
-
-  bssl::UniquePtr<EVP_PKEY> openssl_key =
-      ImportPrivateKeyFile(kTestEcdsaKeyFile);
-  ASSERT_TRUE(openssl_key);
-
-  // Check that the wrapper key returns the correct length and type.
-  EXPECT_EQ(SSLPrivateKey::Type::ECDSA_P256, wrapper_key->GetType());
-  EXPECT_EQ(static_cast<size_t>(EVP_PKEY_size(openssl_key.get())),
-            wrapper_key->GetMaxSignatureLengthInBytes());
-
-  // Test signing against each hash.
-  for (const auto& hash : kHashes) {
-    // ECDSA does not sign MD5-SHA1.
-    if (hash.nid == NID_md5_sha1)
+    // Only RSA signs MD5-SHA1.
+    if (test_key.key_type != SSLPrivateKey::Type::RSA &&
+        hash.nid == NID_md5_sha1) {
       continue;
+    }
 
     SCOPED_TRACE(hash.name);
+
     const EVP_MD* md = EVP_get_digestbynid(hash.nid);
     ASSERT_TRUE(md);
     std::string digest(EVP_MD_size(md), 'a');
 
     std::string signature;
     DoKeySigningWithWrapper(wrapper_key.get(), hash.hash, digest, &signature);
-    ASSERT_TRUE(VerifyTestECDSASignature(digest, signature));
+    EXPECT_TRUE(VerifyWithOpenSSL(md, digest, openssl_key.get(), signature));
+
+    // RSA signing is deterministic, so further check the signature matches.
+    if (test_key.key_type == SSLPrivateKey::Type::RSA) {
+      std::string openssl_signature;
+      ASSERT_TRUE(
+          SignWithOpenSSL(md, digest, openssl_key.get(), &openssl_signature));
+      EXPECT_EQ(openssl_signature, signature);
+    }
   }
 }
 
+INSTANTIATE_TEST_CASE_P(,
+                        SSLPlatformKeyAndroidTest,
+                        testing::ValuesIn(kTestKeys));
+
 }  // namespace net
diff --git a/net/ssl/ssl_platform_key_util.cc b/net/ssl/ssl_platform_key_util.cc
index 6c76220..39af9eb 100644
--- a/net/ssl/ssl_platform_key_util.cc
+++ b/net/ssl/ssl_platform_key_util.cc
@@ -88,7 +88,7 @@
           *out_type = SSLPrivateKey::Type::ECDSA_P384;
           break;
         case NID_secp521r1:
-          *out_type = SSLPrivateKey::Type::ECDSA_P384;
+          *out_type = SSLPrivateKey::Type::ECDSA_P521;
           break;
         default:
           LOG(ERROR) << "Unsupported curve type " << curve;
diff --git a/net/ssl/ssl_platform_key_util_unittest.cc b/net/ssl/ssl_platform_key_util_unittest.cc
index 1e7b9d3..8a00034 100644
--- a/net/ssl/ssl_platform_key_util_unittest.cc
+++ b/net/ssl/ssl_platform_key_util_unittest.cc
@@ -31,6 +31,10 @@
   return GetClientCertInfo(cert.get(), out_type, out_max_length);
 }
 
+size_t BitsToBytes(size_t bits) {
+  return (bits + 7) / 8;
+}
+
 }  // namespace
 
 TEST(SSLPlatformKeyUtil, GetClientCertInfo) {
@@ -43,7 +47,15 @@
 
   ASSERT_TRUE(GetClientCertInfoFromFile("client_4.pem", &type, &max_length));
   EXPECT_EQ(SSLPrivateKey::Type::ECDSA_P256, type);
-  EXPECT_EQ(ECDSA_SIG_max_len(256u / 8u), max_length);
+  EXPECT_EQ(ECDSA_SIG_max_len(BitsToBytes(256)), max_length);
+
+  ASSERT_TRUE(GetClientCertInfoFromFile("client_5.pem", &type, &max_length));
+  EXPECT_EQ(SSLPrivateKey::Type::ECDSA_P384, type);
+  EXPECT_EQ(ECDSA_SIG_max_len(BitsToBytes(384)), max_length);
+
+  ASSERT_TRUE(GetClientCertInfoFromFile("client_6.pem", &type, &max_length));
+  EXPECT_EQ(SSLPrivateKey::Type::ECDSA_P521, type);
+  EXPECT_EQ(ECDSA_SIG_max_len(BitsToBytes(521)), max_length);
 }
 
 }  // namespace net
diff --git a/rlz/features/BUILD.gn b/rlz/features/BUILD.gn
new file mode 100644
index 0000000..58328e7
--- /dev/null
+++ b/rlz/features/BUILD.gn
@@ -0,0 +1,11 @@
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//build/buildflag_header.gni")
+import("//rlz/features/features.gni")
+
+buildflag_header("features") {
+  header = "features.h"
+  flags = [ "ENABLE_RLZ=$enable_rlz" ]
+}
diff --git a/rlz/features/features.gni b/rlz/features/features.gni
new file mode 100644
index 0000000..d90c6e1
--- /dev/null
+++ b/rlz/features/features.gni
@@ -0,0 +1,11 @@
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//build/config/chrome_build.gni")
+
+# Whether we are using the rlz library or not.  Platforms like Android send
+# rlz codes for searches but do not use the library.
+enable_rlz_support = is_win || is_mac || is_ios || is_chromeos
+
+enable_rlz = is_chrome_branded && enable_rlz_support
diff --git a/services/service_manager/runner/common/switches.cc b/services/service_manager/runner/common/switches.cc
index 1f4a9a9..25c1766 100644
--- a/services/service_manager/runner/common/switches.cc
+++ b/services/service_manager/runner/common/switches.cc
@@ -18,6 +18,9 @@
 // primordial message pipe to the parent.
 const char kPrimordialPipeToken[] = "primordial-pipe-token";
 
+// The name of the service the process is starting for.
+const char kProcessServiceName[] = "process-service-name";
+
 // Specifies a JSON file from which to read a set of service metadata overrides.
 // This can be used with the standalone mojo_runner to override executable and
 // package resolution behavior.
diff --git a/services/service_manager/runner/common/switches.h b/services/service_manager/runner/common/switches.h
index d36cfda..a14b36a8 100644
--- a/services/service_manager/runner/common/switches.h
+++ b/services/service_manager/runner/common/switches.h
@@ -12,6 +12,7 @@
 extern const char kChildProcess[];
 extern const char kEnableSandbox[];
 extern const char kPrimordialPipeToken[];
+extern const char kProcessServiceName[];
 extern const char kServiceOverrides[];
 
 }  // namespace switches
diff --git a/services/service_manager/runner/host/child_process_host.cc b/services/service_manager/runner/host/child_process_host.cc
index 5d77b7b..faf2ba58 100644
--- a/services/service_manager/runner/host/child_process_host.cc
+++ b/services/service_manager/runner/host/child_process_host.cc
@@ -81,8 +81,9 @@
 
   child_command_line->AppendArguments(parent_command_line, false);
 
+  child_command_line->AppendSwitchASCII(::switches::kProcessServiceName,
+                                        target.name());
 #ifndef NDEBUG
-  child_command_line->AppendSwitchASCII("n", target.name());
   child_command_line->AppendSwitchASCII("u", target.user_id());
 #endif
 
diff --git a/skia/config/SkUserConfig.h b/skia/config/SkUserConfig.h
index 1f13d6c..f25d37ec 100644
--- a/skia/config/SkUserConfig.h
+++ b/skia/config/SkUserConfig.h
@@ -228,6 +228,10 @@
 #   define SK_DISABLE_COLOR_XFORM_PIPELINE
 #endif
 
+#ifndef    SK_SUPPORT_EXOTIC_CLIPOPS
+#   define SK_SUPPORT_EXOTIC_CLIPOPS
+#endif
+
 #ifndef    SK_SUPPORT_LEGACY_IMAGE_ENCODER_CLASS
 #   define SK_SUPPORT_LEGACY_IMAGE_ENCODER_CLASS
 #endif
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json
index 5e303fe..cfcafa1 100644
--- a/testing/buildbot/chromium.android.json
+++ b/testing/buildbot/chromium.android.json
@@ -17,7 +17,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -49,7 +49,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -80,7 +80,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -114,7 +114,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -146,7 +146,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -177,7 +177,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -209,7 +209,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -240,7 +240,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -271,7 +271,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -305,7 +305,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -337,7 +337,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -368,7 +368,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -402,7 +402,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -434,7 +434,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -465,7 +465,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -496,7 +496,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -527,7 +527,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -558,7 +558,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -589,7 +589,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -621,7 +621,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -652,7 +652,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -683,7 +683,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -714,7 +714,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -745,7 +745,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -777,7 +777,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -809,7 +809,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -841,7 +841,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -873,7 +873,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -908,7 +908,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -940,7 +940,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -971,7 +971,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1002,7 +1002,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1033,7 +1033,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1064,7 +1064,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1095,7 +1095,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1126,7 +1126,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1157,7 +1157,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1333,7 +1333,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1366,7 +1366,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1399,7 +1399,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1435,7 +1435,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1468,7 +1468,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1501,7 +1501,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1534,7 +1534,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1567,7 +1567,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1600,7 +1600,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1633,7 +1633,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1666,7 +1666,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1699,7 +1699,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1732,7 +1732,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1765,7 +1765,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1798,7 +1798,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1831,7 +1831,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1864,7 +1864,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1897,7 +1897,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1930,7 +1930,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1963,7 +1963,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1999,7 +1999,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -2032,7 +2032,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -2065,7 +2065,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -2098,7 +2098,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -2131,7 +2131,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -2164,7 +2164,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -2197,7 +2197,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -2230,7 +2230,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -2266,7 +2266,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -2302,7 +2302,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -2338,7 +2338,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -2374,7 +2374,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -2410,7 +2410,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -2563,7 +2563,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -2597,7 +2597,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -2628,7 +2628,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -2662,7 +2662,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -2693,7 +2693,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -2724,7 +2724,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -2755,7 +2755,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -2789,7 +2789,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -2820,7 +2820,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -2851,7 +2851,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -2885,7 +2885,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -2919,7 +2919,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -2950,7 +2950,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -2981,7 +2981,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -3012,7 +3012,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -3046,7 +3046,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -3077,7 +3077,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -3108,7 +3108,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -3139,7 +3139,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -3170,7 +3170,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -3201,7 +3201,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -3232,7 +3232,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -3263,7 +3263,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -3294,7 +3294,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -3325,7 +3325,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -3356,7 +3356,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -3387,7 +3387,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -3421,7 +3421,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -3452,7 +3452,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -3483,7 +3483,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -3514,7 +3514,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -3545,7 +3545,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -3576,7 +3576,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -3607,7 +3607,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -3638,7 +3638,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index bce8672..2d3b5c1 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -1586,7 +1586,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1618,7 +1618,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json
index 1087293..bfd3e45 100644
--- a/testing/buildbot/chromium.gpu.fyi.json
+++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -11,7 +11,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -42,7 +42,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -73,7 +73,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -364,7 +364,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -395,7 +395,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -426,7 +426,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -713,7 +713,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -744,7 +744,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -775,7 +775,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -806,7 +806,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1093,7 +1093,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1124,7 +1124,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1155,7 +1155,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1442,7 +1442,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1473,7 +1473,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1504,7 +1504,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -13553,6 +13553,25 @@
       },
       {
         "args": [
+          "--test-launcher-batch-limit=400",
+          "--deqp-egl-display-type=angle-d3d11"
+        ],
+        "name": "angle_deqp_gles3_d3d11_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "1002:6613",
+              "os": "Windows-2008ServerR2-SP1"
+            }
+          ],
+          "shards": 12
+        },
+        "test": "angle_deqp_gles3_tests",
+        "use_xvfb": false
+      },
+      {
+        "args": [
           "--use-gpu-in-tests",
           "--test-launcher-retry-limit=0"
         ],
diff --git a/testing/buildbot/chromium.linux.json b/testing/buildbot/chromium.linux.json
index e02833d..32ddf79 100644
--- a/testing/buildbot/chromium.linux.json
+++ b/testing/buildbot/chromium.linux.json
@@ -33,7 +33,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -65,7 +65,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -96,7 +96,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -130,7 +130,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -162,7 +162,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -193,7 +193,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -225,7 +225,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -256,7 +256,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -287,7 +287,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -321,7 +321,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -356,7 +356,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -388,7 +388,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -419,7 +419,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -450,7 +450,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -485,7 +485,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -517,7 +517,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -548,7 +548,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -579,7 +579,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -610,7 +610,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -641,7 +641,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -673,7 +673,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -704,7 +704,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -735,7 +735,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -766,7 +766,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -797,7 +797,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -829,7 +829,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -861,7 +861,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -893,7 +893,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -925,7 +925,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -960,7 +960,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -992,7 +992,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1023,7 +1023,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1054,7 +1054,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1085,7 +1085,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1116,7 +1116,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1147,7 +1147,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1178,7 +1178,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1209,7 +1209,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1308,7 +1308,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1340,7 +1340,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1371,7 +1371,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1405,7 +1405,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1437,7 +1437,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1468,7 +1468,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1500,7 +1500,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1531,7 +1531,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1562,7 +1562,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1596,7 +1596,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1631,7 +1631,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1663,7 +1663,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1694,7 +1694,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1725,7 +1725,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1760,7 +1760,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1792,7 +1792,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1823,7 +1823,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1854,7 +1854,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1885,7 +1885,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1916,7 +1916,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1948,7 +1948,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -1979,7 +1979,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -2010,7 +2010,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -2041,7 +2041,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -2072,7 +2072,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -2104,7 +2104,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -2136,7 +2136,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -2168,7 +2168,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -2200,7 +2200,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -2235,7 +2235,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -2267,7 +2267,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -2298,7 +2298,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -2329,7 +2329,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -2360,7 +2360,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -2391,7 +2391,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -2422,7 +2422,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -2453,7 +2453,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
@@ -2484,7 +2484,7 @@
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
               "location": "bin",
-              "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a"
+              "revision": "git_revision:25755a2c316937ee44a6432163dc5e2f9c85cf58"
             }
           ],
           "dimension_sets": [
diff --git a/testing/buildbot/chromium.perf.fyi.json b/testing/buildbot/chromium.perf.fyi.json
index 4a8ce94..0764442 100644
--- a/testing/buildbot/chromium.perf.fyi.json
+++ b/testing/buildbot/chromium.perf.fyi.json
@@ -5,6 +5,1374 @@
     "isolated_scripts": [
       {
         "args": [
+          "battor.power_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "battor.power_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "battor.power_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "battor.power_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "battor.power_cases_no_chrome_trace",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "battor.power_cases_no_chrome_trace",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "battor.power_cases_no_chrome_trace",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "battor.power_cases_no_chrome_trace.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "battor.steady_state",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "battor.steady_state",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "battor.steady_state",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "battor.steady_state.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "battor.tough_video_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "battor.tough_video_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "battor.tough_video_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "battor.tough_video_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "battor.trivial_pages",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "battor.trivial_pages",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "battor.trivial_pages",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "battor.trivial_pages.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.bindings",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.bindings",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device1",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.bindings",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.bindings.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device1",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.blink_gc",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.blink_gc",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device6",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.blink_gc",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.blink_gc.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device6",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.canvas",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.canvas",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.canvas",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.canvas.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.css",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.css",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.css",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.css.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.dom",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.dom",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device1",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.dom",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.dom.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device1",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.events",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.events",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device1",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.events",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.events.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device1",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.layout",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.layout",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.layout",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.layout.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.paint",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.paint",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device3",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.paint",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.paint.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device3",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.paint_slimmingpaintinvalidation",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.paint_slimmingpaintinvalidation",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.paint_slimmingpaintinvalidation",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.paint_slimmingpaintinvalidation.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.parser",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.parser",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device5",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.parser",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.parser.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device5",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.pywebsocket",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.pywebsocket",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.pywebsocket",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.pywebsocket.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.shadow_dom",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.shadow_dom",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.shadow_dom",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.shadow_dom.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.svg",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.svg",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device3",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.svg",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.svg.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device3",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.svg_slimmingpaintinvalidation",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.svg_slimmingpaintinvalidation",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device3",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.svg_slimmingpaintinvalidation",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.svg_slimmingpaintinvalidation.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device3",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.xml_http_request",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.xml_http_request",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device1",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.xml_http_request",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.xml_http_request.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device1",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_style.key_mobile_sites",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_style.key_mobile_sites",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_style.key_mobile_sites",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_style.key_mobile_sites.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_style.polymer",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_style.polymer",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device5",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_style.polymer",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_style.polymer.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device5",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_style.top_25",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_style.top_25",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_style.top_25",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_style.top_25.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blob_storage.blob_storage",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blob_storage.blob_storage",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device3",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blob_storage.blob_storage",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blob_storage.blob_storage.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device3",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
           "dromaeo.cssqueryjquery",
           "-v",
           "--upload-results",
@@ -21,7 +1389,7 @@
           "dimension_sets": [
             {
               "android_devices": "1",
-              "id": "build245-m4--device1",
+              "id": "build245-m4--device6",
               "os": "Android",
               "pool": "Chrome-perf"
             }
@@ -50,6 +1418,91 @@
           "dimension_sets": [
             {
               "android_devices": "1",
+              "id": "build245-m4--device6",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.domcoreattr",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.domcoreattr",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.domcoreattr",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.domcoreattr.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.domcoremodify",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.domcoremodify",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
               "id": "build245-m4--device1",
               "os": "Android",
               "pool": "Chrome-perf"
@@ -62,6 +1515,2828 @@
       },
       {
         "args": [
+          "dromaeo.domcoremodify",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.domcoremodify.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device1",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.domcorequery",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.domcorequery",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.domcorequery",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.domcorequery.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.domcoretraverse",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.domcoretraverse",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.domcoretraverse",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.domcoretraverse.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.jslibattrjquery",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.jslibattrjquery",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device5",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.jslibattrjquery",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.jslibattrjquery.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device5",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.jslibattrprototype",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.jslibattrprototype",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.jslibattrprototype",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.jslibattrprototype.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.jslibeventjquery",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.jslibeventjquery",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.jslibeventjquery",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.jslibeventjquery.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.jslibeventprototype",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.jslibeventprototype",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device3",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.jslibeventprototype",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.jslibeventprototype.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device3",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.jslibmodifyjquery",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.jslibmodifyjquery",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device5",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.jslibmodifyjquery",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.jslibmodifyjquery.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device5",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.jslibmodifyprototype",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.jslibmodifyprototype",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.jslibmodifyprototype",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.jslibmodifyprototype.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.jslibstylejquery",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.jslibstylejquery",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.jslibstylejquery",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.jslibstylejquery.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.jslibstyleprototype",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.jslibstyleprototype",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device1",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.jslibstyleprototype",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.jslibstyleprototype.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device1",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.jslibtraversejquery",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.jslibtraversejquery",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.jslibtraversejquery",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.jslibtraversejquery.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.jslibtraverseprototype",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.jslibtraverseprototype",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device6",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.jslibtraverseprototype",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.jslibtraverseprototype.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device6",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dummy_benchmark.noisy_benchmark_1",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dummy_benchmark.noisy_benchmark_1",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device1",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dummy_benchmark.noisy_benchmark_1",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dummy_benchmark.noisy_benchmark_1.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device1",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dummy_benchmark.stable_benchmark_1",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dummy_benchmark.stable_benchmark_1",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dummy_benchmark.stable_benchmark_1",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dummy_benchmark.stable_benchmark_1.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "gpu_times.gpu_rasterization.key_mobile_sites_smooth",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "gpu_times.gpu_rasterization.key_mobile_sites_smooth",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "gpu_times.gpu_rasterization.key_mobile_sites_smooth",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "gpu_times.gpu_rasterization.key_mobile_sites_smooth.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "gpu_times.gpu_rasterization.top_25_smooth",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "gpu_times.gpu_rasterization.top_25_smooth",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "gpu_times.gpu_rasterization.top_25_smooth",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "gpu_times.gpu_rasterization.top_25_smooth.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "gpu_times.key_mobile_sites_smooth",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "gpu_times.key_mobile_sites_smooth",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "gpu_times.key_mobile_sites_smooth",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "gpu_times.key_mobile_sites_smooth.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "gpu_times.top_25_smooth",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "gpu_times.top_25_smooth",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "gpu_times.top_25_smooth",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "gpu_times.top_25_smooth.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "image_decoding.image_decoding_measurement",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "image_decoding.image_decoding_measurement",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device5",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "image_decoding.image_decoding_measurement",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "image_decoding.image_decoding_measurement.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device5",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "indexeddb_perf",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "indexeddb_perf",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device3",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "indexeddb_perf",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "indexeddb_perf.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device3",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "jetstream",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "jetstream",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "jetstream",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "jetstream.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "jitter",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "jitter",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "jitter",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "jitter.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "kraken",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "kraken",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device5",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "kraken",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "kraken.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device5",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "loading.cluster_telemetry",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "loading.cluster_telemetry",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device1",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "loading.cluster_telemetry",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "loading.cluster_telemetry.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device1",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "loading.mobile",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "loading.mobile",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "loading.mobile",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "loading.mobile.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "media.android.tough_video_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "media.android.tough_video_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device5",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "media.android.tough_video_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "media.android.tough_video_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device5",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "media.chromeOS.tough_video_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "media.chromeOS.tough_video_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "media.chromeOS.tough_video_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "media.chromeOS.tough_video_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "media.chromeOS4kOnly.tough_video_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "media.chromeOS4kOnly.tough_video_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "media.chromeOS4kOnly.tough_video_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "media.chromeOS4kOnly.tough_video_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "media.media_cns_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "media.media_cns_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device1",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "media.media_cns_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "media.media_cns_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device1",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "media.mse_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "media.mse_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device3",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "media.mse_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "media.mse_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device3",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "media.tough_video_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "media.tough_video_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device5",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "media.tough_video_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "media.tough_video_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device5",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "media.tough_video_cases_extra",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "media.tough_video_cases_extra",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "media.tough_video_cases_extra",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "media.tough_video_cases_extra.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "memory.blink_memory_mobile",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "memory.blink_memory_mobile",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "memory.blink_memory_mobile",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "memory.blink_memory_mobile.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "memory.dual_browser_test",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "memory.dual_browser_test",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "memory.dual_browser_test",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "memory.dual_browser_test.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "memory.long_running_dual_browser_test",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "memory.long_running_dual_browser_test",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "memory.long_running_dual_browser_test",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "memory.long_running_dual_browser_test.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "memory.long_running_idle_gmail_background_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "memory.long_running_idle_gmail_background_tbmv2",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device5",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "memory.long_running_idle_gmail_background_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "memory.long_running_idle_gmail_background_tbmv2.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device5",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "memory.long_running_idle_gmail_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "memory.long_running_idle_gmail_tbmv2",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device3",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "memory.long_running_idle_gmail_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "memory.long_running_idle_gmail_tbmv2.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device3",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "memory.top_10_mobile",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "memory.top_10_mobile",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "memory.top_10_mobile",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "memory.top_10_mobile.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "memory.top_10_mobile_stress",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "memory.top_10_mobile_stress",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device6",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "memory.top_10_mobile_stress",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "memory.top_10_mobile_stress.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device6",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "octane",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "octane",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device6",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "octane",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "octane.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device6",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "oilpan_gc_times.blink_perf_stress",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "oilpan_gc_times.blink_perf_stress",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device1",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "oilpan_gc_times.blink_perf_stress",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "oilpan_gc_times.blink_perf_stress.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device1",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "oilpan_gc_times.key_silk_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "oilpan_gc_times.key_silk_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device6",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "oilpan_gc_times.key_silk_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "oilpan_gc_times.key_silk_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device6",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "oilpan_gc_times.sync_scroll.key_mobile_sites_smooth",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "oilpan_gc_times.sync_scroll.key_mobile_sites_smooth",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device3",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "oilpan_gc_times.sync_scroll.key_mobile_sites_smooth",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "oilpan_gc_times.sync_scroll.key_mobile_sites_smooth.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device3",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "oilpan_gc_times.tough_animation_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "oilpan_gc_times.tough_animation_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device6",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "oilpan_gc_times.tough_animation_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "oilpan_gc_times.tough_animation_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device6",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "oortonline",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "oortonline",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device6",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "oortonline",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "oortonline.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device6",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "oortonline_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "oortonline_tbmv2",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device1",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "oortonline_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "oortonline_tbmv2.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device1",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "page_cycler_v2.basic_oopif",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "page_cycler_v2.basic_oopif",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device3",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "page_cycler_v2.basic_oopif",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "page_cycler_v2.basic_oopif.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device3",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "page_cycler_v2.intl_ar_fa_he",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "page_cycler_v2.intl_ar_fa_he",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device3",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "page_cycler_v2.intl_ar_fa_he",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "page_cycler_v2.intl_ar_fa_he.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device3",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "page_cycler_v2.intl_es_fr_pt-BR",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "page_cycler_v2.intl_es_fr_pt-BR",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device5",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "page_cycler_v2.intl_es_fr_pt-BR",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "page_cycler_v2.intl_es_fr_pt-BR.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device5",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
           "page_cycler_v2.intl_hi_ru",
           "-v",
           "--upload-results",
@@ -78,7 +4353,7 @@
           "dimension_sets": [
             {
               "android_devices": "1",
-              "id": "build245-m4--device2",
+              "id": "build245-m4--device7",
               "os": "Android",
               "pool": "Chrome-perf"
             }
@@ -107,6 +4382,34 @@
           "dimension_sets": [
             {
               "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "page_cycler_v2.intl_ja_zh",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "page_cycler_v2.intl_ja_zh",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
               "id": "build245-m4--device2",
               "os": "Android",
               "pool": "Chrome-perf"
@@ -119,6 +4422,2543 @@
       },
       {
         "args": [
+          "page_cycler_v2.intl_ja_zh",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "page_cycler_v2.intl_ja_zh.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "page_cycler_v2.intl_ko_th_vi",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "page_cycler_v2.intl_ko_th_vi",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device6",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "page_cycler_v2.intl_ko_th_vi",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "page_cycler_v2.intl_ko_th_vi.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device6",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "page_cycler_v2.top_10_mobile",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "page_cycler_v2.top_10_mobile",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "page_cycler_v2.top_10_mobile",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "page_cycler_v2.top_10_mobile.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "page_cycler_v2.tough_layout_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "page_cycler_v2.tough_layout_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "page_cycler_v2.tough_layout_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "page_cycler_v2.tough_layout_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "page_cycler_v2.typical_25",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "page_cycler_v2.typical_25",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device3",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "page_cycler_v2.typical_25",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "page_cycler_v2.typical_25.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device3",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "page_cycler_v2_site_isolation.basic_oopif",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "page_cycler_v2_site_isolation.basic_oopif",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "page_cycler_v2_site_isolation.basic_oopif",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "page_cycler_v2_site_isolation.basic_oopif.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "power.android_acceptance",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "power.android_acceptance",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device1",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "power.android_acceptance",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "power.android_acceptance.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device1",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "power.gpu_rasterization.top_10",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "power.gpu_rasterization.top_10",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "power.gpu_rasterization.top_10",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "power.gpu_rasterization.top_10.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "power.gpu_rasterization.top_25",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "power.gpu_rasterization.top_25",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device5",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "power.gpu_rasterization.top_25",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "power.gpu_rasterization.top_25.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device5",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "power.gpu_rasterization.typical_10_mobile",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "power.gpu_rasterization.typical_10_mobile",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "power.gpu_rasterization.typical_10_mobile",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "power.gpu_rasterization.typical_10_mobile.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "power.steady_state",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "power.steady_state",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device5",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "power.steady_state",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "power.steady_state.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device5",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "power.top_10",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "power.top_10",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "power.top_10",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "power.top_10.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "power.top_25",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "power.top_25",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "power.top_25",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "power.top_25.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "power.tough_ad_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "power.tough_ad_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device6",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "power.tough_ad_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "power.tough_ad_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device6",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "power.trivial_pages",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "power.trivial_pages",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "power.trivial_pages",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "power.trivial_pages.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "power.typical_10_mobile",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "power.typical_10_mobile",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "power.typical_10_mobile",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "power.typical_10_mobile.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "power.typical_10_mobile_reload",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "power.typical_10_mobile_reload",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device5",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "power.typical_10_mobile_reload",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "power.typical_10_mobile_reload.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device5",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "rasterize_and_record_micro.key_mobile_sites",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "rasterize_and_record_micro.key_mobile_sites",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "rasterize_and_record_micro.key_mobile_sites",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "rasterize_and_record_micro.key_mobile_sites.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "rasterize_and_record_micro.key_silk_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "rasterize_and_record_micro.key_silk_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "rasterize_and_record_micro.key_silk_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "rasterize_and_record_micro.key_silk_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "rasterize_and_record_micro.partial_invalidation",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "rasterize_and_record_micro.partial_invalidation",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "rasterize_and_record_micro.partial_invalidation",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "rasterize_and_record_micro.partial_invalidation.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "rasterize_and_record_micro.polymer",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "rasterize_and_record_micro.polymer",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "rasterize_and_record_micro.polymer",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "rasterize_and_record_micro.polymer.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "rasterize_and_record_micro.top_25",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "rasterize_and_record_micro.top_25",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device6",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "rasterize_and_record_micro.top_25",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "rasterize_and_record_micro.top_25.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device6",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "repaint.gpu_rasterization.key_mobile_sites_repaint",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "repaint.gpu_rasterization.key_mobile_sites_repaint",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "repaint.gpu_rasterization.key_mobile_sites_repaint",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "repaint.gpu_rasterization.key_mobile_sites_repaint.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "repaint.key_mobile_sites_repaint",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "repaint.key_mobile_sites_repaint",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device3",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "repaint.key_mobile_sites_repaint",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "repaint.key_mobile_sites_repaint.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device3",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "robohornet_pro",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "robohornet_pro",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "robohornet_pro",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "robohornet_pro.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "scheduler.tough_scheduling_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "scheduler.tough_scheduling_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "scheduler.tough_scheduling_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "scheduler.tough_scheduling_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "service_worker.service_worker",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "service_worker.service_worker",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "service_worker.service_worker",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "service_worker.service_worker.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "service_worker.service_worker_micro_benchmark",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "service_worker.service_worker_micro_benchmark",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "service_worker.service_worker_micro_benchmark",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "service_worker.service_worker_micro_benchmark.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.desktop_tough_pinch_zoom_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.desktop_tough_pinch_zoom_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device3",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.desktop_tough_pinch_zoom_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.desktop_tough_pinch_zoom_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device3",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.gpu_rasterization.polymer",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.gpu_rasterization.polymer",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.gpu_rasterization.polymer",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.gpu_rasterization.polymer.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.gpu_rasterization.top_25_smooth",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.gpu_rasterization.top_25_smooth",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.gpu_rasterization.top_25_smooth",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.gpu_rasterization.top_25_smooth.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.gpu_rasterization.tough_filters_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.gpu_rasterization.tough_filters_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device6",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.gpu_rasterization.tough_filters_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.gpu_rasterization.tough_filters_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device6",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.gpu_rasterization.tough_path_rendering_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.gpu_rasterization.tough_path_rendering_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.gpu_rasterization.tough_path_rendering_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.gpu_rasterization.tough_path_rendering_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.gpu_rasterization.tough_pinch_zoom_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.gpu_rasterization.tough_pinch_zoom_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.gpu_rasterization.tough_scrolling_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.gpu_rasterization.tough_scrolling_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device6",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.gpu_rasterization.tough_scrolling_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.gpu_rasterization.tough_scrolling_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device6",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.gpu_rasterization_and_decoding.image_decoding_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.gpu_rasterization_and_decoding.image_decoding_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.gpu_rasterization_and_decoding.image_decoding_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.gpu_rasterization_and_decoding.image_decoding_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.image_decoding_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.image_decoding_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device6",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.image_decoding_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.image_decoding_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device6",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.key_desktop_move_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.key_desktop_move_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device5",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.key_desktop_move_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.key_desktop_move_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device5",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.key_mobile_sites_smooth",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.key_mobile_sites_smooth",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.key_mobile_sites_smooth",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.key_mobile_sites_smooth.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.key_silk_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.key_silk_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device5",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.key_silk_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.key_silk_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device5",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.maps",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.maps",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.maps",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.maps.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.pathological_mobile_sites",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.pathological_mobile_sites",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.pathological_mobile_sites",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.pathological_mobile_sites.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.scrolling_tough_ad_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.scrolling_tough_ad_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.scrolling_tough_ad_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.scrolling_tough_ad_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.simple_mobile_sites",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.simple_mobile_sites",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device3",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.simple_mobile_sites",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.simple_mobile_sites.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device3",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.sync_scroll.key_mobile_sites_smooth",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.sync_scroll.key_mobile_sites_smooth",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device3",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.sync_scroll.key_mobile_sites_smooth",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.sync_scroll.key_mobile_sites_smooth.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device3",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
           "smoothness.top_25_smooth",
           "-v",
           "--upload-results",
@@ -135,7 +6975,7 @@
           "dimension_sets": [
             {
               "android_devices": "1",
-              "id": "build245-m4--device3",
+              "id": "build245-m4--device7",
               "os": "Android",
               "pool": "Chrome-perf"
             }
@@ -164,6 +7004,205 @@
           "dimension_sets": [
             {
               "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.tough_ad_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.tough_ad_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.tough_ad_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.tough_ad_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.tough_animation_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.tough_animation_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device5",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.tough_animation_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.tough_animation_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device5",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.tough_canvas_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.tough_canvas_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device5",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.tough_canvas_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.tough_canvas_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device5",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.tough_filters_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.tough_filters_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
               "id": "build245-m4--device3",
               "os": "Android",
               "pool": "Chrome-perf"
@@ -176,6 +7215,1232 @@
       },
       {
         "args": [
+          "smoothness.tough_filters_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.tough_filters_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device3",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.tough_image_decode_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.tough_image_decode_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device5",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.tough_image_decode_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.tough_image_decode_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device5",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.tough_path_rendering_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.tough_path_rendering_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device3",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.tough_path_rendering_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.tough_path_rendering_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device3",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.tough_pinch_zoom_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.tough_pinch_zoom_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.tough_pinch_zoom_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.tough_pinch_zoom_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.tough_scrolling_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.tough_scrolling_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device6",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.tough_scrolling_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.tough_scrolling_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device6",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.tough_texture_upload_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.tough_texture_upload_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.tough_texture_upload_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.tough_texture_upload_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.tough_webgl_ad_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.tough_webgl_ad_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device3",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.tough_webgl_ad_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.tough_webgl_ad_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device3",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.tough_webgl_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.tough_webgl_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.tough_webgl_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.tough_webgl_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "spaceport",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "spaceport",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device5",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "spaceport",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "spaceport.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device5",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "speedometer",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "speedometer",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device6",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "speedometer-ignition",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "speedometer-ignition",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device1",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "speedometer-ignition",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "speedometer-ignition.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device1",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "speedometer",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "speedometer.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device6",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "start_with_ext.cold.blank_page",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "start_with_ext.cold.blank_page",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "start_with_ext.cold.blank_page",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "start_with_ext.cold.blank_page.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "start_with_ext.warm.blank_page",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "start_with_ext.warm.blank_page",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device6",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "start_with_ext.warm.blank_page",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "start_with_ext.warm.blank_page.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device6",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "start_with_url.cold.startup_pages",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "start_with_url.cold.startup_pages",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device3",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "start_with_url.cold.startup_pages",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "start_with_url.cold.startup_pages.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device3",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "start_with_url.warm.startup_pages",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "start_with_url.warm.startup_pages",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device3",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "start_with_url.warm.startup_pages",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "start_with_url.warm.startup_pages.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device3",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "startup.cold.blank_page",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "startup.cold.blank_page",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device3",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "startup.cold.blank_page",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "startup.cold.blank_page.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device3",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "startup.large_profile.cold.blank_page",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "startup.large_profile.cold.blank_page",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device6",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "startup.large_profile.cold.blank_page",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "startup.large_profile.cold.blank_page.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device6",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "startup.large_profile.warm.blank_page",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "startup.large_profile.warm.blank_page",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "startup.large_profile.warm.blank_page",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "startup.large_profile.warm.blank_page.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "startup.warm.blank_page",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "startup.warm.blank_page",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "startup.warm.blank_page",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "startup.warm.blank_page.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "startup.warm.chrome_signin",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "startup.warm.chrome_signin",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "startup.warm.chrome_signin",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "startup.warm.chrome_signin.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "storage.indexeddb_endure",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "storage.indexeddb_endure",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device3",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "storage.indexeddb_endure",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "storage.indexeddb_endure.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device3",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "storage.indexeddb_endure_tracing",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "storage.indexeddb_endure_tracing",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device5",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "storage.indexeddb_endure_tracing",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "storage.indexeddb_endure_tracing.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device5",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
           "sunspider",
           "-v",
           "--upload-results",
@@ -192,7 +8457,7 @@
           "dimension_sets": [
             {
               "android_devices": "1",
-              "id": "build245-m4--device4",
+              "id": "build245-m4--device6",
               "os": "Android",
               "pool": "Chrome-perf"
             }
@@ -221,6 +8486,34 @@
           "dimension_sets": [
             {
               "android_devices": "1",
+              "id": "build245-m4--device6",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "system_health.common_desktop",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "system_health.common_desktop",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
               "id": "build245-m4--device4",
               "os": "Android",
               "pool": "Chrome-perf"
@@ -233,6 +8526,206 @@
       },
       {
         "args": [
+          "system_health.common_desktop",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "system_health.common_desktop.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "system_health.common_mobile",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "system_health.common_mobile",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "system_health.common_mobile",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "system_health.common_mobile.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "system_health.memory_desktop",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "system_health.memory_desktop",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device1",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "system_health.memory_desktop",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "system_health.memory_desktop.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device1",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "system_health.memory_mobile",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "system_health.memory_mobile",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device6",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "system_health.memory_mobile",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "system_health.memory_mobile.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device6",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
           "system_health.webview_startup",
           "-v",
           "--upload-results",
@@ -249,7 +8742,7 @@
           "dimension_sets": [
             {
               "android_devices": "1",
-              "id": "build245-m4--device5",
+              "id": "build245-m4--device7",
               "os": "Android",
               "pool": "Chrome-perf"
             }
@@ -278,6 +8771,2172 @@
           "dimension_sets": [
             {
               "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "system_health.webview_startup_multiprocess",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "system_health.webview_startup_multiprocess",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "system_health.webview_startup_multiprocess",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "system_health.webview_startup_multiprocess.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "tab_switching.five_blank_pages",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "tab_switching.five_blank_pages",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "tab_switching.five_blank_pages",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "tab_switching.five_blank_pages.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "tab_switching.top_10",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "tab_switching.top_10",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "tab_switching.top_10",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "tab_switching.top_10.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "tab_switching.tough_energy_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "tab_switching.tough_energy_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "tab_switching.tough_energy_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "tab_switching.tough_energy_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "tab_switching.tough_image_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "tab_switching.tough_image_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "tab_switching.tough_image_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "tab_switching.tough_image_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "tab_switching.typical_25",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "tab_switching.typical_25",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device5",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "tab_switching.typical_25",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "tab_switching.typical_25.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device5",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "text_selection.character",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "text_selection.character",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device1",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "text_selection.character",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "text_selection.character.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device1",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "text_selection.direction",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "text_selection.direction",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "text_selection.direction",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "text_selection.direction.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "thread_times.key_hit_test_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "thread_times.key_hit_test_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device1",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "thread_times.key_hit_test_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "thread_times.key_hit_test_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device1",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "thread_times.key_idle_power_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "thread_times.key_idle_power_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "thread_times.key_idle_power_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "thread_times.key_idle_power_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device7",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "thread_times.key_mobile_sites_smooth",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "thread_times.key_mobile_sites_smooth",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "thread_times.key_mobile_sites_smooth",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "thread_times.key_mobile_sites_smooth.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "thread_times.key_noop_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "thread_times.key_noop_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device3",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "thread_times.key_noop_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "thread_times.key_noop_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device3",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "thread_times.key_silk_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "thread_times.key_silk_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "thread_times.key_silk_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "thread_times.key_silk_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "thread_times.polymer",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "thread_times.polymer",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device1",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "thread_times.polymer",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "thread_times.polymer.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device1",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "thread_times.simple_mobile_sites",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "thread_times.simple_mobile_sites",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device5",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "thread_times.simple_mobile_sites",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "thread_times.simple_mobile_sites.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device5",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "thread_times.tough_compositor_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "thread_times.tough_compositor_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "thread_times.tough_compositor_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "thread_times.tough_compositor_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "thread_times.tough_scrolling_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "thread_times.tough_scrolling_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device6",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "thread_times.tough_scrolling_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "thread_times.tough_scrolling_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device6",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "tracing.tracing_with_background_memory_infra",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "tracing.tracing_with_background_memory_infra",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device6",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "tracing.tracing_with_background_memory_infra",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "tracing.tracing_with_background_memory_infra.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device6",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "tracing.tracing_with_debug_overhead",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "tracing.tracing_with_debug_overhead",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device1",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "tracing.tracing_with_debug_overhead",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "tracing.tracing_with_debug_overhead.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device1",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.browsing_desktop",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.browsing_desktop",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device3",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.browsing_desktop",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.browsing_desktop.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device3",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.browsing_desktop_ignition",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.browsing_desktop_ignition",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.browsing_desktop_ignition",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.browsing_desktop_ignition.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.browsing_mobile",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.browsing_mobile",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.browsing_mobile",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.browsing_mobile.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.browsing_mobile_ignition",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.browsing_mobile_ignition",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device6",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.browsing_mobile_ignition",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.browsing_mobile_ignition.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device6",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.detached_context_age_in_gc",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.detached_context_age_in_gc",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.detached_context_age_in_gc",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.detached_context_age_in_gc.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device4",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.google",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.google",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device1",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.google",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.google.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device1",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.infinite_scroll-ignition_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.infinite_scroll-ignition_tbmv2",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device1",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.infinite_scroll-ignition_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.infinite_scroll-ignition_tbmv2.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device1",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.infinite_scroll_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.infinite_scroll_tbmv2",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device6",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.infinite_scroll_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.infinite_scroll_tbmv2.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device6",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.key_mobile_sites_smooth",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.key_mobile_sites_smooth",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device5",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.key_mobile_sites_smooth",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.key_mobile_sites_smooth.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device5",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.mobile_infinite_scroll_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.mobile_infinite_scroll_tbmv2",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device1",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.mobile_infinite_scroll_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.mobile_infinite_scroll_tbmv2.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device1",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.runtime_stats.top_25",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.runtime_stats.top_25",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device1",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.runtime_stats.top_25",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.runtime_stats.top_25.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device1",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.todomvc",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.todomvc",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.todomvc-ignition",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.todomvc-ignition",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device3",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.todomvc-ignition",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.todomvc-ignition.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device3",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.todomvc",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.todomvc.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.top_25_smooth",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.top_25_smooth",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device6",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.top_25_smooth",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.top_25_smooth.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device6",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "webrtc.datachannel",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.datachannel",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "webrtc.datachannel",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.datachannel.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device2",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "webrtc.getusermedia",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.getusermedia",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device5",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "webrtc.getusermedia",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.getusermedia.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device5",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "webrtc.peerconnection",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.peerconnection",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device6",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "webrtc.peerconnection",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.peerconnection.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device6",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "webrtc.stress",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.stress",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device1",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "webrtc.stress",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.stress.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device1",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "webrtc.webrtc_smoothness",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=android-chromium"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.webrtc_smoothness",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
+              "id": "build245-m4--device5",
+              "os": "Android",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "webrtc.webrtc_smoothness",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.webrtc_smoothness.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "android_devices": "1",
               "id": "build245-m4--device5",
               "os": "Android",
               "pool": "Chrome-perf"
@@ -301,7 +10960,1375 @@
           "dimension_sets": [
             {
               "gpu": "8086:22b1",
-              "id": "build48-b4",
+              "id": "build137-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "battor.power_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "battor.power_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build148-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "battor.power_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "battor.power_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build148-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "battor.power_cases_no_chrome_trace",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "battor.power_cases_no_chrome_trace",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build145-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "battor.power_cases_no_chrome_trace",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "battor.power_cases_no_chrome_trace.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build145-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "battor.steady_state",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "battor.steady_state",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build149-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "battor.steady_state",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "battor.steady_state.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build149-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "battor.tough_video_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "battor.tough_video_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build146-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "battor.tough_video_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "battor.tough_video_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build146-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "battor.trivial_pages",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "battor.trivial_pages",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build142-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "battor.trivial_pages",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "battor.trivial_pages.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build142-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.bindings",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.bindings",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build47-b4",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.bindings",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.bindings.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build47-b4",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.blink_gc",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.blink_gc",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build142-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.blink_gc",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.blink_gc.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build142-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.canvas",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.canvas",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build47-b4",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.canvas",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.canvas.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build47-b4",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.css",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.css",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build154-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.css",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.css.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build154-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.dom",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.dom",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build145-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.dom",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.dom.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build145-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.events",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.events",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build141-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.events",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.events.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build141-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.layout",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.layout",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build143-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.layout",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.layout.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build143-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.paint",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.paint",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build146-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.paint",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.paint.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build146-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.paint_slimmingpaintinvalidation",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.paint_slimmingpaintinvalidation",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build144-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.paint_slimmingpaintinvalidation",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.paint_slimmingpaintinvalidation.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build144-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.parser",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.parser",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build155-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.parser",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.parser.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build155-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.pywebsocket",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.pywebsocket",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build149-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.pywebsocket",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.pywebsocket.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build149-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.shadow_dom",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.shadow_dom",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build148-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.shadow_dom",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.shadow_dom.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build148-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.svg",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.svg",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build151-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.svg",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.svg.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build151-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.svg_slimmingpaintinvalidation",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.svg_slimmingpaintinvalidation",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build146-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.svg_slimmingpaintinvalidation",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.svg_slimmingpaintinvalidation.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build146-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.xml_http_request",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.xml_http_request",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build141-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_perf.xml_http_request",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_perf.xml_http_request.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build141-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_style.key_mobile_sites",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_style.key_mobile_sites",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build155-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_style.key_mobile_sites",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_style.key_mobile_sites.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build155-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_style.polymer",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_style.polymer",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build138-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_style.polymer",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_style.polymer.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build138-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_style.top_25",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_style.top_25",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build151-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blink_style.top_25",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blink_style.top_25.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build151-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blob_storage.blob_storage",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blob_storage.blob_storage",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build145-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "blob_storage.blob_storage",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "blob_storage.blob_storage.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build145-b1",
               "os": "Windows-10-10586",
               "pool": "Chrome-perf"
             }
@@ -320,7 +12347,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:22b1",
-              "id": "build47-b4",
+              "id": "build136-b1",
               "os": "Windows-10-10586",
               "pool": "Chrome-perf"
             }
@@ -388,6 +12415,918 @@
         }
       },
       {
+        "args": [
+          "dromaeo.domcoreattr",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.domcoreattr",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build151-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.domcoreattr",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.domcoreattr.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build151-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.domcoremodify",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.domcoremodify",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build150-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.domcoremodify",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.domcoremodify.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build150-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.domcorequery",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.domcorequery",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build143-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.domcorequery",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.domcorequery.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build143-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.domcoretraverse",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.domcoretraverse",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build144-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.domcoretraverse",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.domcoretraverse.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build144-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.jslibattrjquery",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.jslibattrjquery",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build154-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.jslibattrjquery",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.jslibattrjquery.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build154-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.jslibattrprototype",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.jslibattrprototype",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build155-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.jslibattrprototype",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.jslibattrprototype.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build155-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.jslibeventjquery",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.jslibeventjquery",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build148-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.jslibeventjquery",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.jslibeventjquery.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build148-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.jslibeventprototype",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.jslibeventprototype",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build148-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.jslibeventprototype",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.jslibeventprototype.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build148-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.jslibmodifyjquery",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.jslibmodifyjquery",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build48-b4",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.jslibmodifyjquery",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.jslibmodifyjquery.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build48-b4",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.jslibmodifyprototype",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.jslibmodifyprototype",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build151-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.jslibmodifyprototype",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.jslibmodifyprototype.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build151-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.jslibstylejquery",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.jslibstylejquery",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build144-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.jslibstylejquery",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.jslibstylejquery.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build144-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.jslibstyleprototype",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.jslibstyleprototype",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build47-b4",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.jslibstyleprototype",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.jslibstyleprototype.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build47-b4",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.jslibtraversejquery",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.jslibtraversejquery",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build155-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.jslibtraversejquery",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.jslibtraversejquery.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build155-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.jslibtraverseprototype",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.jslibtraverseprototype",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build145-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dromaeo.jslibtraverseprototype",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dromaeo.jslibtraverseprototype.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build145-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dummy_benchmark.noisy_benchmark_1",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dummy_benchmark.noisy_benchmark_1",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build47-b4",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dummy_benchmark.noisy_benchmark_1",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dummy_benchmark.noisy_benchmark_1.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build47-b4",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dummy_benchmark.stable_benchmark_1",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dummy_benchmark.stable_benchmark_1",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build47-b4",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "dummy_benchmark.stable_benchmark_1",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "dummy_benchmark.stable_benchmark_1.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build47-b4",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
         "args": [],
         "isolate_name": "gpu_perftests",
         "name": "gpu_perftests",
@@ -396,7 +13335,520 @@
           "dimension_sets": [
             {
               "gpu": "8086:22b1",
-              "id": "build47-b4",
+              "id": "build136-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "gpu_times.gpu_rasterization.key_mobile_sites_smooth",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "gpu_times.gpu_rasterization.key_mobile_sites_smooth",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build153-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "gpu_times.gpu_rasterization.key_mobile_sites_smooth",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "gpu_times.gpu_rasterization.key_mobile_sites_smooth.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build153-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "gpu_times.gpu_rasterization.top_25_smooth",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "gpu_times.gpu_rasterization.top_25_smooth",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build155-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "gpu_times.gpu_rasterization.top_25_smooth",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "gpu_times.gpu_rasterization.top_25_smooth.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build155-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "gpu_times.key_mobile_sites_smooth",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "gpu_times.key_mobile_sites_smooth",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build146-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "gpu_times.key_mobile_sites_smooth",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "gpu_times.key_mobile_sites_smooth.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build146-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "gpu_times.top_25_smooth",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "gpu_times.top_25_smooth",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build141-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "gpu_times.top_25_smooth",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "gpu_times.top_25_smooth.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build141-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "image_decoding.image_decoding_measurement",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "image_decoding.image_decoding_measurement",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build147-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "image_decoding.image_decoding_measurement",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "image_decoding.image_decoding_measurement.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build147-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "indexeddb_perf",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "indexeddb_perf",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build154-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "indexeddb_perf",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "indexeddb_perf.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build154-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "jetstream",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "jetstream",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build154-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "jetstream",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "jetstream.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build154-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "jitter",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "jitter",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build150-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "jitter",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "jitter.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build150-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "kraken",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "kraken",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build146-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "kraken",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "kraken.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build146-b1",
               "os": "Windows-10-10586",
               "pool": "Chrome-perf"
             }
@@ -415,6 +13867,889 @@
           "dimension_sets": [
             {
               "gpu": "8086:22b1",
+              "id": "build136-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "loading.cluster_telemetry",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "loading.cluster_telemetry",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build138-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "loading.cluster_telemetry",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "loading.cluster_telemetry.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build138-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "loading.mobile",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "loading.mobile",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build48-b4",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "loading.mobile",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "loading.mobile.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build48-b4",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "media.android.tough_video_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "media.android.tough_video_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build142-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "media.android.tough_video_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "media.android.tough_video_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build142-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "media.chromeOS.tough_video_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "media.chromeOS.tough_video_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build141-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "media.chromeOS.tough_video_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "media.chromeOS.tough_video_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build141-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "media.chromeOS4kOnly.tough_video_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "media.chromeOS4kOnly.tough_video_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build148-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "media.chromeOS4kOnly.tough_video_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "media.chromeOS4kOnly.tough_video_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build148-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "media.media_cns_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "media.media_cns_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build153-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "media.media_cns_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "media.media_cns_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build153-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "media.mse_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "media.mse_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build143-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "media.mse_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "media.mse_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build143-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "media.tough_video_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "media.tough_video_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build147-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "media.tough_video_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "media.tough_video_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build147-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "media.tough_video_cases_extra",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "media.tough_video_cases_extra",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build142-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "media.tough_video_cases_extra",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "media.tough_video_cases_extra.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build142-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "memory.blink_memory_mobile",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "memory.blink_memory_mobile",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build137-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "memory.blink_memory_mobile",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "memory.blink_memory_mobile.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build137-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "memory.dual_browser_test",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "memory.dual_browser_test",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build138-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "memory.dual_browser_test",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "memory.dual_browser_test.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build138-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "memory.long_running_dual_browser_test",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "memory.long_running_dual_browser_test",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build143-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "memory.long_running_dual_browser_test",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "memory.long_running_dual_browser_test.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build143-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "memory.long_running_idle_gmail_background_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "memory.long_running_idle_gmail_background_tbmv2",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build152-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "memory.long_running_idle_gmail_background_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "memory.long_running_idle_gmail_background_tbmv2.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build152-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "memory.long_running_idle_gmail_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "memory.long_running_idle_gmail_tbmv2",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build140-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "memory.long_running_idle_gmail_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "memory.long_running_idle_gmail_tbmv2.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build140-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "memory.top_10_mobile",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "memory.top_10_mobile",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build155-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "memory.top_10_mobile",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "memory.top_10_mobile.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build155-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "memory.top_10_mobile_stress",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "memory.top_10_mobile_stress",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
               "id": "build47-b4",
               "os": "Windows-10-10586",
               "pool": "Chrome-perf"
@@ -427,6 +14762,605 @@
       },
       {
         "args": [
+          "memory.top_10_mobile_stress",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "memory.top_10_mobile_stress.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build47-b4",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "octane",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "octane",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build142-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "octane",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "octane.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build142-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "oilpan_gc_times.blink_perf_stress",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "oilpan_gc_times.blink_perf_stress",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build152-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "oilpan_gc_times.blink_perf_stress",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "oilpan_gc_times.blink_perf_stress.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build152-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "oilpan_gc_times.key_silk_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "oilpan_gc_times.key_silk_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build141-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "oilpan_gc_times.key_silk_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "oilpan_gc_times.key_silk_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build141-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "oilpan_gc_times.sync_scroll.key_mobile_sites_smooth",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "oilpan_gc_times.sync_scroll.key_mobile_sites_smooth",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build47-b4",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "oilpan_gc_times.sync_scroll.key_mobile_sites_smooth",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "oilpan_gc_times.sync_scroll.key_mobile_sites_smooth.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build47-b4",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "oilpan_gc_times.tough_animation_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "oilpan_gc_times.tough_animation_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build150-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "oilpan_gc_times.tough_animation_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "oilpan_gc_times.tough_animation_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build150-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "oortonline",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "oortonline",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build155-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "oortonline",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "oortonline.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build155-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "oortonline_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "oortonline_tbmv2",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build140-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "oortonline_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "oortonline_tbmv2.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build140-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "page_cycler_v2.basic_oopif",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "page_cycler_v2.basic_oopif",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build150-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "page_cycler_v2.basic_oopif",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "page_cycler_v2.basic_oopif.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build150-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "page_cycler_v2.intl_ar_fa_he",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "page_cycler_v2.intl_ar_fa_he",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build147-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "page_cycler_v2.intl_ar_fa_he",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "page_cycler_v2.intl_ar_fa_he.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build147-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "page_cycler_v2.intl_es_fr_pt-BR",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "page_cycler_v2.intl_es_fr_pt-BR",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build145-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "page_cycler_v2.intl_es_fr_pt-BR",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "page_cycler_v2.intl_es_fr_pt-BR.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build145-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
           "page_cycler_v2.intl_hi_ru",
           "-v",
           "--upload-results",
@@ -443,7 +15377,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:22b1",
-              "id": "build48-b4",
+              "id": "build143-b1",
               "os": "Windows-10-10586",
               "pool": "Chrome-perf"
             }
@@ -472,6 +15406,148 @@
           "dimension_sets": [
             {
               "gpu": "8086:22b1",
+              "id": "build143-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "page_cycler_v2.intl_ja_zh",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "page_cycler_v2.intl_ja_zh",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build137-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "page_cycler_v2.intl_ja_zh",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "page_cycler_v2.intl_ja_zh.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build137-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "page_cycler_v2.intl_ko_th_vi",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "page_cycler_v2.intl_ko_th_vi",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build141-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "page_cycler_v2.intl_ko_th_vi",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "page_cycler_v2.intl_ko_th_vi.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build141-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "page_cycler_v2.top_10_mobile",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "page_cycler_v2.top_10_mobile",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
               "id": "build48-b4",
               "os": "Windows-10-10586",
               "pool": "Chrome-perf"
@@ -483,6 +15559,206 @@
         }
       },
       {
+        "args": [
+          "page_cycler_v2.top_10_mobile",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "page_cycler_v2.top_10_mobile.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build48-b4",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "page_cycler_v2.tough_layout_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "page_cycler_v2.tough_layout_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build148-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "page_cycler_v2.tough_layout_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "page_cycler_v2.tough_layout_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build148-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "page_cycler_v2.typical_25",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "page_cycler_v2.typical_25",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build138-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "page_cycler_v2.typical_25",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "page_cycler_v2.typical_25.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build138-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "page_cycler_v2_site_isolation.basic_oopif",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "page_cycler_v2_site_isolation.basic_oopif",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build149-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "page_cycler_v2_site_isolation.basic_oopif",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "page_cycler_v2_site_isolation.basic_oopif.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build149-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
         "args": [],
         "isolate_name": "performance_browser_tests",
         "name": "performance_browser_tests",
@@ -491,6 +15767,547 @@
           "dimension_sets": [
             {
               "gpu": "8086:22b1",
+              "id": "build137-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "power.android_acceptance",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "power.android_acceptance",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build153-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "power.android_acceptance",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "power.android_acceptance.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build153-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "power.gpu_rasterization.top_10",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "power.gpu_rasterization.top_10",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build154-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "power.gpu_rasterization.top_10",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "power.gpu_rasterization.top_10.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build154-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "power.gpu_rasterization.top_25",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "power.gpu_rasterization.top_25",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build151-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "power.gpu_rasterization.top_25",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "power.gpu_rasterization.top_25.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build151-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "power.gpu_rasterization.typical_10_mobile",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "power.gpu_rasterization.typical_10_mobile",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build136-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "power.gpu_rasterization.typical_10_mobile",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "power.gpu_rasterization.typical_10_mobile.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build136-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "power.steady_state",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "power.steady_state",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build152-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "power.steady_state",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "power.steady_state.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build152-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "power.top_10",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "power.top_10",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build152-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "power.top_10",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "power.top_10.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build152-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "power.top_25",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "power.top_25",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build152-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "power.top_25",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "power.top_25.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build152-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "power.tough_ad_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "power.tough_ad_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build153-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "power.tough_ad_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "power.tough_ad_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build153-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "power.trivial_pages",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "power.trivial_pages",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build155-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "power.trivial_pages",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "power.trivial_pages.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build155-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "power.typical_10_mobile",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "power.typical_10_mobile",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
               "id": "build48-b4",
               "os": "Windows-10-10586",
               "pool": "Chrome-perf"
@@ -503,6 +16320,1688 @@
       },
       {
         "args": [
+          "power.typical_10_mobile",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "power.typical_10_mobile.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build48-b4",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "power.typical_10_mobile_reload",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "power.typical_10_mobile_reload",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build155-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "power.typical_10_mobile_reload",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "power.typical_10_mobile_reload.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build155-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "rasterize_and_record_micro.key_mobile_sites",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "rasterize_and_record_micro.key_mobile_sites",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build154-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "rasterize_and_record_micro.key_mobile_sites",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "rasterize_and_record_micro.key_mobile_sites.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build154-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "rasterize_and_record_micro.key_silk_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "rasterize_and_record_micro.key_silk_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build136-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "rasterize_and_record_micro.key_silk_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "rasterize_and_record_micro.key_silk_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build136-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "rasterize_and_record_micro.partial_invalidation",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "rasterize_and_record_micro.partial_invalidation",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build152-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "rasterize_and_record_micro.partial_invalidation",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "rasterize_and_record_micro.partial_invalidation.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build152-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "rasterize_and_record_micro.polymer",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "rasterize_and_record_micro.polymer",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build140-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "rasterize_and_record_micro.polymer",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "rasterize_and_record_micro.polymer.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build140-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "rasterize_and_record_micro.top_25",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "rasterize_and_record_micro.top_25",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build150-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "rasterize_and_record_micro.top_25",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "rasterize_and_record_micro.top_25.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build150-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "repaint.gpu_rasterization.key_mobile_sites_repaint",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "repaint.gpu_rasterization.key_mobile_sites_repaint",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build151-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "repaint.gpu_rasterization.key_mobile_sites_repaint",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "repaint.gpu_rasterization.key_mobile_sites_repaint.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build151-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "repaint.key_mobile_sites_repaint",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "repaint.key_mobile_sites_repaint",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build147-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "repaint.key_mobile_sites_repaint",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "repaint.key_mobile_sites_repaint.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build147-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "robohornet_pro",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "robohornet_pro",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build142-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "robohornet_pro",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "robohornet_pro.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build142-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "scheduler.tough_scheduling_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "scheduler.tough_scheduling_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build151-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "scheduler.tough_scheduling_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "scheduler.tough_scheduling_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build151-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "service_worker.service_worker",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "service_worker.service_worker",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build149-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "service_worker.service_worker",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "service_worker.service_worker.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build149-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "service_worker.service_worker_micro_benchmark",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "service_worker.service_worker_micro_benchmark",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build48-b4",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "service_worker.service_worker_micro_benchmark",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "service_worker.service_worker_micro_benchmark.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build48-b4",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.desktop_tough_pinch_zoom_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.desktop_tough_pinch_zoom_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build153-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.desktop_tough_pinch_zoom_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.desktop_tough_pinch_zoom_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build153-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.gpu_rasterization.polymer",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.gpu_rasterization.polymer",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build137-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.gpu_rasterization.polymer",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.gpu_rasterization.polymer.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build137-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.gpu_rasterization.top_25_smooth",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.gpu_rasterization.top_25_smooth",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build145-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.gpu_rasterization.top_25_smooth",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.gpu_rasterization.top_25_smooth.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build145-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.gpu_rasterization.tough_filters_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.gpu_rasterization.tough_filters_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build141-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.gpu_rasterization.tough_filters_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.gpu_rasterization.tough_filters_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build141-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.gpu_rasterization.tough_path_rendering_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.gpu_rasterization.tough_path_rendering_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build48-b4",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.gpu_rasterization.tough_path_rendering_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.gpu_rasterization.tough_path_rendering_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build48-b4",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.gpu_rasterization.tough_pinch_zoom_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build146-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.gpu_rasterization.tough_pinch_zoom_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build146-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.gpu_rasterization.tough_scrolling_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.gpu_rasterization.tough_scrolling_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build140-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.gpu_rasterization.tough_scrolling_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.gpu_rasterization.tough_scrolling_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build140-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.gpu_rasterization_and_decoding.image_decoding_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.gpu_rasterization_and_decoding.image_decoding_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build140-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.gpu_rasterization_and_decoding.image_decoding_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.gpu_rasterization_and_decoding.image_decoding_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build140-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.image_decoding_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.image_decoding_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build147-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.image_decoding_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.image_decoding_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build147-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.key_desktop_move_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.key_desktop_move_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build152-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.key_desktop_move_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.key_desktop_move_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build152-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.key_mobile_sites_smooth",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.key_mobile_sites_smooth",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build142-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.key_mobile_sites_smooth",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.key_mobile_sites_smooth.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build142-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.key_silk_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.key_silk_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build142-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.key_silk_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.key_silk_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build142-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.maps",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.maps",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build138-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.maps",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.maps.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build138-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.pathological_mobile_sites",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.pathological_mobile_sites",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build145-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.pathological_mobile_sites",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.pathological_mobile_sites.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build145-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.scrolling_tough_ad_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.scrolling_tough_ad_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build144-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.scrolling_tough_ad_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.scrolling_tough_ad_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build144-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.simple_mobile_sites",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.simple_mobile_sites",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build136-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.simple_mobile_sites",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.simple_mobile_sites.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build136-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.sync_scroll.key_mobile_sites_smooth",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.sync_scroll.key_mobile_sites_smooth",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build47-b4",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.sync_scroll.key_mobile_sites_smooth",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.sync_scroll.key_mobile_sites_smooth.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build47-b4",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
           "smoothness.top_25_smooth",
           "-v",
           "--upload-results",
@@ -519,7 +18018,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:22b1",
-              "id": "build47-b4",
+              "id": "build148-b1",
               "os": "Windows-10-10586",
               "pool": "Chrome-perf"
             }
@@ -548,6 +18047,1060 @@
           "dimension_sets": [
             {
               "gpu": "8086:22b1",
+              "id": "build148-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.tough_ad_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.tough_ad_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build148-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.tough_ad_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.tough_ad_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build148-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.tough_animation_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.tough_animation_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build140-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.tough_animation_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.tough_animation_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build140-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.tough_canvas_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.tough_canvas_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build48-b4",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.tough_canvas_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.tough_canvas_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build48-b4",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.tough_filters_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.tough_filters_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build146-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.tough_filters_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.tough_filters_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build146-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.tough_image_decode_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.tough_image_decode_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build140-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.tough_image_decode_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.tough_image_decode_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build140-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.tough_path_rendering_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.tough_path_rendering_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build153-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.tough_path_rendering_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.tough_path_rendering_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build153-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.tough_pinch_zoom_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.tough_pinch_zoom_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build141-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.tough_pinch_zoom_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.tough_pinch_zoom_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build141-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.tough_scrolling_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.tough_scrolling_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build153-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.tough_scrolling_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.tough_scrolling_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build153-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.tough_texture_upload_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.tough_texture_upload_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build143-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.tough_texture_upload_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.tough_texture_upload_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build143-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.tough_webgl_ad_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.tough_webgl_ad_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build146-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.tough_webgl_ad_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.tough_webgl_ad_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build146-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.tough_webgl_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.tough_webgl_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build149-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "smoothness.tough_webgl_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "smoothness.tough_webgl_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build149-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "spaceport",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "spaceport",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build155-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "spaceport",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "spaceport.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build155-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "speedometer",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "speedometer",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build147-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "speedometer-ignition",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "speedometer-ignition",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build153-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "speedometer-ignition",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "speedometer-ignition.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build153-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "speedometer",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "speedometer.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build147-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "start_with_ext.cold.blank_page",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "start_with_ext.cold.blank_page",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build152-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "start_with_ext.cold.blank_page",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "start_with_ext.cold.blank_page.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build152-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "start_with_ext.warm.blank_page",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "start_with_ext.warm.blank_page",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build149-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "start_with_ext.warm.blank_page",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "start_with_ext.warm.blank_page.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build149-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "start_with_url.cold.startup_pages",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "start_with_url.cold.startup_pages",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build140-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "start_with_url.cold.startup_pages",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "start_with_url.cold.startup_pages.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build140-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "start_with_url.warm.startup_pages",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "start_with_url.warm.startup_pages",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build143-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "start_with_url.warm.startup_pages",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "start_with_url.warm.startup_pages.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build143-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "startup.cold.blank_page",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "startup.cold.blank_page",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
               "id": "build47-b4",
               "os": "Windows-10-10586",
               "pool": "Chrome-perf"
@@ -560,6 +19113,377 @@
       },
       {
         "args": [
+          "startup.cold.blank_page",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "startup.cold.blank_page.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build47-b4",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "startup.large_profile.cold.blank_page",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "startup.large_profile.cold.blank_page",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build144-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "startup.large_profile.cold.blank_page",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "startup.large_profile.cold.blank_page.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build144-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "startup.large_profile.warm.blank_page",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "startup.large_profile.warm.blank_page",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build150-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "startup.large_profile.warm.blank_page",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "startup.large_profile.warm.blank_page.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build150-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "startup.warm.blank_page",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "startup.warm.blank_page",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build150-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "startup.warm.blank_page",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "startup.warm.blank_page.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build150-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "startup.warm.chrome_signin",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "startup.warm.chrome_signin",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build48-b4",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "startup.warm.chrome_signin",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "startup.warm.chrome_signin.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build48-b4",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "storage.indexeddb_endure",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "storage.indexeddb_endure",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build143-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "storage.indexeddb_endure",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "storage.indexeddb_endure.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build143-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "storage.indexeddb_endure_tracing",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "storage.indexeddb_endure_tracing",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build142-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "storage.indexeddb_endure_tracing",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "storage.indexeddb_endure_tracing.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build142-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
           "sunspider",
           "-v",
           "--upload-results",
@@ -576,7 +19500,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:22b1",
-              "id": "build48-b4",
+              "id": "build153-b1",
               "os": "Windows-10-10586",
               "pool": "Chrome-perf"
             }
@@ -605,7 +19529,235 @@
           "dimension_sets": [
             {
               "gpu": "8086:22b1",
-              "id": "build48-b4",
+              "id": "build153-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "system_health.common_desktop",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "system_health.common_desktop",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build139-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "system_health.common_desktop",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "system_health.common_desktop.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build139-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "system_health.common_mobile",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "system_health.common_mobile",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build139-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "system_health.common_mobile",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "system_health.common_mobile.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build139-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "system_health.memory_desktop",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "system_health.memory_desktop",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build136-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "system_health.memory_desktop",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "system_health.memory_desktop.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build136-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "system_health.memory_mobile",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "system_health.memory_mobile",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build147-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "system_health.memory_mobile",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "system_health.memory_mobile.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build147-b1",
               "os": "Windows-10-10586",
               "pool": "Chrome-perf"
             }
@@ -633,7 +19785,7 @@
           "dimension_sets": [
             {
               "gpu": "8086:22b1",
-              "id": "build47-b4",
+              "id": "build140-b1",
               "os": "Windows-10-10586",
               "pool": "Chrome-perf"
             }
@@ -662,6 +19814,604 @@
           "dimension_sets": [
             {
               "gpu": "8086:22b1",
+              "id": "build140-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "system_health.webview_startup_multiprocess",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "system_health.webview_startup_multiprocess",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build139-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "system_health.webview_startup_multiprocess",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "system_health.webview_startup_multiprocess.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build139-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "tab_switching.five_blank_pages",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "tab_switching.five_blank_pages",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build48-b4",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "tab_switching.five_blank_pages",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "tab_switching.five_blank_pages.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build48-b4",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "tab_switching.top_10",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "tab_switching.top_10",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build144-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "tab_switching.top_10",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "tab_switching.top_10.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build144-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "tab_switching.tough_energy_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "tab_switching.tough_energy_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build155-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "tab_switching.tough_energy_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "tab_switching.tough_energy_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build155-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "tab_switching.tough_image_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "tab_switching.tough_image_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build142-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "tab_switching.tough_image_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "tab_switching.tough_image_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build142-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "tab_switching.typical_25",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "tab_switching.typical_25",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build155-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "tab_switching.typical_25",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "tab_switching.typical_25.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build155-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "text_selection.character",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "text_selection.character",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build147-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "text_selection.character",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "text_selection.character.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build147-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "text_selection.direction",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "text_selection.direction",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build146-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "text_selection.direction",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "text_selection.direction.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build146-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "thread_times.key_hit_test_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "thread_times.key_hit_test_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build145-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "thread_times.key_hit_test_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "thread_times.key_hit_test_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build145-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "thread_times.key_idle_power_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "thread_times.key_idle_power_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build151-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "thread_times.key_idle_power_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "thread_times.key_idle_power_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build151-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "thread_times.key_mobile_sites_smooth",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "thread_times.key_mobile_sites_smooth",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
               "id": "build47-b4",
               "os": "Windows-10-10586",
               "pool": "Chrome-perf"
@@ -673,6 +20423,491 @@
         }
       },
       {
+        "args": [
+          "thread_times.key_mobile_sites_smooth",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "thread_times.key_mobile_sites_smooth.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build47-b4",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "thread_times.key_noop_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "thread_times.key_noop_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build143-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "thread_times.key_noop_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "thread_times.key_noop_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build143-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "thread_times.key_silk_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "thread_times.key_silk_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build155-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "thread_times.key_silk_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "thread_times.key_silk_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build155-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "thread_times.polymer",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "thread_times.polymer",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build140-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "thread_times.polymer",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "thread_times.polymer.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build140-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "thread_times.simple_mobile_sites",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "thread_times.simple_mobile_sites",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build150-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "thread_times.simple_mobile_sites",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "thread_times.simple_mobile_sites.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build150-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "thread_times.tough_compositor_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "thread_times.tough_compositor_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build141-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "thread_times.tough_compositor_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "thread_times.tough_compositor_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build141-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "thread_times.tough_scrolling_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "thread_times.tough_scrolling_cases",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build47-b4",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "thread_times.tough_scrolling_cases",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "thread_times.tough_scrolling_cases.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build47-b4",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "tracing.tracing_with_background_memory_infra",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "tracing.tracing_with_background_memory_infra",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build151-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "tracing.tracing_with_background_memory_infra",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "tracing.tracing_with_background_memory_infra.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build151-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "tracing.tracing_with_debug_overhead",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "tracing.tracing_with_debug_overhead",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build145-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "tracing.tracing_with_debug_overhead",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "tracing.tracing_with_debug_overhead.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build145-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
         "args": [],
         "isolate_name": "tracing_perftests",
         "name": "tracing_perftests",
@@ -681,6 +20916,689 @@
           "dimension_sets": [
             {
               "gpu": "8086:22b1",
+              "id": "build137-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.browsing_desktop",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.browsing_desktop",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build153-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.browsing_desktop",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.browsing_desktop.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build153-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.browsing_desktop_ignition",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.browsing_desktop_ignition",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build154-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.browsing_desktop_ignition",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.browsing_desktop_ignition.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build154-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.browsing_mobile",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.browsing_mobile",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build155-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.browsing_mobile",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.browsing_mobile.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build155-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.browsing_mobile_ignition",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.browsing_mobile_ignition",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build143-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.browsing_mobile_ignition",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.browsing_mobile_ignition.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build143-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.detached_context_age_in_gc",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.detached_context_age_in_gc",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build139-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.detached_context_age_in_gc",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.detached_context_age_in_gc.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build139-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.google",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.google",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build147-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.google",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.google.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build147-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.infinite_scroll-ignition_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.infinite_scroll-ignition_tbmv2",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build144-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.infinite_scroll-ignition_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.infinite_scroll-ignition_tbmv2.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build144-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.infinite_scroll_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.infinite_scroll_tbmv2",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build146-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.infinite_scroll_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.infinite_scroll_tbmv2.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build146-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.key_mobile_sites_smooth",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.key_mobile_sites_smooth",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build145-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.key_mobile_sites_smooth",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.key_mobile_sites_smooth.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build145-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.mobile_infinite_scroll_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.mobile_infinite_scroll_tbmv2",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build138-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.mobile_infinite_scroll_tbmv2",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.mobile_infinite_scroll_tbmv2.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build138-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.runtime_stats.top_25",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.runtime_stats.top_25",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build147-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.runtime_stats.top_25",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.runtime_stats.top_25.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build147-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.todomvc",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.todomvc",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build147-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.todomvc-ignition",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.todomvc-ignition",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
               "id": "build48-b4",
               "os": "Windows-10-10586",
               "pool": "Chrome-perf"
@@ -690,6 +21608,406 @@
           "hard_timeout": 7200,
           "io_timeout": 3600
         }
+      },
+      {
+        "args": [
+          "v8.todomvc-ignition",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.todomvc-ignition.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build48-b4",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.todomvc",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.todomvc.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build147-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.top_25_smooth",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.top_25_smooth",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build149-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "v8.top_25_smooth",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "v8.top_25_smooth.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build149-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "webrtc.datachannel",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.datachannel",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build149-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "webrtc.datachannel",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.datachannel.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build149-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "webrtc.getusermedia",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.getusermedia",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build141-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "webrtc.getusermedia",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.getusermedia.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build141-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "webrtc.peerconnection",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.peerconnection",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build149-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "webrtc.peerconnection",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.peerconnection.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build149-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "webrtc.stress",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.stress",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build146-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "webrtc.stress",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.stress.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build146-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "webrtc.webrtc_smoothness",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=release_x64"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.webrtc_smoothness",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build152-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
+      },
+      {
+        "args": [
+          "webrtc.webrtc_smoothness",
+          "-v",
+          "--upload-results",
+          "--output-format=chartjson",
+          "--browser=reference",
+          "--output-trace-tag=_ref"
+        ],
+        "isolate_name": "telemetry_perf_tests",
+        "name": "webrtc.webrtc_smoothness.reference",
+        "override_compile_targets": [
+          "telemetry_perf_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:22b1",
+              "id": "build152-b1",
+              "os": "Windows-10-10586",
+              "pool": "Chrome-perf"
+            }
+          ],
+          "expiration": 21600,
+          "hard_timeout": 7200,
+          "io_timeout": 3600
+        }
       }
     ]
   },
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2 b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2
index 819718f6..3c4848f 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2
@@ -2163,6 +2163,9 @@
 crbug.com/645667 compositing/clip-change.html [ Failure ]
 crbug.com/645667 compositing/layer-creation/iframe-clip-removed.html [ Failure ]
 
+# Need to write SPv2 version of this code.
+crbug.com/157218 compositing/overflow/border-radius-styles-with-composited-child.html [ Failure ]
+
 # Notes about rebaselined tests:
 #
 # Rebaselined for small pixel differences.
diff --git a/third_party/WebKit/LayoutTests/RandomOrderExpectations b/third_party/WebKit/LayoutTests/RandomOrderExpectations
index d9e8734d..cd4b977 100644
--- a/third_party/WebKit/LayoutTests/RandomOrderExpectations
+++ b/third_party/WebKit/LayoutTests/RandomOrderExpectations
@@ -20,7 +20,7 @@
 crbug.com/663849 fast/events/mouse-cursor.html [ Pass Failure ]
 crbug.com/663851 fast/events/onload-re-entry.html [ Pass Failure ]
 crbug.com/663853 fast/scroll-behavior/main-frame-interrupted-scroll.html [ Pass Failure ]
-crbug.com/671478 [ Win ] fast/table/percent-height-replaced-content-in-cell.html [ Pass Failure ]
+crbug.com/671478 fast/table/percent-height-replaced-content-in-cell.html [ Pass Failure ]
 crbug.com/663855 fast/text/ellipsis-ltr-text-in-rtl-flow-underline-composition.html [ Pass Failure ]
 crbug.com/663855 fast/text/ellipsis-rtl-text-in-ltr-flow.html [ Pass Failure ]
 crbug.com/663855 fast/text/ellipsis-rtl-text-in-rtl-flow.html [ Pass Failure ]
@@ -49,7 +49,7 @@
 crbug.com/663874 http/tests/fetch/window/thorough/redirect-password-other-https.html [ Pass Failure ]
 crbug.com/663874 http/tests/fetch/window/thorough/scheme-blob.html [ Pass Failure ]
 crbug.com/663874 http/tests/fetch/window/thorough/scheme-data-other-https.html [ Pass Failure ]
-crbug.com/671480 [ Win ] http/tests/inspector/file-system-project-mapping.html [ Pass Failure ]
+crbug.com/671480 http/tests/inspector/file-system-project-mapping.html [ Pass Failure ]
 crbug.com/663876 http/tests/loading/doc-write-sync-third-party-script-block-effectively-2g.html [ Pass Failure ]
 crbug.com/663877 http/tests/media/video-load-suspend.html [ Pass Failure ]
 crbug.com/663879 http/tests/misc/script-no-store.html [ Pass Failure ]
@@ -64,7 +64,7 @@
 crbug.com/664839 http/tests/security/link-crossorigin-preload-no-cors.html [ Pass Failure ]
 crbug.com/664839 http/tests/security/same-origin-css.html [ Pass Failure ]
 crbug.com/664839 http/tests/security/same-origin-css-in-quirks.html [ Pass Failure ]
-crbug.com/671475 [ Win ] http/tests/security/suborigins/suborigin-invalid-options.html [ Pass Failure ]
+crbug.com/671475 http/tests/security/suborigins/suborigin-invalid-options.html [ Pass Failure ]
 crbug.com/664839 http/tests/security/webgl-remote-read-remote-image-allowed.html [ Pass Failure ]
 crbug.com/664839 http/tests/security/webgl-remote-read-remote-image-allowed-with-credentials.html [ Pass Failure ]
 crbug.com/664840 http/tests/w3c/webperf/submission/Google/resource-timing/html/test_resource_script_types.html [ Pass Failure ]
@@ -88,7 +88,7 @@
 crbug.com/663874 virtual/mojo-loading/http/tests/fetch/window/thorough/redirect-password-other-https.html [ Pass Failure ]
 crbug.com/663874 virtual/mojo-loading/http/tests/fetch/window/thorough/scheme-blob.html [ Pass Failure ]
 crbug.com/663874 virtual/mojo-loading/http/tests/fetch/window/thorough/scheme-data-other-https.html [ Pass Failure ]
-crbug.com/671477 [ Win ] virtual/mojo-loading/http/tests/inspector/debugger/fetch-breakpoints.html [ Pass Failure ]
+crbug.com/671477 virtual/mojo-loading/http/tests/inspector/debugger/fetch-breakpoints.html [ Pass Failure ]
 crbug.com/663876 virtual/mojo-loading/http/tests/loading/doc-write-sync-third-party-script-block-effectively-2g.html [ Pass Failure ]
 crbug.com/663877 virtual/mojo-loading/http/tests/media/video-load-suspend.html [ Pass Failure ]
 crbug.com/663879 virtual/mojo-loading/http/tests/misc/script-no-store.html [ Pass Failure ]
@@ -108,11 +108,11 @@
 crbug.com/664840 virtual/mojo-loading/http/tests/w3c/webperf/submission/Google/resource-timing/html/test_resource_script_types.html [ Pass Failure ]
 crbug.com/664841 virtual/mojo-loading/http/tests/workers/worker-document-domain-security.html [ Pass Failure ]
 crbug.com/664841 virtual/mojo-loading/http/tests/workers/worker-performance-timeline.html [ Pass Failure ]
-crbug.com/673003 [ Win ] virtual/spinvalidation/paint/invalidation/svg/marker-viewBox-changes.svg [ Pass Failure ]
-crbug.com/673003 [ Win ] virtual/spinvalidation/paint/invalidation/outline-clip-change.html [ Pass Failure ]
+crbug.com/673003 virtual/spinvalidation/paint/invalidation/svg/marker-viewBox-changes.svg [ Pass Failure ]
+crbug.com/673003 virtual/spinvalidation/paint/invalidation/outline-clip-change.html [ Pass Failure ]
 crbug.com/664843 inspector/elements/styles-4/styles-update-from-js.html [ Pass Failure ]
 crbug.com/664842 inspector-protocol/heap-profiler/heap-snapshot-with-active-dom-object.html [ Pass Failure ]
-crbug.com/672204 [ Win ] media/avtrack/video-track-selected.html [ Pass Failure ]
+crbug.com/672204 media/avtrack/video-track-selected.html [ Pass Failure ]
 crbug.com/664844 media/track/track-cue-rendering-tree-is-removed-properly.html [ Pass Failure ]
 crbug.com/664844 media/track/track-default-attribute.html [ Pass Failure ]
 crbug.com/664844 media/track/track-kind-user-preference.html [ Pass Failure ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index 66b2f82..cebc782 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -101,7 +101,6 @@
 crbug.com/645667 virtual/spinvalidation/paint/invalidation/outline-clip-change.html [ Crash Failure ]
 crbug.com/645667 virtual/spinvalidation/paint/invalidation/filter-repaint-accelerated-on-accelerated-filter.html [ Crash ]
 crbug.com/645667 virtual/spinvalidation/paint/invalidation/position-change-keeping-geometry.html [ Crash ]
-crbug.com/645667 virtual/spinvalidation/paint/invalidation/svg/marker-viewBox-changes.svg [ Crash Failure ]
 crbug.com/645667 virtual/spinvalidation/paint/invalidation/compositing/should-not-repaint-composited-descendants.html [ Crash ]
 crbug.com/645667 virtual/spinvalidation/paint/invalidation/compositing/resize-repaint.html [ Crash ]
 crbug.com/645667 virtual/spinvalidation/paint/invalidation/compositing/shrink-layer.html [ Crash ]
@@ -625,6 +624,12 @@
 crbug.com/635619 virtual/layout_ng/fast/block/float/trailing-float-with-content.html [ Skip ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/vertical-move-relayout.html [ Skip ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/width-update-after-clear.html [ Skip ]
+crbug.com/635619 virtual/layout_ng/fast/block/float/avoid-floats-when-negative-margin-top-2.html [ Skip ]
+crbug.com/635619 virtual/layout_ng/fast/block/float/avoid-floats-when-negative-margin-top-3.html [ Skip ]
+crbug.com/635619 virtual/layout_ng/fast/block/float/avoid-floats-when-negative-margin-top-4.html [ Skip ]
+crbug.com/635619 virtual/layout_ng/fast/block/float/avoid-floats-when-negative-margin-top-5.html [ Skip ]
+crbug.com/635619 virtual/layout_ng/fast/block/float/avoid-floats-when-negative-margin-top-6.html [ Skip ]
+crbug.com/635619 virtual/layout_ng/fast/block/float/avoid-floats-when-negative-margin-top.html [ Skip ]
 # ====== LayoutNG-only failures until here ======
 
 # Requires ServiceWorkerNavigationPreload feature enabled. Run under
@@ -1639,34 +1644,6 @@
 
 crbug.com/610464 [ Linux Win7 Debug ] inspector/components/throttler.html [ Failure Pass ]
 
-# TODO(jlebel): Remove when methods are implemented.
-crbug.com/624019 [ Mac ] bluetooth/characteristic/notifications/add-multiple-event-listeners.html [ Skip ]
-crbug.com/624019 [ Mac ] bluetooth/characteristic/notifications/concurrent-stops.html [ Skip ]
-crbug.com/624019 [ Mac ] bluetooth/characteristic/notifications/event-after-starting.html [ Skip ]
-crbug.com/624019 [ Mac ] bluetooth/characteristic/notifications/gc-with-pending-stop.html [ Skip ]
-crbug.com/624019 [ Mac ] bluetooth/characteristic/notifications/parallel-start-stop.html [ Skip ]
-crbug.com/624019 [ Mac ] bluetooth/characteristic/notifications/start-before-stop-resolves.html [ Skip ]
-crbug.com/624019 [ Mac ] bluetooth/characteristic/notifications/start-stop-start-stop.html [ Skip ]
-crbug.com/624019 [ Mac ] bluetooth/characteristic/notifications/start-succeeds.html [ Skip ]
-crbug.com/624019 [ Mac ] bluetooth/characteristic/notifications/stop-after-start-succeeds.html [ Skip ]
-crbug.com/624019 [ Mac ] bluetooth/characteristic/notifications/stop-twice.html [ Skip ]
-crbug.com/624019 [ Mac ] bluetooth/characteristic/notifications/stop-without-starting.html [ Skip ]
-crbug.com/624019 [ Mac ] bluetooth/characteristic/stopNotifications/gen-gatt-op-device-disconnects-before.html [ Skip ]
-crbug.com/624019 [ Mac ] bluetooth/characteristic/stopNotifications/device-reconnects-during-success.html [ Skip ]
-crbug.com/624019 [ Mac ] bluetooth/characteristic/stopNotifications/reconnect-during-success.html [ Skip ]
-crbug.com/624019 [ Mac ] bluetooth/characteristic/stopNotifications/gen-gatt-op-device-disconnects-during-success.html [ Skip ]
-crbug.com/624019 [ Mac ] bluetooth/characteristic/stopNotifications/gen-gatt-op-disconnect-called-during-success.html [ Skip ]
-crbug.com/624019 [ Mac ] bluetooth/characteristic/stopNotifications/gen-gatt-op-disconnect-called-before.html [ Skip ]
-crbug.com/624019 [ Mac ] bluetooth/characteristic/stopNotifications/gen-gatt-op-garbage-collection-ran-during-success.html [ Skip ]
-crbug.com/624019 [ Mac ] bluetooth/service/getCharacteristics/gen-device-disconnects-invalidates-objects.html [ Skip ]
-crbug.com/624019 [ Mac ] bluetooth/service/getCharacteristics/gen-disconnect-invalidates-objects-with-uuid.html [ Skip ]
-crbug.com/624019 [ Mac ] bluetooth/service/getCharacteristic/gen-device-disconnects-invalidates-objects.html [ Skip ]
-crbug.com/624019 [ Mac ] bluetooth/service/getCharacteristics/gen-disconnect-invalidates-objects.html [ Skip ]
-crbug.com/624019 [ Mac ] bluetooth/service/getCharacteristics/gen-device-disconnects-invalidates-objects-with-uuid.html [ Skip ]
-crbug.com/624019 [ Mac ] bluetooth/service/getCharacteristic/gen-disconnect-invalidates-objects.html [ Skip ]
-
-
-
 crbug.com/487344 paint/invalidation/video-paint-invalidation.html [ Failure ]
 crbug.com/487344 virtual/spinvalidation/paint/invalidation/video-paint-invalidation.html [ Skip ]
 crbug.com/487344 [ Win ] compositing/video/video-controls-layer-creation.html [ Pass Failure ]
@@ -1889,8 +1866,6 @@
 
 crbug.com/660295 inspector/elements/elements-panel-restore-selection-when-node-comes-later.html [ Pass Failure ]
 
-crbug.com/657968 storage/indexeddb/idbdatabase-createObjectStore-exception-order.html [ Pass Failure ]
-crbug.com/657968 storage/indexeddb/idbdatabase-deleteObjectStore-exception-order.html [ Pass Failure ]
 crbug.com/667236 fast/forms/select/menulist-appearance-basic.html [ NeedsRebaseline ]
 crbug.com/667236 [ Linux ] fast/forms/select/basic-selects.html [ NeedsRebaseline ]
 crbug.com/667236 [ Linux ] fast/forms/select/select-autofilled.html [ NeedsRebaseline ]
@@ -2262,3 +2237,9 @@
 # Added 2016-12-12
 crbug.com/610835 http/tests/security/XFrameOptions/x-frame-options-deny-multiple-clients.html [ Failure Pass ]
 crbug.com/610835 virtual/mojo-loading/http/tests/security/XFrameOptions/x-frame-options-deny-multiple-clients.html [ Failure Pass ]
+
+# Added 2016-12-12
+crbug.com/673463 [ Linux ] fast/forms/associatedFormControls-leak-nodes.html [ Pass Failure ]
+
+# Added 2016-12-12
+crbug.com/673539 [ Linux ] css3/filters/effect-contrast-hw.html [ Pass Failure ]
diff --git a/third_party/WebKit/LayoutTests/compositing/overflow/border-radius-styles-with-composited-child-expected.png b/third_party/WebKit/LayoutTests/compositing/overflow/border-radius-styles-with-composited-child-expected.png
new file mode 100644
index 0000000..249b8d4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/compositing/overflow/border-radius-styles-with-composited-child-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/compositing/overflow/border-radius-styles-with-composited-child-expected.txt b/third_party/WebKit/LayoutTests/compositing/overflow/border-radius-styles-with-composited-child-expected.txt
new file mode 100644
index 0000000..47100f7f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/compositing/overflow/border-radius-styles-with-composited-child-expected.txt
@@ -0,0 +1,17 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutBlockFlow {HTML} at (0,0) size 800x600
+    LayoutBlockFlow {BODY} at (8,10) size 784x580
+layer at (18,10) size 108x108 clip at (22,14) size 100x100
+  LayoutBlockFlow {DIV} at (10,0) size 108x108 [bgcolor=#ADD8E6] [border: (4px solid #000000)]
+layer at (18,128) size 108x108 clip at (22,132) size 100x100
+  LayoutBlockFlow {DIV} at (10,118) size 108x108 [bgcolor=#ADD8E6] [border: (4px dashed #000000)]
+layer at (18,246) size 108x108 clip at (22,250) size 100x100
+  LayoutBlockFlow {DIV} at (10,236) size 108x108 [bgcolor=#ADD8E6] [border: (4px solid #FF00007F)]
+layer at (22,14) size 96x96
+  LayoutBlockFlow {DIV} at (4,4) size 96x96 [bgcolor=#008000]
+layer at (22,132) size 96x96
+  LayoutBlockFlow {DIV} at (4,4) size 96x96 [bgcolor=#008000]
+layer at (22,250) size 96x96
+  LayoutBlockFlow {DIV} at (4,4) size 96x96 [bgcolor=#008000]
diff --git a/third_party/WebKit/LayoutTests/compositing/overflow/border-radius-styles-with-composited-child.html b/third_party/WebKit/LayoutTests/compositing/overflow/border-radius-styles-with-composited-child.html
new file mode 100644
index 0000000..37087f0
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/compositing/overflow/border-radius-styles-with-composited-child.html
@@ -0,0 +1,41 @@
+<style>
+
+.outer {
+    border: 4px solid black;
+    width: 100px;
+    height: 100px;
+    border-radius: 40px;
+    background-color: lightblue;
+    overflow: hidden;
+    margin: 10px;
+}
+
+.inner {
+    width: 80px;
+    height: 80px;
+    background-color: green;
+    padding: .5em;
+    will-change: transform;
+}
+
+.dashed {
+    border-style: dashed;
+}
+
+.transparent {
+    border-color: rgba(255,0,0,0.5);
+}
+
+</style>
+
+<div class = "outer">
+    <div class = "inner"></div>
+</div>
+
+<div class = "outer dashed">
+    <div class = "inner"></div>
+</div>
+
+<div class = "outer transparent">
+    <div class = "inner"></div>
+</div>
diff --git a/third_party/WebKit/LayoutTests/compositing/overflow/empty-composited-child-of-border-radius-ancestor-expected.html b/third_party/WebKit/LayoutTests/compositing/overflow/empty-composited-child-of-border-radius-ancestor-expected.html
new file mode 100644
index 0000000..580191f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/compositing/overflow/empty-composited-child-of-border-radius-ancestor-expected.html
@@ -0,0 +1,14 @@
+<style>
+.outermost {
+  border: 4px solid #000;
+  border-radius: 40px;
+  width: 200px;
+  height: 200px;
+  overflow: hidden;
+}
+
+</style>
+
+<div class="outermost">
+</div>
+
diff --git a/third_party/WebKit/LayoutTests/compositing/overflow/empty-composited-child-of-border-radius-ancestor.html b/third_party/WebKit/LayoutTests/compositing/overflow/empty-composited-child-of-border-radius-ancestor.html
new file mode 100644
index 0000000..786c5ed
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/compositing/overflow/empty-composited-child-of-border-radius-ancestor.html
@@ -0,0 +1,24 @@
+<style>
+.outermost {
+  border: 4px solid #000;
+  border-radius: 40px;
+  width: 200px;
+  height: 200px;
+  overflow: hidden;
+}
+
+.inner {
+  width: 200px;
+  height: 200px;
+  position: relative;
+  left: 50px;
+  top: 50px;
+  will-change: transform;
+}
+</style>
+
+<div class="outermost">
+  <div class="inner">
+  </div>
+</div>
+
diff --git a/third_party/WebKit/LayoutTests/compositing/overflow/scrollbar-layer-placement-expected.txt b/third_party/WebKit/LayoutTests/compositing/overflow/scrollbar-layer-placement-expected.txt
index cd12323f..965e202 100644
--- a/third_party/WebKit/LayoutTests/compositing/overflow/scrollbar-layer-placement-expected.txt
+++ b/third_party/WebKit/LayoutTests/compositing/overflow/scrollbar-layer-placement-expected.txt
@@ -29,6 +29,7 @@
     {
       "name": "Scrolling Contents Layer",
       "bounds": [220, 236],
+      "contentsOpaque": true,
       "drawsContent": true
     },
     {
@@ -64,6 +65,7 @@
     {
       "name": "Scrolling Contents Layer",
       "bounds": [220, 236],
+      "contentsOpaque": true,
       "drawsContent": true
     },
     {
@@ -113,6 +115,7 @@
     {
       "name": "Scrolling Contents Layer",
       "bounds": [220, 236],
+      "contentsOpaque": true,
       "drawsContent": true
     },
     {
@@ -178,6 +181,7 @@
     {
       "name": "Scrolling Contents Layer",
       "bounds": [220, 236],
+      "contentsOpaque": true,
       "drawsContent": true
     },
     {
diff --git a/third_party/WebKit/LayoutTests/fast/block/float/avoid-floats-when-negative-margin-top-2-expected.txt b/third_party/WebKit/LayoutTests/fast/block/float/avoid-floats-when-negative-margin-top-2-expected.txt
new file mode 100644
index 0000000..9f54bd13
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/block/float/avoid-floats-when-negative-margin-top-2-expected.txt
@@ -0,0 +1,4 @@
+crbug.com/666487: There should be a green square below.
+
+
+PASS
diff --git a/third_party/WebKit/LayoutTests/fast/block/float/avoid-floats-when-negative-margin-top-2.html b/third_party/WebKit/LayoutTests/fast/block/float/avoid-floats-when-negative-margin-top-2.html
new file mode 100644
index 0000000..8042753
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/block/float/avoid-floats-when-negative-margin-top-2.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<style>
+body { margin: 0px; }
+.float { float: left; width: 50px; height: 100px; background: green;}
+.content { overflow: hidden; margin-top: -100px; width: 50px; height: 100px; background: green;}
+.container { width: 100px; background: red;}
+</style>
+<p>crbug.com/666487: There should be a green square below.</p>
+<div class="container">
+  <div class="float"></div>
+  <br clear=all>
+  <div style="width: 20px; height; 1px"></div>
+  <div class="content" data-offset-x=50></div>
+</div>
+<script src="../../../resources/check-layout.js"></script>
+<script>
+checkLayout('.content');
+</script>
diff --git a/third_party/WebKit/LayoutTests/fast/block/float/avoid-floats-when-negative-margin-top-3-expected.txt b/third_party/WebKit/LayoutTests/fast/block/float/avoid-floats-when-negative-margin-top-3-expected.txt
new file mode 100644
index 0000000..9f54bd13
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/block/float/avoid-floats-when-negative-margin-top-3-expected.txt
@@ -0,0 +1,4 @@
+crbug.com/666487: There should be a green square below.
+
+
+PASS
diff --git a/third_party/WebKit/LayoutTests/fast/block/float/avoid-floats-when-negative-margin-top-3.html b/third_party/WebKit/LayoutTests/fast/block/float/avoid-floats-when-negative-margin-top-3.html
new file mode 100644
index 0000000..0111b37
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/block/float/avoid-floats-when-negative-margin-top-3.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<style>
+body { margin: 0px; }
+.float { float: left; width: 50px; height: 100px; background: green;}
+.content { overflow: hidden; margin-top: -100px; width: 50px; height: 100px; background: green;}
+.container { width: 100px; background: red;}
+</style>
+<p>crbug.com/666487: There should be a green square below.</p>
+<div class="container">
+  <div>
+    <div class="float"></div>
+    <br clear=all>
+  </div>
+  <div style="width: 20px; height; 1px"></div>
+  <div class="content" data-offset-x=50></div>
+</div>
+<script src="../../../resources/check-layout.js"></script>
+<script>
+checkLayout('.content');
+</script>
diff --git a/third_party/WebKit/LayoutTests/fast/block/float/avoid-floats-when-negative-margin-top-4-expected.txt b/third_party/WebKit/LayoutTests/fast/block/float/avoid-floats-when-negative-margin-top-4-expected.txt
new file mode 100644
index 0000000..9f54bd13
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/block/float/avoid-floats-when-negative-margin-top-4-expected.txt
@@ -0,0 +1,4 @@
+crbug.com/666487: There should be a green square below.
+
+
+PASS
diff --git a/third_party/WebKit/LayoutTests/fast/block/float/avoid-floats-when-negative-margin-top-4.html b/third_party/WebKit/LayoutTests/fast/block/float/avoid-floats-when-negative-margin-top-4.html
new file mode 100644
index 0000000..14f119a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/block/float/avoid-floats-when-negative-margin-top-4.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<style>
+body { margin: 0px; }
+.float { float: left; width: 50px; height: 100px; background: green;}
+.content { overflow: hidden; margin-top: -100px; width: 50px; height: 100px; background: green;}
+.container { width: 100px; background: red;}
+</style>
+<p>crbug.com/666487: There should be a green square below.</p>
+<div class="container">
+  <div>
+    <div class="float"></div>
+    <br clear=all>
+  </div>
+  <div style="float:left;"></div>
+  <div class="content" data-offset-x=50></div>
+</div>
+<script src="../../../resources/check-layout.js"></script>
+<script>
+checkLayout('.content');
+</script>
diff --git a/third_party/WebKit/LayoutTests/fast/block/float/avoid-floats-when-negative-margin-top-5-expected.txt b/third_party/WebKit/LayoutTests/fast/block/float/avoid-floats-when-negative-margin-top-5-expected.txt
new file mode 100644
index 0000000..9f54bd13
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/block/float/avoid-floats-when-negative-margin-top-5-expected.txt
@@ -0,0 +1,4 @@
+crbug.com/666487: There should be a green square below.
+
+
+PASS
diff --git a/third_party/WebKit/LayoutTests/fast/block/float/avoid-floats-when-negative-margin-top-5.html b/third_party/WebKit/LayoutTests/fast/block/float/avoid-floats-when-negative-margin-top-5.html
new file mode 100644
index 0000000..9e711bd3
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/block/float/avoid-floats-when-negative-margin-top-5.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<style>
+body { margin: 0px; }
+.float { float: left; width: 50px; height: 100px; background: green;}
+.content { overflow: hidden; margin-top: -100px; width: 50px; height: 100px; background: green;}
+.container { width: 100px; background: red;}
+</style>
+<p>crbug.com/666487: There should be a green square below.</p>
+<div class="container">
+  <div>
+    <div class="float"></div>
+    <br clear=all>
+  </div>
+  <div style="position:absolute;"></div>
+  <div class="content" data-offset-x=50></div>
+</div>
+<script src="../../../resources/check-layout.js"></script>
+<script>
+checkLayout('.content');
+</script>
diff --git a/third_party/WebKit/LayoutTests/fast/block/float/avoid-floats-when-negative-margin-top-6-expected.txt b/third_party/WebKit/LayoutTests/fast/block/float/avoid-floats-when-negative-margin-top-6-expected.txt
new file mode 100644
index 0000000..9f54bd13
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/block/float/avoid-floats-when-negative-margin-top-6-expected.txt
@@ -0,0 +1,4 @@
+crbug.com/666487: There should be a green square below.
+
+
+PASS
diff --git a/third_party/WebKit/LayoutTests/fast/block/float/avoid-floats-when-negative-margin-top-6.html b/third_party/WebKit/LayoutTests/fast/block/float/avoid-floats-when-negative-margin-top-6.html
new file mode 100644
index 0000000..1c58540
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/block/float/avoid-floats-when-negative-margin-top-6.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<style>
+body { margin: 0px; }
+.float { float: left; width: 50px; height: 100px; background: green;}
+.content { overflow: hidden; margin-top: -100px; width: 50px; height: 100px; background: green;}
+.container { width: 100px; background: red;}
+</style>
+<p>crbug.com/666487: There should be a green square below.</p>
+<div class="container">
+  <div>
+    <div class="float"></div>
+    <br clear=all>
+  </div>
+  <div style="overflow:hidden;"></div>
+  <div class="content" data-offset-x=50></div>
+</div>
+<script src="../../../resources/check-layout.js"></script>
+<script>
+checkLayout('.content');
+</script>
diff --git a/third_party/WebKit/LayoutTests/fast/block/float/avoid-floats-when-negative-margin-top-expected.txt b/third_party/WebKit/LayoutTests/fast/block/float/avoid-floats-when-negative-margin-top-expected.txt
new file mode 100644
index 0000000..9f54bd13
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/block/float/avoid-floats-when-negative-margin-top-expected.txt
@@ -0,0 +1,4 @@
+crbug.com/666487: There should be a green square below.
+
+
+PASS
diff --git a/third_party/WebKit/LayoutTests/fast/block/float/avoid-floats-when-negative-margin-top.html b/third_party/WebKit/LayoutTests/fast/block/float/avoid-floats-when-negative-margin-top.html
new file mode 100644
index 0000000..2ff4b736
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/block/float/avoid-floats-when-negative-margin-top.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<style>
+body { margin: 0px; }
+.float { float: left; width: 50px; height: 100px; background: green;}
+.content { overflow: hidden; margin-top: -100px; width: 50px; height: 100px; background: green;}
+.container { width: 100px; background: red;}
+</style>
+<p>crbug.com/666487: There should be a green square below.</p>
+<div class="container">
+  <div class="float"></div>
+  <br clear=all>
+  <div></div>
+  <div class="content" data-offset-x=50></div>
+</div>
+<script src="../../../resources/check-layout.js"></script>
+<script>
+checkLayout('.content');
+</script>
diff --git a/third_party/WebKit/LayoutTests/fast/borders/border-radius-with-composited-child.html b/third_party/WebKit/LayoutTests/fast/borders/border-radius-with-composited-child.html
index 16fd438..1e8782d 100644
--- a/third_party/WebKit/LayoutTests/fast/borders/border-radius-with-composited-child.html
+++ b/third_party/WebKit/LayoutTests/fast/borders/border-radius-with-composited-child.html
@@ -1,6 +1,6 @@
 <!DOCTYPE HTML>
-<p>Below there should be a solid black circle.</p>
+<p>Below there should be a solid green circle with a black border and no red.</p>
 <br>
-<div style="position:relative; z-index:1; overflow:hidden; margin-top:100px; width:200px; height:200px; border-radius:50%; border:10px solid black; background:black;">
-    <div style="transform:translateZ(0); width:300px; height:300px; margin-left:-50px; margin-top:-50px; background:black;"></div>
+<div style="position:relative; z-index:1; overflow:hidden; margin-top:100px; width:200px; height:200px; border-radius:50%; border:10px solid black; background:red;">
+    <div style="transform:translateZ(0); width:300px; height:300px; margin-left:-50px; margin-top:-50px; background:green;"></div>
 </div>
diff --git a/third_party/WebKit/LayoutTests/fast/css/invalidation/independent-inheritance-fast-path.html b/third_party/WebKit/LayoutTests/fast/css/invalidation/independent-inheritance-fast-path.html
index d7d8dd50..f8ad807 100644
--- a/third_party/WebKit/LayoutTests/fast/css/invalidation/independent-inheritance-fast-path.html
+++ b/third_party/WebKit/LayoutTests/fast/css/invalidation/independent-inheritance-fast-path.html
@@ -18,6 +18,7 @@
     ["borderCollapse", "separate", "collapse"],
     ["emptyCells", "show", "hide"],
     ["captionSide", "left", "right"],
+    ["listStylePosition", "outside", "inside"],
 ];
 
 independent_properties.forEach(function(test_data)
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/dynamic/change-second-row-height.html b/third_party/WebKit/LayoutTests/fast/multicol/dynamic/change-second-row-height.html
new file mode 100644
index 0000000..17202ea
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/multicol/dynamic/change-second-row-height.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<p>The word "HEST" should be seen below.</p>
+<div style="position:relative; columns:2; column-gap:0; column-fill:auto; width:400px; height:40px; line-height:20px; orphans:1; widows:1;">
+    <div id="inner" style="columns:2; column-gap:0; column-fill:auto; height:80px;">
+        <div>
+            <br>
+            <br>
+            <br>
+            <br>
+            <br>
+            <span id="elm">HEST</span><br>
+        </div>
+    </div>
+</div>
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<script>
+test(() => {
+    var inner = document.getElementById("inner");
+    var elm = document.getElementById("elm");
+    assert_equals(elm.offsetLeft, 200);
+    document.body.offsetLeft;
+    inner.style.height = "72px";
+    assert_equals(elm.offsetLeft, 300);
+}, "Change inner multicol height, which only affects the second row.");
+</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/inspector-test.js b/third_party/WebKit/LayoutTests/http/tests/inspector/inspector-test.js
index 518f686..e5f92c9 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/inspector-test.js
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector/inspector-test.js
@@ -360,11 +360,15 @@
 
     function dumpNavigatorTreeElement(prefix, treeElement)
     {
-        var titleText;
-        if (treeElement.title instanceof Element)
-            titleText = treeElement.title.firstChild.textContent + " [mapped]";
-        else
-            titleText = treeElement.title;
+        var titleText = treeElement.title;
+        if (treeElement._trailingIconsElement) {
+            var iconTypes = [];
+            for (var icon = treeElement._trailingIconsElement.firstChild; icon; icon = icon.nextSibling) {
+                iconTypes.push(icon._iconType);
+            }
+            if (iconTypes.length)
+                titleText = titleText + " [" + iconTypes.join(", ") + "]";
+        }
         if (treeElement._nodeType === Sources.NavigatorView.Types.FileSystem || treeElement._nodeType === Sources.NavigatorView.Types.FileSystemFolder) {
             var hasMappedFiles = treeElement.listItemElement.classList.contains("has-mapped-files");
             if (!hasMappedFiles)
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/network/font-face-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector/network/font-face-expected.txt
index 86e95eb..a7969aa2 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/network/font-face-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector/network/font-face-expected.txt
@@ -1,8 +1,8 @@
 Tests that a used font-face is reported and an unused font-face is not reported.
 
 
-Symbol(RequestStarted): font-face.html
-Symbol(RequestFinished): font-face.html
-Symbol(RequestStarted): used.ttf
-Symbol(RequestFinished): used.ttf
+RequestStarted: font-face.html
+RequestFinished: font-face.html
+RequestStarted: used.ttf
+RequestFinished: used.ttf
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/network/font-face.html b/third_party/WebKit/LayoutTests/http/tests/inspector/network/font-face.html
index 801cb8e5..3be4b01 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/network/font-face.html
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector/network/font-face.html
@@ -9,17 +9,17 @@
 }
 
 function test() {
-    function onRequest(event)
+    function onRequest(eventType, event)
     {
         var request = event.data;
         if (request.name() === 'done') {
             InspectorTest.completeTest();
             return;
         }
-        InspectorTest.addResult(event.type.toString() + ": " + request.name());
+        InspectorTest.addResult(eventType + ": " + request.name());
     }
-    InspectorTest.networkManager.addEventListener(SDK.NetworkManager.Events.RequestStarted, onRequest);
-    InspectorTest.networkManager.addEventListener(SDK.NetworkManager.Events.RequestFinished, onRequest);
+    InspectorTest.networkManager.addEventListener(SDK.NetworkManager.Events.RequestStarted, onRequest.bind(null, "RequestStarted"));
+    InspectorTest.networkManager.addEventListener(SDK.NetworkManager.Events.RequestFinished, onRequest.bind(null, "RequestFinished"));
 
     InspectorTest.evaluateInPage("createIFrame()");
 }
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/persistence/persistence-navigator-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector/persistence/persistence-navigator-expected.txt
index 1fd994c7..4b184db6 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/persistence/persistence-navigator-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector/persistence/persistence-navigator-expected.txt
@@ -25,7 +25,7 @@
     inspector
       persistence
         resources
-          foo.js [mapped]
+          foo.js [smallicon-green-checkmark]
         persistence-navigator.html
         persistence-test.js
       debugger-test.js
@@ -33,7 +33,7 @@
       isolated-filesystem-test.js
 www
   inspector/persistence/resources
-    foo.js [mapped]
+    foo.js [smallicon-green-checkmark]
 
 Running: removeFileMapping
 top
diff --git a/third_party/WebKit/LayoutTests/inspector/elements/edit/set-outer-html-test.js b/third_party/WebKit/LayoutTests/inspector/elements/edit/set-outer-html-test.js
index 4c98f10..d552395 100644
--- a/third_party/WebKit/LayoutTests/inspector/elements/edit/set-outer-html-test.js
+++ b/third_party/WebKit/LayoutTests/inspector/elements/edit/set-outer-html-test.js
@@ -24,6 +24,8 @@
 
         for (var key in SDK.DOMModel.Events) {
             var eventName = SDK.DOMModel.Events[key];
+            if (eventName === SDK.DOMModel.Events.MarkersChanged || eventName === SDK.DOMModel.Events.DOMMutated)
+                continue;
             InspectorTest.domModel.addEventListener(eventName, InspectorTest.recordEvent.bind(InspectorTest, eventName));
         }
 
@@ -33,7 +35,7 @@
 
 InspectorTest.recordEvent = function(eventName, event)
 {
-    if (!event.data || event.type === SDK.DOMModel.Events.MarkersChanged || event.type === SDK.DOMModel.Events.DOMMutated)
+    if (!event.data)
         return;
     var node = event.data.node || event.data;
     var parent = event.data.parent;
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger-breakpoints/breakpoint-manager.js b/third_party/WebKit/LayoutTests/inspector/sources/debugger-breakpoints/breakpoint-manager.js
index 707e998..1abfd1619 100644
--- a/third_party/WebKit/LayoutTests/inspector/sources/debugger-breakpoints/breakpoint-manager.js
+++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger-breakpoints/breakpoint-manager.js
@@ -236,6 +236,8 @@
         return this._target;
     }
 
+    setBeforePausedCallback(callback) { }
+
     _targetDisposed() { }
 
     debuggerEnabled()
diff --git a/third_party/WebKit/LayoutTests/platform/android/compositing/overflow/scrollbar-layer-placement-expected.txt b/third_party/WebKit/LayoutTests/platform/android/compositing/overflow/scrollbar-layer-placement-expected.txt
deleted file mode 100644
index f817084..0000000
--- a/third_party/WebKit/LayoutTests/platform/android/compositing/overflow/scrollbar-layer-placement-expected.txt
+++ /dev/null
@@ -1,256 +0,0 @@
-{
-  "name": "Content Root Layer",
-  "bounds": [800, 600],
-  "children": [
-    {
-      "name": "LayoutView #document",
-      "bounds": [800, 600],
-      "contentsOpaque": true,
-      "drawsContent": true,
-      "children": [
-        {
-          "name": "LayoutBlockFlow (positioned) DIV class='outer A'",
-          "position": [6, 6],
-          "bounds": [340, 282],
-          "drawsContent": true,
-          "children": [
-            {
-              "name": "LayoutBlockFlow (relative positioned) DIV class='scroller'",
-              "position": [32, 32],
-              "bounds": [278, 218],
-              "shouldFlattenTransform": false,
-              "drawsContent": true,
-              "backgroundColor": "#FFFFFF",
-              "children": [
-                {
-                  "name": "Scrolling Layer",
-                  "position": [29, 29],
-                  "bounds": [220, 160],
-                  "shouldFlattenTransform": false,
-                  "children": [
-                    {
-                      "name": "Scrolling Contents Layer",
-                      "bounds": [220, 236],
-                      "drawsContent": true
-                    }
-                  ]
-                },
-                {
-                  "name": "Overflow Controls Host Layer",
-                  "position": [24, 24],
-                  "bounds": [230, 170],
-                  "children": [
-                    {
-                      "name": "Vertical Scrollbar Layer",
-                      "position": [218, 5],
-                      "bounds": [7, 160]
-                    }
-                  ]
-                }
-              ]
-            }
-          ]
-        },
-        {
-          "name": "LayoutBlockFlow (positioned) DIV class='outer B'",
-          "position": [355, 6],
-          "bounds": [340, 282],
-          "drawsContent": true,
-          "children": [
-            {
-              "name": "LayoutBlockFlow DIV class='scroller'",
-              "position": [32, 32],
-              "bounds": [278, 218],
-              "shouldFlattenTransform": false,
-              "drawsContent": true,
-              "backgroundColor": "#FFFFFF",
-              "children": [
-                {
-                  "name": "Scrolling Layer",
-                  "position": [29, 29],
-                  "bounds": [220, 160],
-                  "shouldFlattenTransform": false,
-                  "children": [
-                    {
-                      "name": "Scrolling Contents Layer",
-                      "bounds": [220, 236],
-                      "drawsContent": true
-                    }
-                  ]
-                }
-              ]
-            },
-            {
-              "name": "LayoutBlockFlow (relative positioned) DIV class='content'",
-              "position": [73, 73],
-              "bounds": [196, 212],
-              "contentsOpaque": true,
-              "drawsContent": true,
-              "backgroundColor": "#DDDDDD"
-            },
-            {
-              "name": "Overflow Controls Host Layer",
-              "position": [56, 56],
-              "bounds": [230, 170],
-              "children": [
-                {
-                  "name": "Vertical Scrollbar Layer",
-                  "position": [218, 5],
-                  "bounds": [7, 160]
-                }
-              ]
-            }
-          ]
-        },
-        {
-          "name": "LayoutBlockFlow (positioned) DIV class='outer C'",
-          "position": [6, 297],
-          "bounds": [340, 282],
-          "drawsContent": true,
-          "children": [
-            {
-              "name": "Ancestor Clipping Layer",
-              "position": [40, 40],
-              "bounds": [260, 100],
-              "shouldFlattenTransform": false,
-              "children": [
-                {
-                  "name": "LayoutBlockFlow DIV class='scroller'",
-                  "position": [-9, -9],
-                  "bounds": [278, 218],
-                  "shouldFlattenTransform": false,
-                  "drawsContent": true,
-                  "backgroundColor": "#FFFFFF",
-                  "children": [
-                    {
-                      "name": "Scrolling Layer",
-                      "position": [29, 29],
-                      "bounds": [220, 160],
-                      "shouldFlattenTransform": false,
-                      "children": [
-                        {
-                          "name": "Scrolling Contents Layer",
-                          "bounds": [220, 236],
-                          "drawsContent": true
-                        }
-                      ]
-                    }
-                  ]
-                }
-              ]
-            },
-            {
-              "name": "LayoutBlockFlow (relative positioned) DIV class='content'",
-              "position": [72, 72],
-              "bounds": [196, 212],
-              "contentsOpaque": true,
-              "drawsContent": true,
-              "backgroundColor": "#DDDDDD"
-            },
-            {
-              "name": "Overflow Controls Ancestor Clipping Layer",
-              "position": [40, 40],
-              "bounds": [260, 100],
-              "children": [
-                {
-                  "name": "Overflow Controls Host Layer",
-                  "position": [15, 15],
-                  "bounds": [230, 170],
-                  "children": [
-                    {
-                      "name": "Vertical Scrollbar Layer",
-                      "position": [218, 5],
-                      "bounds": [7, 160]
-                    }
-                  ]
-                }
-              ]
-            }
-          ]
-        },
-        {
-          "name": "LayoutBlockFlow (positioned) DIV class='outer D'",
-          "position": [355, 297],
-          "bounds": [340, 282],
-          "drawsContent": true,
-          "children": [
-            {
-              "name": "LayoutBlockFlow (relative positioned) DIV class='clipper'",
-              "position": [24, 24],
-              "bounds": [292, 200],
-              "drawsContent": true,
-              "children": [
-                {
-                  "name": "Child Containment Layer",
-                  "position": [10, 10],
-                  "bounds": [272, 180],
-                  "children": [
-                    {
-                      "name": "Ancestor Clipping Layer",
-                      "position": [6, 6],
-                      "bounds": [260, 100],
-                      "shouldFlattenTransform": false,
-                      "children": [
-                        {
-                          "name": "LayoutBlockFlow DIV class='scroller'",
-                          "position": [-9, -9],
-                          "bounds": [278, 218],
-                          "shouldFlattenTransform": false,
-                          "drawsContent": true,
-                          "backgroundColor": "#FFFFFF",
-                          "children": [
-                            {
-                              "name": "Scrolling Layer",
-                              "position": [29, 29],
-                              "bounds": [220, 160],
-                              "shouldFlattenTransform": false,
-                              "children": [
-                                {
-                                  "name": "Scrolling Contents Layer",
-                                  "bounds": [220, 236],
-                                  "drawsContent": true
-                                }
-                              ]
-                            }
-                          ]
-                        }
-                      ]
-                    }
-                  ]
-                }
-              ]
-            },
-            {
-              "name": "LayoutBlockFlow (relative positioned) DIV class='content'",
-              "position": [72, 72],
-              "bounds": [196, 212],
-              "contentsOpaque": true,
-              "drawsContent": true,
-              "backgroundColor": "#DDDDDD"
-            },
-            {
-              "name": "Overflow Controls Ancestor Clipping Layer",
-              "position": [40, 40],
-              "bounds": [260, 100],
-              "children": [
-                {
-                  "name": "Overflow Controls Host Layer",
-                  "position": [15, 15],
-                  "bounds": [230, 170],
-                  "children": [
-                    {
-                      "name": "Vertical Scrollbar Layer",
-                      "position": [218, 5],
-                      "bounds": [7, 160]
-                    }
-                  ]
-                }
-              ]
-            }
-          ]
-        }
-      ]
-    }
-  ]
-}
-
diff --git a/third_party/WebKit/LayoutTests/platform/android/svg/W3C-SVG-1.1-SE/coords-dom-02-f-expected.png b/third_party/WebKit/LayoutTests/platform/android/svg/W3C-SVG-1.1-SE/coords-dom-02-f-expected.png
index 54ff006c..d607997 100644
--- a/third_party/WebKit/LayoutTests/platform/android/svg/W3C-SVG-1.1-SE/coords-dom-02-f-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/android/svg/W3C-SVG-1.1-SE/coords-dom-02-f-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/android/svg/W3C-SVG-1.1-SE/coords-dom-02-f-expected.txt b/third_party/WebKit/LayoutTests/platform/android/svg/W3C-SVG-1.1-SE/coords-dom-02-f-expected.txt
index 9501ac5..ca7947be 100644
--- a/third_party/WebKit/LayoutTests/platform/android/svg/W3C-SVG-1.1-SE/coords-dom-02-f-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/android/svg/W3C-SVG-1.1-SE/coords-dom-02-f-expected.txt
@@ -1,5 +1,16 @@
 layer at (0,0) size 480x360
   LayoutView at (0,0) size 480x360
 layer at (0,0) size 480x360
-  LayoutBlockFlow {HTML} at (0,0) size 480x360
-    LayoutBlockFlow {BODY} at (8,8) size 464x344
+  LayoutSVGRoot {svg} at (0,0) size 480x360
+    LayoutSVGHiddenContainer {defs} at (0,0) size 0x0
+    LayoutSVGContainer {g} at (160,140) size 160x80
+      LayoutSVGContainer {g} at (-60,-20) size 160x80 [transform={m=((1.00,0.00)(0.00,1.00)) t=(220.00,160.00)}]
+        LayoutSVGContainer {g} at (-60,-20) size 160x80
+          LayoutSVGEllipse {circle} at (-40,-40) size 80x80 [transform={m=((2.00,0.00)(0.00,1.00)) t=(20.00,20.00)}] [fill={[type=SOLID] [color=#FF0000]}] [cx=0.00] [cy=0.00] [r=40.00]
+        LayoutSVGContainer {g} at (-40,-40) size 80x80 [transform={m=((2.00,0.00)(0.00,1.00)) t=(20.00,20.00)}]
+          LayoutSVGEllipse {circle} at (-40,-40) size 80x80 [fill={[type=SOLID] [color=#00FF00]}] [cx=0.00] [cy=0.00] [r=40.00]
+    LayoutSVGContainer {g} at (10,311) size 231x36
+      LayoutSVGText {text} at (10,311) size 231x36 contains 1 chunk(s)
+        LayoutSVGInlineText {#text} at (10,311) size 231x36
+          chunk 1 text run 1 at (10.00,340.00) startOffset 0 endOffset 16 width 231.00: "$Revision: 1.7 $"
+    LayoutSVGRect {rect} at (1,1) size 478x358 [stroke={[type=SOLID] [color=#000000]}] [x=1.00] [y=1.00] [width=478.00] [height=358.00]
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-radius-with-composited-child-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-radius-with-composited-child-expected.png
index 7659089c..615d698f 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-radius-with-composited-child-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-radius-with-composited-child-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-radius-with-composited-child-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-radius-with-composited-child-expected.txt
index 89b3ca3..fd7a43ae 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-radius-with-composited-child-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-radius-with-composited-child-expected.txt
@@ -4,11 +4,11 @@
   LayoutBlockFlow {HTML} at (0,0) size 800x400
     LayoutBlockFlow {BODY} at (8,16) size 784x376
       LayoutBlockFlow {P} at (0,0) size 784x20
-        LayoutText {#text} at (0,0) size 255x19
-          text run at (0,0) width 255: "Below there should be a solid black circle."
+        LayoutText {#text} at (0,0) size 446x19
+          text run at (0,0) width 446: "Below there should be a solid green circle with a black border and no red."
       LayoutBlockFlow (anonymous) at (0,36) size 784x20
         LayoutBR {BR} at (0,0) size 0x19
 layer at (8,172) size 220x220 clip at (18,182) size 200x200 scrollWidth 250 scrollHeight 250
-  LayoutBlockFlow (relative positioned) zI: 1 {DIV} at (0,156) size 220x220 [bgcolor=#000000] [border: (10px solid #000000)]
+  LayoutBlockFlow (relative positioned) zI: 1 {DIV} at (0,156) size 220x220 [bgcolor=#FF0000] [border: (10px solid #000000)]
 layer at (-32,132) size 300x300 backgroundClip at (18,182) size 200x200 clip at (18,182) size 200x200
-  LayoutBlockFlow {DIV} at (-40,-40) size 300x300
+  LayoutBlockFlow {DIV} at (-40,-40) size 300x300 [bgcolor=#008000]
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/clip/overflow-border-radius-composited-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/clip/overflow-border-radius-composited-expected.png
index 3121adf..b936637 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/clip/overflow-border-radius-composited-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/clip/overflow-border-radius-composited-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/prefer_compositing_to_lcd_text/compositing/overflow/scrollbar-layer-placement-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/prefer_compositing_to_lcd_text/compositing/overflow/scrollbar-layer-placement-expected.txt
deleted file mode 100644
index cd12323f..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/prefer_compositing_to_lcd_text/compositing/overflow/scrollbar-layer-placement-expected.txt
+++ /dev/null
@@ -1,208 +0,0 @@
-{
-  "layers": [
-    {
-      "name": "LayoutView #document",
-      "bounds": [800, 600],
-      "contentsOpaque": true,
-      "drawsContent": true
-    },
-    {
-      "name": "LayoutBlockFlow (positioned) DIV class='outer A'",
-      "position": [6, 6],
-      "bounds": [340, 282],
-      "drawsContent": true
-    },
-    {
-      "name": "LayoutBlockFlow (relative positioned) DIV class='scroller'",
-      "position": [32, 32],
-      "bounds": [278, 218],
-      "shouldFlattenTransform": false,
-      "drawsContent": true,
-      "backgroundColor": "#FFFFFF"
-    },
-    {
-      "name": "Scrolling Layer",
-      "position": [29, 29],
-      "bounds": [220, 160],
-      "shouldFlattenTransform": false
-    },
-    {
-      "name": "Scrolling Contents Layer",
-      "bounds": [220, 236],
-      "drawsContent": true
-    },
-    {
-      "name": "Overflow Controls Host Layer",
-      "position": [24, 24],
-      "bounds": [230, 170]
-    },
-    {
-      "name": "Vertical Scrollbar Layer",
-      "position": [218, 5],
-      "bounds": [7, 160]
-    },
-    {
-      "name": "LayoutBlockFlow (positioned) DIV class='outer B'",
-      "position": [355, 6],
-      "bounds": [340, 282],
-      "drawsContent": true
-    },
-    {
-      "name": "LayoutBlockFlow DIV class='scroller'",
-      "position": [32, 32],
-      "bounds": [278, 218],
-      "shouldFlattenTransform": false,
-      "drawsContent": true,
-      "backgroundColor": "#FFFFFF"
-    },
-    {
-      "name": "Scrolling Layer",
-      "position": [29, 29],
-      "bounds": [220, 160],
-      "shouldFlattenTransform": false
-    },
-    {
-      "name": "Scrolling Contents Layer",
-      "bounds": [220, 236],
-      "drawsContent": true
-    },
-    {
-      "name": "LayoutBlockFlow (relative positioned) DIV class='content'",
-      "position": [73, 73],
-      "bounds": [196, 212],
-      "contentsOpaque": true,
-      "drawsContent": true,
-      "backgroundColor": "#DDDDDD"
-    },
-    {
-      "name": "Overflow Controls Host Layer",
-      "position": [56, 56],
-      "bounds": [230, 170]
-    },
-    {
-      "name": "Vertical Scrollbar Layer",
-      "position": [218, 5],
-      "bounds": [7, 160]
-    },
-    {
-      "name": "LayoutBlockFlow (positioned) DIV class='outer C'",
-      "position": [6, 297],
-      "bounds": [340, 282],
-      "drawsContent": true
-    },
-    {
-      "name": "Ancestor Clipping Layer",
-      "position": [40, 40],
-      "bounds": [260, 100],
-      "shouldFlattenTransform": false
-    },
-    {
-      "name": "LayoutBlockFlow DIV class='scroller'",
-      "position": [-9, -9],
-      "bounds": [278, 218],
-      "shouldFlattenTransform": false,
-      "drawsContent": true,
-      "backgroundColor": "#FFFFFF"
-    },
-    {
-      "name": "Scrolling Layer",
-      "position": [29, 29],
-      "bounds": [220, 160],
-      "shouldFlattenTransform": false
-    },
-    {
-      "name": "Scrolling Contents Layer",
-      "bounds": [220, 236],
-      "drawsContent": true
-    },
-    {
-      "name": "LayoutBlockFlow (relative positioned) DIV class='content'",
-      "position": [72, 72],
-      "bounds": [196, 212],
-      "contentsOpaque": true,
-      "drawsContent": true,
-      "backgroundColor": "#DDDDDD"
-    },
-    {
-      "name": "Overflow Controls Ancestor Clipping Layer",
-      "position": [40, 40],
-      "bounds": [260, 100]
-    },
-    {
-      "name": "Overflow Controls Host Layer",
-      "position": [15, 15],
-      "bounds": [230, 170]
-    },
-    {
-      "name": "Vertical Scrollbar Layer",
-      "position": [218, 5],
-      "bounds": [7, 160]
-    },
-    {
-      "name": "LayoutBlockFlow (positioned) DIV class='outer D'",
-      "position": [355, 297],
-      "bounds": [340, 282],
-      "drawsContent": true
-    },
-    {
-      "name": "LayoutBlockFlow (relative positioned) DIV class='clipper'",
-      "position": [24, 24],
-      "bounds": [292, 200],
-      "drawsContent": true
-    },
-    {
-      "name": "Child Containment Layer",
-      "position": [10, 10],
-      "bounds": [272, 180]
-    },
-    {
-      "name": "Ancestor Clipping Layer",
-      "position": [6, 6],
-      "bounds": [260, 100],
-      "shouldFlattenTransform": false
-    },
-    {
-      "name": "LayoutBlockFlow DIV class='scroller'",
-      "position": [-9, -9],
-      "bounds": [278, 218],
-      "shouldFlattenTransform": false,
-      "drawsContent": true,
-      "backgroundColor": "#FFFFFF"
-    },
-    {
-      "name": "Scrolling Layer",
-      "position": [29, 29],
-      "bounds": [220, 160],
-      "shouldFlattenTransform": false
-    },
-    {
-      "name": "Scrolling Contents Layer",
-      "bounds": [220, 236],
-      "drawsContent": true
-    },
-    {
-      "name": "LayoutBlockFlow (relative positioned) DIV class='content'",
-      "position": [72, 72],
-      "bounds": [196, 212],
-      "contentsOpaque": true,
-      "drawsContent": true,
-      "backgroundColor": "#DDDDDD"
-    },
-    {
-      "name": "Overflow Controls Ancestor Clipping Layer",
-      "position": [40, 40],
-      "bounds": [260, 100]
-    },
-    {
-      "name": "Overflow Controls Host Layer",
-      "position": [15, 15],
-      "bounds": [230, 170]
-    },
-    {
-      "name": "Vertical Scrollbar Layer",
-      "position": [218, 5],
-      "bounds": [7, 160]
-    }
-  ]
-}
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/prefer_compositing_to_lcd_text/compositing/overflow/scrollbar-layer-placement-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/prefer_compositing_to_lcd_text/compositing/overflow/scrollbar-layer-placement-expected.txt
deleted file mode 100644
index cd12323f..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/prefer_compositing_to_lcd_text/compositing/overflow/scrollbar-layer-placement-expected.txt
+++ /dev/null
@@ -1,208 +0,0 @@
-{
-  "layers": [
-    {
-      "name": "LayoutView #document",
-      "bounds": [800, 600],
-      "contentsOpaque": true,
-      "drawsContent": true
-    },
-    {
-      "name": "LayoutBlockFlow (positioned) DIV class='outer A'",
-      "position": [6, 6],
-      "bounds": [340, 282],
-      "drawsContent": true
-    },
-    {
-      "name": "LayoutBlockFlow (relative positioned) DIV class='scroller'",
-      "position": [32, 32],
-      "bounds": [278, 218],
-      "shouldFlattenTransform": false,
-      "drawsContent": true,
-      "backgroundColor": "#FFFFFF"
-    },
-    {
-      "name": "Scrolling Layer",
-      "position": [29, 29],
-      "bounds": [220, 160],
-      "shouldFlattenTransform": false
-    },
-    {
-      "name": "Scrolling Contents Layer",
-      "bounds": [220, 236],
-      "drawsContent": true
-    },
-    {
-      "name": "Overflow Controls Host Layer",
-      "position": [24, 24],
-      "bounds": [230, 170]
-    },
-    {
-      "name": "Vertical Scrollbar Layer",
-      "position": [218, 5],
-      "bounds": [7, 160]
-    },
-    {
-      "name": "LayoutBlockFlow (positioned) DIV class='outer B'",
-      "position": [355, 6],
-      "bounds": [340, 282],
-      "drawsContent": true
-    },
-    {
-      "name": "LayoutBlockFlow DIV class='scroller'",
-      "position": [32, 32],
-      "bounds": [278, 218],
-      "shouldFlattenTransform": false,
-      "drawsContent": true,
-      "backgroundColor": "#FFFFFF"
-    },
-    {
-      "name": "Scrolling Layer",
-      "position": [29, 29],
-      "bounds": [220, 160],
-      "shouldFlattenTransform": false
-    },
-    {
-      "name": "Scrolling Contents Layer",
-      "bounds": [220, 236],
-      "drawsContent": true
-    },
-    {
-      "name": "LayoutBlockFlow (relative positioned) DIV class='content'",
-      "position": [73, 73],
-      "bounds": [196, 212],
-      "contentsOpaque": true,
-      "drawsContent": true,
-      "backgroundColor": "#DDDDDD"
-    },
-    {
-      "name": "Overflow Controls Host Layer",
-      "position": [56, 56],
-      "bounds": [230, 170]
-    },
-    {
-      "name": "Vertical Scrollbar Layer",
-      "position": [218, 5],
-      "bounds": [7, 160]
-    },
-    {
-      "name": "LayoutBlockFlow (positioned) DIV class='outer C'",
-      "position": [6, 297],
-      "bounds": [340, 282],
-      "drawsContent": true
-    },
-    {
-      "name": "Ancestor Clipping Layer",
-      "position": [40, 40],
-      "bounds": [260, 100],
-      "shouldFlattenTransform": false
-    },
-    {
-      "name": "LayoutBlockFlow DIV class='scroller'",
-      "position": [-9, -9],
-      "bounds": [278, 218],
-      "shouldFlattenTransform": false,
-      "drawsContent": true,
-      "backgroundColor": "#FFFFFF"
-    },
-    {
-      "name": "Scrolling Layer",
-      "position": [29, 29],
-      "bounds": [220, 160],
-      "shouldFlattenTransform": false
-    },
-    {
-      "name": "Scrolling Contents Layer",
-      "bounds": [220, 236],
-      "drawsContent": true
-    },
-    {
-      "name": "LayoutBlockFlow (relative positioned) DIV class='content'",
-      "position": [72, 72],
-      "bounds": [196, 212],
-      "contentsOpaque": true,
-      "drawsContent": true,
-      "backgroundColor": "#DDDDDD"
-    },
-    {
-      "name": "Overflow Controls Ancestor Clipping Layer",
-      "position": [40, 40],
-      "bounds": [260, 100]
-    },
-    {
-      "name": "Overflow Controls Host Layer",
-      "position": [15, 15],
-      "bounds": [230, 170]
-    },
-    {
-      "name": "Vertical Scrollbar Layer",
-      "position": [218, 5],
-      "bounds": [7, 160]
-    },
-    {
-      "name": "LayoutBlockFlow (positioned) DIV class='outer D'",
-      "position": [355, 297],
-      "bounds": [340, 282],
-      "drawsContent": true
-    },
-    {
-      "name": "LayoutBlockFlow (relative positioned) DIV class='clipper'",
-      "position": [24, 24],
-      "bounds": [292, 200],
-      "drawsContent": true
-    },
-    {
-      "name": "Child Containment Layer",
-      "position": [10, 10],
-      "bounds": [272, 180]
-    },
-    {
-      "name": "Ancestor Clipping Layer",
-      "position": [6, 6],
-      "bounds": [260, 100],
-      "shouldFlattenTransform": false
-    },
-    {
-      "name": "LayoutBlockFlow DIV class='scroller'",
-      "position": [-9, -9],
-      "bounds": [278, 218],
-      "shouldFlattenTransform": false,
-      "drawsContent": true,
-      "backgroundColor": "#FFFFFF"
-    },
-    {
-      "name": "Scrolling Layer",
-      "position": [29, 29],
-      "bounds": [220, 160],
-      "shouldFlattenTransform": false
-    },
-    {
-      "name": "Scrolling Contents Layer",
-      "bounds": [220, 236],
-      "drawsContent": true
-    },
-    {
-      "name": "LayoutBlockFlow (relative positioned) DIV class='content'",
-      "position": [72, 72],
-      "bounds": [196, 212],
-      "contentsOpaque": true,
-      "drawsContent": true,
-      "backgroundColor": "#DDDDDD"
-    },
-    {
-      "name": "Overflow Controls Ancestor Clipping Layer",
-      "position": [40, 40],
-      "bounds": [260, 100]
-    },
-    {
-      "name": "Overflow Controls Host Layer",
-      "position": [15, 15],
-      "bounds": [230, 170]
-    },
-    {
-      "name": "Vertical Scrollbar Layer",
-      "position": [218, 5],
-      "bounds": [7, 160]
-    }
-  ]
-}
-
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-radius-with-composited-child-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-radius-with-composited-child-expected.png
index 667be4d..dd51cdc 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-radius-with-composited-child-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-radius-with-composited-child-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-radius-with-composited-child-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-radius-with-composited-child-expected.txt
index 52b99ab0..981b686 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-radius-with-composited-child-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-radius-with-composited-child-expected.txt
@@ -4,11 +4,11 @@
   LayoutBlockFlow {HTML} at (0,0) size 800x396
     LayoutBlockFlow {BODY} at (8,16) size 784x372
       LayoutBlockFlow {P} at (0,0) size 784x18
-        LayoutText {#text} at (0,0) size 272x18
-          text run at (0,0) width 272: "Below there should be a solid black circle."
+        LayoutText {#text} at (0,0) size 473x18
+          text run at (0,0) width 473: "Below there should be a solid green circle with a black border and no red."
       LayoutBlockFlow (anonymous) at (0,34) size 784x18
         LayoutBR {BR} at (0,0) size 0x18
 layer at (8,168) size 220x220 clip at (18,178) size 200x200 scrollWidth 250 scrollHeight 250
-  LayoutBlockFlow (relative positioned) zI: 1 {DIV} at (0,152) size 220x220 [bgcolor=#000000] [border: (10px solid #000000)]
+  LayoutBlockFlow (relative positioned) zI: 1 {DIV} at (0,152) size 220x220 [bgcolor=#FF0000] [border: (10px solid #000000)]
 layer at (-32,128) size 300x300 backgroundClip at (18,178) size 200x200 clip at (18,178) size 200x200
-  LayoutBlockFlow {DIV} at (-40,-40) size 300x300
+  LayoutBlockFlow {DIV} at (-40,-40) size 300x300 [bgcolor=#008000]
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/clip/overflow-border-radius-composited-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/clip/overflow-border-radius-composited-expected.png
index ee32eca..4bf08438 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/clip/overflow-border-radius-composited-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/clip/overflow-border-radius-composited-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-radius-with-composited-child-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-radius-with-composited-child-expected.png
index e78d1de6..566c0b5c 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-radius-with-composited-child-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-radius-with-composited-child-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-radius-with-composited-child-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-radius-with-composited-child-expected.txt
index b9168fc1..9be3ba9 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-radius-with-composited-child-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-radius-with-composited-child-expected.txt
@@ -4,11 +4,11 @@
   LayoutBlockFlow {HTML} at (0,0) size 800x396
     LayoutBlockFlow {BODY} at (8,16) size 784x372
       LayoutBlockFlow {P} at (0,0) size 784x18
-        LayoutText {#text} at (0,0) size 272x17
-          text run at (0,0) width 272: "Below there should be a solid black circle."
+        LayoutText {#text} at (0,0) size 473x17
+          text run at (0,0) width 473: "Below there should be a solid green circle with a black border and no red."
       LayoutBlockFlow (anonymous) at (0,34) size 784x18
         LayoutBR {BR} at (0,0) size 0x17
 layer at (8,168) size 220x220 clip at (18,178) size 200x200 scrollWidth 250 scrollHeight 250
-  LayoutBlockFlow (relative positioned) zI: 1 {DIV} at (0,152) size 220x220 [bgcolor=#000000] [border: (10px solid #000000)]
+  LayoutBlockFlow (relative positioned) zI: 1 {DIV} at (0,152) size 220x220 [bgcolor=#FF0000] [border: (10px solid #000000)]
 layer at (-32,128) size 300x300 backgroundClip at (18,178) size 200x200 clip at (18,178) size 200x200
-  LayoutBlockFlow {DIV} at (-40,-40) size 300x300
+  LayoutBlockFlow {DIV} at (-40,-40) size 300x300 [bgcolor=#008000]
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/clip/overflow-border-radius-composited-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/clip/overflow-border-radius-composited-expected.png
index bf9eaea3..3c48d1f 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/clip/overflow-border-radius-composited-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/clip/overflow-border-radius-composited-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/prefer_compositing_to_lcd_text/compositing/overflow/scrollbar-layer-placement-expected.txt b/third_party/WebKit/LayoutTests/platform/win/virtual/prefer_compositing_to_lcd_text/compositing/overflow/scrollbar-layer-placement-expected.txt
deleted file mode 100644
index cd12323f..0000000
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/prefer_compositing_to_lcd_text/compositing/overflow/scrollbar-layer-placement-expected.txt
+++ /dev/null
@@ -1,208 +0,0 @@
-{
-  "layers": [
-    {
-      "name": "LayoutView #document",
-      "bounds": [800, 600],
-      "contentsOpaque": true,
-      "drawsContent": true
-    },
-    {
-      "name": "LayoutBlockFlow (positioned) DIV class='outer A'",
-      "position": [6, 6],
-      "bounds": [340, 282],
-      "drawsContent": true
-    },
-    {
-      "name": "LayoutBlockFlow (relative positioned) DIV class='scroller'",
-      "position": [32, 32],
-      "bounds": [278, 218],
-      "shouldFlattenTransform": false,
-      "drawsContent": true,
-      "backgroundColor": "#FFFFFF"
-    },
-    {
-      "name": "Scrolling Layer",
-      "position": [29, 29],
-      "bounds": [220, 160],
-      "shouldFlattenTransform": false
-    },
-    {
-      "name": "Scrolling Contents Layer",
-      "bounds": [220, 236],
-      "drawsContent": true
-    },
-    {
-      "name": "Overflow Controls Host Layer",
-      "position": [24, 24],
-      "bounds": [230, 170]
-    },
-    {
-      "name": "Vertical Scrollbar Layer",
-      "position": [218, 5],
-      "bounds": [7, 160]
-    },
-    {
-      "name": "LayoutBlockFlow (positioned) DIV class='outer B'",
-      "position": [355, 6],
-      "bounds": [340, 282],
-      "drawsContent": true
-    },
-    {
-      "name": "LayoutBlockFlow DIV class='scroller'",
-      "position": [32, 32],
-      "bounds": [278, 218],
-      "shouldFlattenTransform": false,
-      "drawsContent": true,
-      "backgroundColor": "#FFFFFF"
-    },
-    {
-      "name": "Scrolling Layer",
-      "position": [29, 29],
-      "bounds": [220, 160],
-      "shouldFlattenTransform": false
-    },
-    {
-      "name": "Scrolling Contents Layer",
-      "bounds": [220, 236],
-      "drawsContent": true
-    },
-    {
-      "name": "LayoutBlockFlow (relative positioned) DIV class='content'",
-      "position": [73, 73],
-      "bounds": [196, 212],
-      "contentsOpaque": true,
-      "drawsContent": true,
-      "backgroundColor": "#DDDDDD"
-    },
-    {
-      "name": "Overflow Controls Host Layer",
-      "position": [56, 56],
-      "bounds": [230, 170]
-    },
-    {
-      "name": "Vertical Scrollbar Layer",
-      "position": [218, 5],
-      "bounds": [7, 160]
-    },
-    {
-      "name": "LayoutBlockFlow (positioned) DIV class='outer C'",
-      "position": [6, 297],
-      "bounds": [340, 282],
-      "drawsContent": true
-    },
-    {
-      "name": "Ancestor Clipping Layer",
-      "position": [40, 40],
-      "bounds": [260, 100],
-      "shouldFlattenTransform": false
-    },
-    {
-      "name": "LayoutBlockFlow DIV class='scroller'",
-      "position": [-9, -9],
-      "bounds": [278, 218],
-      "shouldFlattenTransform": false,
-      "drawsContent": true,
-      "backgroundColor": "#FFFFFF"
-    },
-    {
-      "name": "Scrolling Layer",
-      "position": [29, 29],
-      "bounds": [220, 160],
-      "shouldFlattenTransform": false
-    },
-    {
-      "name": "Scrolling Contents Layer",
-      "bounds": [220, 236],
-      "drawsContent": true
-    },
-    {
-      "name": "LayoutBlockFlow (relative positioned) DIV class='content'",
-      "position": [72, 72],
-      "bounds": [196, 212],
-      "contentsOpaque": true,
-      "drawsContent": true,
-      "backgroundColor": "#DDDDDD"
-    },
-    {
-      "name": "Overflow Controls Ancestor Clipping Layer",
-      "position": [40, 40],
-      "bounds": [260, 100]
-    },
-    {
-      "name": "Overflow Controls Host Layer",
-      "position": [15, 15],
-      "bounds": [230, 170]
-    },
-    {
-      "name": "Vertical Scrollbar Layer",
-      "position": [218, 5],
-      "bounds": [7, 160]
-    },
-    {
-      "name": "LayoutBlockFlow (positioned) DIV class='outer D'",
-      "position": [355, 297],
-      "bounds": [340, 282],
-      "drawsContent": true
-    },
-    {
-      "name": "LayoutBlockFlow (relative positioned) DIV class='clipper'",
-      "position": [24, 24],
-      "bounds": [292, 200],
-      "drawsContent": true
-    },
-    {
-      "name": "Child Containment Layer",
-      "position": [10, 10],
-      "bounds": [272, 180]
-    },
-    {
-      "name": "Ancestor Clipping Layer",
-      "position": [6, 6],
-      "bounds": [260, 100],
-      "shouldFlattenTransform": false
-    },
-    {
-      "name": "LayoutBlockFlow DIV class='scroller'",
-      "position": [-9, -9],
-      "bounds": [278, 218],
-      "shouldFlattenTransform": false,
-      "drawsContent": true,
-      "backgroundColor": "#FFFFFF"
-    },
-    {
-      "name": "Scrolling Layer",
-      "position": [29, 29],
-      "bounds": [220, 160],
-      "shouldFlattenTransform": false
-    },
-    {
-      "name": "Scrolling Contents Layer",
-      "bounds": [220, 236],
-      "drawsContent": true
-    },
-    {
-      "name": "LayoutBlockFlow (relative positioned) DIV class='content'",
-      "position": [72, 72],
-      "bounds": [196, 212],
-      "contentsOpaque": true,
-      "drawsContent": true,
-      "backgroundColor": "#DDDDDD"
-    },
-    {
-      "name": "Overflow Controls Ancestor Clipping Layer",
-      "position": [40, 40],
-      "bounds": [260, 100]
-    },
-    {
-      "name": "Overflow Controls Host Layer",
-      "position": [15, 15],
-      "bounds": [230, 170]
-    },
-    {
-      "name": "Vertical Scrollbar Layer",
-      "position": [218, 5],
-      "bounds": [7, 160]
-    }
-  ]
-}
-
diff --git a/third_party/WebKit/LayoutTests/sensor/resources/sensor-helpers.js b/third_party/WebKit/LayoutTests/sensor/resources/sensor-helpers.js
index ff79ae5..262145f 100644
--- a/third_party/WebKit/LayoutTests/sensor/resources/sensor-helpers.js
+++ b/third_party/WebKit/LayoutTests/sensor/resources/sensor-helpers.js
@@ -244,10 +244,10 @@
       }
 
       // Returns initialized Sensor proxy to the client.
-      getSensor(type, stub) {
+      getSensor(type, request) {
         if (this.get_sensor_should_fail_) {
-          return getSensorResponse(null,
-              connection.bindProxy(null, sensor.SensorClient));
+          var ignored = new sensor.SensorClientPtr();
+          return getSensorResponse(null, bindings.makeRequest(ignored));
         }
 
         let offset =
@@ -258,6 +258,7 @@
         }
 
         if (this.active_sensor_ == null) {
+          var stub = connection.bindHandleToStub(request.handle, sensor.Sensor);
           let mockSensor = new MockSensor(stub, this.shared_buffer_handle_,
               offset, this.reading_size_in_bytes_, reporting_mode);
           this.active_sensor_ = mockSensor;
@@ -284,10 +285,11 @@
           this.resolve_func_(this.active_sensor_);
         }
 
-        var client_handle = connection.bindProxy(proxy => {
-          this.active_sensor_.client_ = proxy;
-          }, sensor.SensorClient);
-        return getSensorResponse(init_params, client_handle);
+        var client_request = new bindings.InterfaceRequest(
+            connection.bindProxy(proxy => {
+              this.active_sensor_.client_ = proxy;
+            }, sensor.SensorClient));
+        return getSensorResponse(init_params, client_request);
       }
 
       // Binds object to mojo message pipe
diff --git a/third_party/WebKit/LayoutTests/storage/indexeddb/idbdatabase-createObjectStore-exception-order.html b/third_party/WebKit/LayoutTests/storage/indexeddb/idbdatabase-createObjectStore-exception-order.html
index 5de8ed6..490019d 100644
--- a/third_party/WebKit/LayoutTests/storage/indexeddb/idbdatabase-createObjectStore-exception-order.html
+++ b/third_party/WebKit/LayoutTests/storage/indexeddb/idbdatabase-createObjectStore-exception-order.html
@@ -11,17 +11,18 @@
   (t, db, req) => {
     db.createObjectStore('s');
 
-    req.transaction.abort();
+    req.transaction.onabort = () => {
+      setTimeout(t.step_func(() => {
+        assert_throws(
+          'InvalidStateError', () => { db.createObjectStore('s2'); },
+          '"running an upgrade transaction" check (InvalidStateError) ' +
+          'should precede "not active" check (TransactionInactiveError)');
+
+        t.done();
+      }), 0);
+    };
     req.onerror = null;
-
-    setTimeout(t.step_func(() => {
-      assert_throws(
-        'InvalidStateError', () => { db.createObjectStore('s2'); },
-        '"running an upgrade transaction" check (InvalidStateError) ' +
-        'should precede "not active" check (TransactionInactiveError)');
-
-      t.done();
-    }), 0);
+    req.transaction.abort();
   },
   (t, db) => { t.assert_unreached('open should fail'); },
   'IDBDatabase.createObjectStore exception order: ' +
@@ -32,8 +33,8 @@
   (t, db, req) => {
     const store = db.createObjectStore('s');
 
-    req.transaction.abort();
     req.onerror = null;
+    req.transaction.abort();
 
     assert_throws(
       'TransactionInactiveError',
diff --git a/third_party/WebKit/LayoutTests/storage/indexeddb/idbdatabase-deleteObjectStore-exception-order.html b/third_party/WebKit/LayoutTests/storage/indexeddb/idbdatabase-deleteObjectStore-exception-order.html
index a45190c0..b411393 100644
--- a/third_party/WebKit/LayoutTests/storage/indexeddb/idbdatabase-deleteObjectStore-exception-order.html
+++ b/third_party/WebKit/LayoutTests/storage/indexeddb/idbdatabase-deleteObjectStore-exception-order.html
@@ -10,15 +10,17 @@
 indexeddb_test(
   (t, db, req) => {
     db.createObjectStore('s');
-    req.transaction.abort();
+    req.transaction.onabort = () => {
+      setTimeout(t.step_func(() => {
+        assert_throws(
+          'InvalidStateError', () => { db.deleteObjectStore('s'); },
+          '"running an upgrade transaction" check (InvalidStateError) ' +
+          'should precede "not active" check (TransactionInactiveError)');
+        t.done();
+      }), 0);
+    };
     req.onerror = null;
-    setTimeout(t.step_func(() => {
-      assert_throws(
-        'InvalidStateError', () => { db.deleteObjectStore('s'); },
-        '"running an upgrade transaction" check (InvalidStateError) ' +
-        'should precede "not active" check (TransactionInactiveError)');
-      t.done();
-    }), 0);
+    req.transaction.abort();
   },
   (t, db) => { t.assert_unreached('open should fail'); },
   'IDBDatabase.deleteObjectStore exception order: ' +
@@ -27,8 +29,8 @@
 
 indexeddb_test(
   (t, db, req) => {
-    req.transaction.abort();
     req.onerror = null;
+    req.transaction.abort();
     assert_throws(
       'TransactionInactiveError', () => { db.deleteObjectStore('nope'); },
       '"not active" check (TransactionInactiveError) should precede ' +
diff --git a/third_party/WebKit/LayoutTests/svg/transforms/text-with-transform-and-zoom-expected.html b/third_party/WebKit/LayoutTests/svg/transforms/text-with-transform-and-zoom-expected.html
new file mode 100644
index 0000000..5fc78bb
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/svg/transforms/text-with-transform-and-zoom-expected.html
@@ -0,0 +1,2 @@
+<!DOCTYPE html>
+<div style="width: 200px; height: 100px; background-color: green"></div>
diff --git a/third_party/WebKit/LayoutTests/svg/transforms/text-with-transform-and-zoom.html b/third_party/WebKit/LayoutTests/svg/transforms/text-with-transform-and-zoom.html
new file mode 100644
index 0000000..e795309
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/svg/transforms/text-with-transform-and-zoom.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<script src="../../resources/ahem.js"></script>
+<svg height="100" width="100" style="zoom: 2" fill="green" font-family="Ahem" font-size="50px">
+  <text transform="translate(-50,-40)" x="50" y="80">X</text>
+  <text style="transform: translate(-50px, -40px)" x="100" y="80">X</text>
+</svg>
diff --git a/third_party/WebKit/LayoutTests/usb/resources/usb-helpers.js b/third_party/WebKit/LayoutTests/usb/resources/usb-helpers.js
index b0687fb..455601e 100644
--- a/third_party/WebKit/LayoutTests/usb/resources/usb-helpers.js
+++ b/third_party/WebKit/LayoutTests/usb/resources/usb-helpers.js
@@ -374,18 +374,19 @@
         return Promise.resolve({ results: devices });
       }
 
-      getDevice(guid, stub) {
-        let device = this.mockDevices_.get(guid);
-        if (device === undefined) {
-          bindings.StubBindings(stub).close();
+      getDevice(guid, request) {
+        let deviceData = this.mockDevices_.get(guid);
+        if (deviceData === undefined) {
+          request.close();
         } else {
-          var mock = new MockDevice(device.info);
+          var stub = connection.bindHandleToStub(request.handle, device.Device);
+          var mock = new MockDevice(deviceData.info);
           bindings.StubBindings(stub).delegate = mock;
           bindings.StubBindings(stub).connectionErrorHandler = () => {
             if (this.deviceCloseHandler_)
-              this.deviceCloseHandler_(device.info);
+              this.deviceCloseHandler_(deviceData.info);
           };
-          device.stubs.push(stub);
+          deviceData.stubs.push(stub);
         }
       }
 
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScheduledAction.cpp b/third_party/WebKit/Source/bindings/core/v8/ScheduledAction.cpp
index aace7e2..183a6f5 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScheduledAction.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/ScheduledAction.cpp
@@ -61,17 +61,7 @@
   visitor->trace(m_code);
 }
 
-ScheduledAction::~ScheduledAction() {
-  // Verify that owning DOMTimer has eagerly disposed.
-  DCHECK(m_info.IsEmpty());
-}
-
-void ScheduledAction::dispose() {
-  m_code.dispose();
-  m_info.Clear();
-  m_function.clear();
-  m_scriptState.clear();
-}
+ScheduledAction::~ScheduledAction() {}
 
 void ScheduledAction::execute(ExecutionContext* context) {
   if (context->isDocument()) {
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScheduledAction.h b/third_party/WebKit/Source/bindings/core/v8/ScheduledAction.h
index b65d36ee..28a80e4 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScheduledAction.h
+++ b/third_party/WebKit/Source/bindings/core/v8/ScheduledAction.h
@@ -56,8 +56,6 @@
   static ScheduledAction* create(ScriptState*, const String& handler);
 
   ~ScheduledAction();
-  void dispose();
-
   DECLARE_TRACE();
 
   void execute(ExecutionContext*);
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptSourceCode.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptSourceCode.cpp
index ef9de04..9c7f78f 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScriptSourceCode.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/ScriptSourceCode.cpp
@@ -36,13 +36,6 @@
 
 ScriptSourceCode::~ScriptSourceCode() {}
 
-void ScriptSourceCode::dispose() {
-  m_source = String();
-  m_resource = nullptr;
-  m_streamer = nullptr;
-  m_url = KURL();
-}
-
 DEFINE_TRACE(ScriptSourceCode) {
   visitor->trace(m_resource);
   visitor->trace(m_streamer);
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptSourceCode.h b/third_party/WebKit/Source/bindings/core/v8/ScriptSourceCode.h
index 15651270..3af0431 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScriptSourceCode.h
+++ b/third_party/WebKit/Source/bindings/core/v8/ScriptSourceCode.h
@@ -56,7 +56,6 @@
   ScriptSourceCode(ScriptStreamer*, ScriptResource*);
 
   ~ScriptSourceCode();
-  void dispose();
   DECLARE_TRACE();
 
   bool isEmpty() const { return m_source.isEmpty(); }
@@ -66,13 +65,13 @@
   bool isNull() const { return m_source.isNull(); }
 
   const String& source() const { return m_source; }
-  ScriptResource* resource() const { return m_resource; }
+  ScriptResource* resource() const { return m_resource.get(); }
   const KURL& url() const;
   int startLine() const { return m_startPosition.m_line.oneBasedInt(); }
   const TextPosition& startPosition() const { return m_startPosition; }
   String sourceMapUrl() const;
 
-  ScriptStreamer* streamer() const { return m_streamer; }
+  ScriptStreamer* streamer() const { return m_streamer.get(); }
 
  private:
   void treatNullSourceAsEmpty();
diff --git a/third_party/WebKit/Source/bindings/scripts/code_generator_web_module.py b/third_party/WebKit/Source/bindings/scripts/code_generator_web_module.py
index 0e44aea..5868b00 100644
--- a/third_party/WebKit/Source/bindings/scripts/code_generator_web_module.py
+++ b/third_party/WebKit/Source/bindings/scripts/code_generator_web_module.py
@@ -38,46 +38,62 @@
 
 
 def interface_context(idl_interface):
-    attributes = []
-    methods = []
-    includes = set()
+    builder = InterfaceContextBuilder(MODULE_PYNAME)
+    builder.set_class_name(idl_interface.name)
+
     for idl_attribute in idl_interface.attributes:
-        attributes.append(Attribute.create(idl_attribute))
-        includes.update(includes_for_type(idl_attribute.idl_type))
+        builder.add_attribute(idl_attribute)
+
     for idl_operation in idl_interface.operations:
+        builder.add_operation(idl_operation)
+
+    return builder.build()
+
+
+class InterfaceContextBuilder(object):
+    def __init__(self, code_generator):
+        self.result = {'code_generator': code_generator}
+
+    def set_class_name(self, class_name):
+        self.result['class_name'] = class_name
+
+    def _ensure_set(self, name):
+        return self.result.setdefault(name, set())
+
+    def _ensure_list(self, name):
+        return self.result.setdefault(name, [])
+
+    def add_attribute(self, idl_attribute):
+        self._ensure_list('attributes').append(
+            self.create_attribute(idl_attribute))
+        self._ensure_set('cpp_includes').update(
+            includes_for_type(idl_attribute.idl_type))
+
+    def add_operation(self, idl_operation):
         if idl_operation.name:
-            methods.append(Method.create(idl_operation))
-    return {
-        'code_generator': MODULE_PYNAME,
-        'class_name': idl_interface.name,
-        'cpp_includes': includes,
-        'attributes': attributes,
-        'methods': methods,
-    }
+            self._ensure_list('methods').append(
+                self.create_method(idl_operation))
+            self._ensure_set('cpp_includes').update(
+                includes_for_type(idl_operation.idl_type))
 
-
-class Attribute(object):
-    def __init__(self, name, return_type):
-        self.name = name
-        self.return_type = return_type
-
-    @staticmethod
-    def create(idl_attribute):
-        name = idl_attribute.name
-        return_type = idl_attribute.idl_type.preprocessed_type.base_type
-        return Attribute(name, return_type)
-
-
-class Method(object):
-    def __init__(self, name, return_type):
-        self.name = name
-        self.return_type = return_type
-
-    @staticmethod
-    def create(idl_operation):
+    def create_method(self, idl_operation):
         name = idl_operation.name
         return_type = idl_operation.idl_type.preprocessed_type.base_type
-        return Method(name, return_type)
+        return {
+            'name': name,
+            'return_type': return_type
+        }
+
+    def create_attribute(self, idl_attribute):
+        name = idl_attribute.name
+        return_type = idl_attribute.idl_type.preprocessed_type.base_type
+        return {
+            'name': name,
+            'return_type': return_type
+        }
+
+    def build(self):
+        return self.result
 
 
 class CodeGeneratorWebModule(CodeGeneratorBase):
@@ -102,7 +118,7 @@
         # TODO(dglazkov): Implement callback interfaces.
         # TODO(dglazkov): Make sure partial interfaces are handled.
         if interface.is_callback or interface.is_partial:
-            raise ValueError("Partial or callback interfaces are not supported")
+            raise ValueError('Partial or callback interfaces are not supported')
 
         template_context = interface_context(interface)
 
diff --git a/third_party/WebKit/Source/bindings/scripts/code_generator_web_module_test.py b/third_party/WebKit/Source/bindings/scripts/code_generator_web_module_test.py
new file mode 100644
index 0000000..28c81af
--- /dev/null
+++ b/third_party/WebKit/Source/bindings/scripts/code_generator_web_module_test.py
@@ -0,0 +1,77 @@
+# 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.
+
+# pylint: disable=import-error,print-statement,relative-import
+
+"""Unit tests for code_generator_web_module.py."""
+
+import unittest
+
+from code_generator_web_module import InterfaceContextBuilder
+
+
+class IdlTestingHelper(object):
+    """A collection of stub makers and helper utils to make testing code
+    generation easy."""
+
+    def make_stub_object(self):
+        return type('', (), {})()
+
+    def add_idl_type_to_stub(self, stub, return_type):
+        stub.idl_type = self.make_stub_object()
+        stub.idl_type.preprocessed_type = self.make_stub_object()
+        stub.idl_type.preprocessed_type.base_type = return_type
+
+    def make_stub_idl_attribute(self, name, return_type):
+        idl_attribute_stub = self.make_stub_object()
+        idl_attribute_stub.name = name
+        self.add_idl_type_to_stub(idl_attribute_stub, return_type)
+        return idl_attribute_stub
+
+    def make_stub_idl_operation(self, name, return_type):
+        idl_operation_stub = self.make_stub_object()
+        idl_operation_stub.name = name
+        self.add_idl_type_to_stub(idl_operation_stub, return_type)
+        return idl_operation_stub
+
+
+class InterfaceContextBuilderTest(unittest.TestCase):
+
+    def test_empty(self):
+        builder = InterfaceContextBuilder('test')
+
+        self.assertEqual({'code_generator': 'test'}, builder.build())
+
+    def test_set_name(self):
+        builder = InterfaceContextBuilder('test')
+
+        builder.set_class_name('foo')
+        self.assertEqual({
+            'code_generator': 'test',
+            'class_name': 'foo',
+        }, builder.build())
+
+    def test_add_attribute(self):
+        helper = IdlTestingHelper()
+        builder = InterfaceContextBuilder('test')
+
+        attribute = helper.make_stub_idl_attribute('foo', 'bar')
+        builder.add_attribute(attribute)
+        self.assertEqual({
+            'code_generator': 'test',
+            'cpp_includes': set(['bar']),
+            'attributes': [{'name': 'foo', 'return_type': 'bar'}],
+        }, builder.build())
+
+    def test_add_method(self):
+        helper = IdlTestingHelper()
+        builder = InterfaceContextBuilder('test')
+
+        operation = helper.make_stub_idl_operation('foo', 'bar')
+        builder.add_operation(operation)
+        self.assertEqual({
+            'code_generator': 'test',
+            'cpp_includes': set(['bar']),
+            'methods': [{'name': 'foo', 'return_type': 'bar'}],
+        }, builder.build())
diff --git a/third_party/WebKit/Source/bindings/templates/web_module_interface.h.tmpl b/third_party/WebKit/Source/bindings/templates/web_module_interface.h.tmpl
index bf9489f..199c7b3 100644
--- a/third_party/WebKit/Source/bindings/templates/web_module_interface.h.tmpl
+++ b/third_party/WebKit/Source/bindings/templates/web_module_interface.h.tmpl
@@ -2,6 +2,24 @@
 
 {% include 'copyright_block.txt' %}
 
-// TODO(dglazkov): Implement generating the header file.
+// TODO(dglazkov): Use chromium-style path.
+#ifndef {{class_name}}_h
+#define {{class_name}}_h
 
-{% endfilter %}
\ No newline at end of file
+{% for include_file in header_includes %}
+#include "{{include_file}}"
+{% endfor %}
+
+namespace blink {
+namespace api {
+
+class {{class_name}} {
+
+};
+
+}  // namespace api
+}  // namespace blink
+
+#endif  // {{class_name}}_h
+
+{% endfilter %}
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/WebTestInterface3.cpp b/third_party/WebKit/Source/bindings/tests/results/core/WebTestInterface3.cpp
index a8675cd..f6715a41 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/WebTestInterface3.cpp
+++ b/third_party/WebKit/Source/bindings/tests/results/core/WebTestInterface3.cpp
@@ -10,6 +10,8 @@
 #include "WebTestInterface3.h"
 
 // TODO(dglazkov): Implement generating includes.
+#include "Webvoid.h"
+#include "WebIterator.h"
 #include "WebDOMString.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/WebTestInterface3.h b/third_party/WebKit/Source/bindings/tests/results/core/WebTestInterface3.h
index d998585..35de42be 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/WebTestInterface3.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/WebTestInterface3.h
@@ -7,4 +7,17 @@
 
 // clang-format off
 
-// TODO(dglazkov): Implement generating the header file.
+// TODO(dglazkov): Use chromium-style path.
+#ifndef TestInterface3_h
+#define TestInterface3_h
+
+namespace blink {
+namespace api {
+
+class TestInterface3 {
+};
+
+}  // namespace api
+}  // namespace blink
+
+#endif  // TestInterface3_h
diff --git a/third_party/WebKit/Source/build/scripts/make_computed_style_base.py b/third_party/WebKit/Source/build/scripts/make_computed_style_base.py
index 19a0e73..b88d4132 100755
--- a/third_party/WebKit/Source/build/scripts/make_computed_style_base.py
+++ b/third_party/WebKit/Source/build/scripts/make_computed_style_base.py
@@ -35,8 +35,8 @@
         self.name = kwargs.pop('name')
         # Name of property field is for
         self.property_name = kwargs.pop('property_name')
-        # Field storage type
-        self.type = kwargs.pop('type')
+        # Internal field storage type
+        self.storage_type = kwargs.pop('storage_type')
         # Bits needed for storage
         self.size = kwargs.pop('size')
         # Default value for field
@@ -112,7 +112,7 @@
                         'inherited_flag',
                         name='m_' + field_name_suffix_lower,
                         property_name=property['name'],
-                        type='bool',
+                        storage_type='bool',
                         size=1,
                         default_value='true',
                         getter_method_name=field_name_suffix_lower,
@@ -128,7 +128,7 @@
                     property_name=property['name'],
                     inherited=property['inherited'],
                     independent=property['independent'],
-                    type=type_name,
+                    storage_type=type_name,
                     size=int(math.ceil(bits_needed)),
                     default_value=default_value,
                     getter_method_name=property_name_lower,
diff --git a/third_party/WebKit/Source/build/scripts/templates/ComputedStyleBase.h.tmpl b/third_party/WebKit/Source/build/scripts/templates/ComputedStyleBase.h.tmpl
index 515603c..b7da448d 100644
--- a/third_party/WebKit/Source/build/scripts/templates/ComputedStyleBase.h.tmpl
+++ b/third_party/WebKit/Source/build/scripts/templates/ComputedStyleBase.h.tmpl
@@ -100,16 +100,16 @@
   // use resetFoo(), which can be more efficient.
   {% for field in fields %}
   // {{field.property_name}}
-  inline static {{field.type}} {{field.initial_method_name}}() { return {{field.default_value}}; }
-  {{field.type}} {{field.getter_method_name}}() const { return static_cast<{{field.type}}>({{field.name}}); }
-  void {{field.setter_method_name}}({{field.type}} v) { {{field.name}} = static_cast<unsigned>(v); }
+  inline static {{field.storage_type}} {{field.initial_method_name}}() { return {{field.default_value}}; }
+  {{field.storage_type}} {{field.getter_method_name}}() const { return static_cast<{{field.storage_type}}>({{field.name}}); }
+  void {{field.setter_method_name}}({{field.storage_type}} v) { {{field.name}} = static_cast<unsigned>(v); }
   inline void {{field.resetter_method_name}}() { {{field.name}} = {{default_value(field)}}; }
 
   {% endfor %}
  protected:
   // Storage.
   {% for field in fields %}
-  unsigned {{field.name}} : {{field.size}}; // {{field.type}}
+  unsigned {{field.name}} : {{field.size}}; // {{field.storage_type}}
   {% endfor %}
 };
 
diff --git a/third_party/WebKit/Source/core/css/CSSProperties.in b/third_party/WebKit/Source/core/css/CSSProperties.in
index f548744..5983a69 100644
--- a/third_party/WebKit/Source/core/css/CSSProperties.in
+++ b/third_party/WebKit/Source/core/css/CSSProperties.in
@@ -266,7 +266,7 @@
 lighting-color interpolable, svg, converter=convertColor
 line-height interpolable, inherited, getter=specifiedLineHeight, converter=convertLineHeight
 list-style-image interpolable, inherited, custom_value, typedom_types=[Image]
-list-style-position inherited, keyword_only, keywords=[outside|inside], initial_keyword=outside
+list-style-position inherited, independent, keyword_only, keywords=[outside|inside], initial_keyword=outside
 list-style-type inherited
 margin-bottom interpolable, initial=initialMargin, converter=convertQuirkyLength
 margin-left interpolable, initial=initialMargin, converter=convertQuirkyLength
diff --git a/third_party/WebKit/Source/core/dom/BUILD.gn b/third_party/WebKit/Source/core/dom/BUILD.gn
index 55c3620..874b587d 100644
--- a/third_party/WebKit/Source/core/dom/BUILD.gn
+++ b/third_party/WebKit/Source/core/dom/BUILD.gn
@@ -155,8 +155,6 @@
     "IgnoreDestructiveWriteCountIncrementer.h",
     "IncrementLoadEventDelayCount.cpp",
     "IncrementLoadEventDelayCount.h",
-    "IntersectionGeometry.cpp",
-    "IntersectionGeometry.h",
     "IntersectionObservation.cpp",
     "IntersectionObservation.h",
     "IntersectionObserver.cpp",
diff --git a/third_party/WebKit/Source/core/dom/Document.cpp b/third_party/WebKit/Source/core/dom/Document.cpp
index b40ae4a..80626a5 100644
--- a/third_party/WebKit/Source/core/dom/Document.cpp
+++ b/third_party/WebKit/Source/core/dom/Document.cpp
@@ -409,7 +409,9 @@
       m_evaluateMediaQueriesOnStyleRecalc(false),
       m_pendingSheetLayout(NoLayoutWithPendingSheets),
       m_frame(initializer.frame()),
-      m_domWindow(m_frame ? m_frame->localDOMWindow() : 0),
+      // TODO(dcheng): Why does this need both a LocalFrame and LocalDOMWindow
+      // pointer?
+      m_domWindow(m_frame ? m_frame->domWindow() : nullptr),
       m_importsController(this, initializer.importsController()),
       m_contextFeatures(ContextFeatures::defaultSwitch()),
       m_wellFormed(false),
@@ -499,10 +501,10 @@
     m_fetcher = m_frame->loader().documentLoader()->fetcher();
     FrameFetchContext::provideDocumentToContext(m_fetcher->context(), this);
 
+    // TODO(dcheng): Why does this need to check that DOMWindow is non-null?
     CustomElementRegistry* registry =
-        m_frame->localDOMWindow()
-            ? m_frame->localDOMWindow()->maybeCustomElements()
-            : nullptr;
+        m_frame->domWindow() ? m_frame->domWindow()->maybeCustomElements()
+                             : nullptr;
     if (registry && m_registrationContext)
       registry->entangle(m_registrationContext);
   } else if (m_importsController) {
@@ -1209,7 +1211,7 @@
   return String();
 }
 
-void Document::setReadyState(ReadyState readyState) {
+void Document::setReadyState(DocumentReadyState readyState) {
   if (readyState == m_readyState)
     return;
 
@@ -3028,11 +3030,10 @@
         DocumentLoadTiming& timing = documentLoader->timing();
         DCHECK(timing.navigationStart());
         timing.markUnloadEventStart();
-        m_frame->localDOMWindow()->dispatchEvent(unloadEvent, this);
+        m_frame->domWindow()->dispatchEvent(unloadEvent, this);
         timing.markUnloadEventEnd();
       } else {
-        m_frame->localDOMWindow()->dispatchEvent(unloadEvent,
-                                                 m_frame->document());
+        m_frame->domWindow()->dispatchEvent(unloadEvent, m_frame->document());
       }
     }
     m_loadEventProgress = UnloadEventHandled;
@@ -6374,21 +6375,11 @@
 bool Document::isSecureContext(
     String& errorMessage,
     const SecureContextCheck privilegeContextCheck) const {
-  bool isSecure = isSecureContextImpl(privilegeContextCheck);
-  if (getSandboxFlags() != SandboxNone) {
-    UseCounter::count(
-        *this, isSecure
-                   ? UseCounter::SecureContextCheckForSandboxedOriginPassed
-                   : UseCounter::SecureContextCheckForSandboxedOriginFailed);
+  if (!isSecureContext(privilegeContextCheck)) {
+    errorMessage = SecurityOrigin::isPotentiallyTrustworthyErrorMessage();
+    return false;
   }
-  UseCounter::count(*this, isSecure ? UseCounter::SecureContextCheckPassed
-                                    : UseCounter::SecureContextCheckFailed);
-
-  if (isSecure)
-    return true;
-
-  errorMessage = SecurityOrigin::isPotentiallyTrustworthyErrorMessage();
-  return false;
+  return true;
 }
 
 bool Document::isSecureContext(
diff --git a/third_party/WebKit/Source/core/dom/Document.h b/third_party/WebKit/Source/core/dom/Document.h
index 67ac81e..23c3884 100644
--- a/third_party/WebKit/Source/core/dom/Document.h
+++ b/third_party/WebKit/Source/core/dom/Document.h
@@ -674,8 +674,10 @@
   }
   bool inNoQuirksMode() const { return m_compatibilityMode == NoQuirksMode; }
 
-  enum ReadyState { Loading, Interactive, Complete };
-  void setReadyState(ReadyState);
+  // https://html.spec.whatwg.org/multipage/dom.html#documentreadystate
+  enum DocumentReadyState { Loading, Interactive, Complete };
+
+  void setReadyState(DocumentReadyState);
   bool isLoadCompleted();
 
   enum ParsingState { Parsing, InDOMContentLoaded, FinishedParsing };
@@ -1512,7 +1514,8 @@
   const Member<VisitedLinkState> m_visitedLinkState;
 
   bool m_visuallyOrdered;
-  ReadyState m_readyState;
+
+  DocumentReadyState m_readyState;
   ParsingState m_parsingState;
 
   bool m_gotoAnchorNeededAfterStylesheetsLoad;
diff --git a/third_party/WebKit/Source/core/dom/IntersectionGeometry.cpp b/third_party/WebKit/Source/core/dom/IntersectionGeometry.cpp
deleted file mode 100644
index 1956b7b6..0000000
--- a/third_party/WebKit/Source/core/dom/IntersectionGeometry.cpp
+++ /dev/null
@@ -1,241 +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/dom/IntersectionGeometry.h"
-
-#include "core/dom/Element.h"
-#include "core/dom/ElementRareData.h"
-#include "core/frame/FrameView.h"
-#include "core/frame/LocalFrame.h"
-#include "core/layout/LayoutBox.h"
-#include "core/layout/LayoutView.h"
-#include "core/layout/api/LayoutAPIShim.h"
-#include "core/layout/api/LayoutViewItem.h"
-#include "core/paint/PaintLayer.h"
-
-namespace blink {
-
-namespace {
-
-bool isContainingBlockChainDescendant(LayoutObject* descendant,
-                                      LayoutObject* ancestor) {
-  LocalFrame* ancestorFrame = ancestor->document().frame();
-  LocalFrame* descendantFrame = descendant->document().frame();
-
-  if (ancestor->isLayoutView())
-    return descendantFrame && descendantFrame->tree().top() == ancestorFrame;
-
-  if (ancestorFrame != descendantFrame)
-    return false;
-
-  while (descendant && descendant != ancestor)
-    descendant = descendant->containingBlock();
-  return descendant;
-}
-
-void mapRectUpToDocument(LayoutRect& rect,
-                         const LayoutObject& layoutObject,
-                         const Document& document) {
-  FloatQuad mappedQuad = layoutObject.localToAbsoluteQuad(
-      FloatQuad(FloatRect(rect)), UseTransforms | ApplyContainerFlip);
-  rect = LayoutRect(mappedQuad.boundingBox());
-}
-
-void mapRectDownToDocument(LayoutRect& rect,
-                           LayoutBoxModelObject& layoutObject,
-                           const Document& document) {
-  FloatQuad mappedQuad = document.layoutView()->ancestorToLocalQuad(
-      &layoutObject, FloatQuad(FloatRect(rect)),
-      UseTransforms | ApplyContainerFlip | TraverseDocumentBoundaries);
-  rect = LayoutRect(mappedQuad.boundingBox());
-}
-
-LayoutUnit computeMargin(const Length& length, LayoutUnit referenceLength) {
-  if (length.type() == Percent) {
-    return LayoutUnit(
-        static_cast<int>(referenceLength.toFloat() * length.percent() / 100.0));
-  }
-  DCHECK_EQ(length.type(), Fixed);
-  return LayoutUnit(length.intValue());
-}
-
-}  // namespace
-
-IntersectionGeometry::IntersectionGeometry(
-    Node* root,
-    Element* target,
-    const Vector<Length>& rootMargin,
-    ReportRootBounds shouldReportRootBounds)
-    : m_root(root),
-      m_target(target),
-      m_rootMargin(rootMargin),
-      m_shouldReportRootBounds(shouldReportRootBounds) {
-  DCHECK(m_target);
-  DCHECK(rootMargin.isEmpty() || rootMargin.size() == 4);
-}
-
-IntersectionGeometry::~IntersectionGeometry() {}
-
-Element* IntersectionGeometry::root() const {
-  if (m_root && !m_root->isDocumentNode())
-    return toElement(m_root);
-  return nullptr;
-}
-
-LayoutObject* IntersectionGeometry::getRootLayoutObject() const {
-  DCHECK(m_root);
-  if (m_root->isDocumentNode()) {
-    return LayoutAPIShim::layoutObjectFrom(
-        toDocument(m_root)->layoutViewItem());
-  }
-  return toElement(m_root)->layoutObject();
-}
-
-void IntersectionGeometry::initializeGeometry() {
-  initializeTargetRect();
-  m_intersectionRect = m_targetRect;
-  initializeRootRect();
-  m_doesIntersect = true;
-}
-
-void IntersectionGeometry::initializeTargetRect() {
-  LayoutObject* targetLayoutObject = m_target->layoutObject();
-  DCHECK(targetLayoutObject && targetLayoutObject->isBoxModelObject());
-  m_targetRect = LayoutRect(
-      toLayoutBoxModelObject(targetLayoutObject)->borderBoundingBox());
-}
-
-void IntersectionGeometry::initializeRootRect() {
-  LayoutObject* rootLayoutObject = getRootLayoutObject();
-  if (rootLayoutObject->isLayoutView()) {
-    m_rootRect = LayoutRect(
-        toLayoutView(rootLayoutObject)->frameView()->visibleContentRect());
-  } else if (rootLayoutObject->isBox() && rootLayoutObject->hasOverflowClip()) {
-    m_rootRect = LayoutRect(toLayoutBox(rootLayoutObject)->contentBoxRect());
-  } else {
-    m_rootRect = LayoutRect(
-        toLayoutBoxModelObject(rootLayoutObject)->borderBoundingBox());
-  }
-  applyRootMargin();
-}
-
-void IntersectionGeometry::applyRootMargin() {
-  if (m_rootMargin.isEmpty())
-    return;
-
-  // TODO(szager): Make sure the spec is clear that left/right margins are
-  // resolved against width and not height.
-  LayoutUnit topMargin = computeMargin(m_rootMargin[0], m_rootRect.height());
-  LayoutUnit rightMargin = computeMargin(m_rootMargin[1], m_rootRect.width());
-  LayoutUnit bottomMargin = computeMargin(m_rootMargin[2], m_rootRect.height());
-  LayoutUnit leftMargin = computeMargin(m_rootMargin[3], m_rootRect.width());
-
-  m_rootRect.setX(m_rootRect.x() - leftMargin);
-  m_rootRect.setWidth(m_rootRect.width() + leftMargin + rightMargin);
-  m_rootRect.setY(m_rootRect.y() - topMargin);
-  m_rootRect.setHeight(m_rootRect.height() + topMargin + bottomMargin);
-}
-
-void IntersectionGeometry::clipToRoot() {
-  // Map and clip rect into root element coordinates.
-  // TODO(szager): the writing mode flipping needs a test.
-  LayoutBox* rootLayoutObject = toLayoutBox(getRootLayoutObject());
-  LayoutObject* targetLayoutObject = m_target->layoutObject();
-
-  m_doesIntersect = targetLayoutObject->mapToVisualRectInAncestorSpace(
-      rootLayoutObject, m_intersectionRect, EdgeInclusive);
-  if (rootLayoutObject->hasOverflowClip())
-    m_intersectionRect.move(-rootLayoutObject->scrolledContentOffset());
-
-  if (!m_doesIntersect)
-    return;
-  LayoutRect rootClipRect(m_rootRect);
-  rootLayoutObject->flipForWritingMode(rootClipRect);
-  m_doesIntersect &= m_intersectionRect.inclusiveIntersect(rootClipRect);
-}
-
-void IntersectionGeometry::mapTargetRectToTargetFrameCoordinates() {
-  LayoutObject& targetLayoutObject = *m_target->layoutObject();
-  Document& targetDocument = m_target->document();
-  LayoutSize scrollPosition =
-      LayoutSize(targetDocument.view()->getScrollOffset());
-  mapRectUpToDocument(m_targetRect, targetLayoutObject, targetDocument);
-  m_targetRect.move(-scrollPosition);
-}
-
-void IntersectionGeometry::mapRootRectToRootFrameCoordinates() {
-  LayoutObject& rootLayoutObject = *getRootLayoutObject();
-  Document& rootDocument = rootLayoutObject.document();
-  LayoutSize scrollPosition =
-      LayoutSize(rootDocument.view()->getScrollOffset());
-  mapRectUpToDocument(m_rootRect, rootLayoutObject,
-                      rootLayoutObject.document());
-  m_rootRect.move(-scrollPosition);
-}
-
-void IntersectionGeometry::mapRootRectToTargetFrameCoordinates() {
-  LayoutObject& rootLayoutObject = *getRootLayoutObject();
-  Document& targetDocument = m_target->document();
-  LayoutSize scrollPosition =
-      LayoutSize(targetDocument.view()->getScrollOffset());
-
-  if (&targetDocument == &rootLayoutObject.document()) {
-    mapRectUpToDocument(m_intersectionRect, rootLayoutObject, targetDocument);
-  } else {
-    mapRectDownToDocument(m_intersectionRect,
-                          toLayoutBoxModelObject(rootLayoutObject),
-                          targetDocument);
-  }
-
-  m_intersectionRect.move(-scrollPosition);
-}
-
-void IntersectionGeometry::computeGeometry() {
-  // In the first few lines here, before initializeGeometry is called, "return
-  // true" effectively means "if the previous observed state was that root and
-  // target were intersecting, then generate a notification indicating that they
-  // are no longer intersecting."  This happens, for example, when root or
-  // target is removed from the DOM tree and not reinserted before the next
-  // frame is generated, or display:none is set on the root or target.
-  if (!m_target->isConnected())
-    return;
-  Element* rootElement = root();
-  if (rootElement && !rootElement->isConnected())
-    return;
-
-  LayoutObject* rootLayoutObject = getRootLayoutObject();
-  if (!rootLayoutObject || !rootLayoutObject->isBoxModelObject())
-    return;
-  // TODO(szager): Support SVG
-  LayoutObject* targetLayoutObject = m_target->layoutObject();
-  if (!targetLayoutObject)
-    return;
-  if (!targetLayoutObject->isBoxModelObject() && !targetLayoutObject->isText())
-    return;
-  if (!isContainingBlockChainDescendant(targetLayoutObject, rootLayoutObject))
-    return;
-
-  initializeGeometry();
-
-  clipToRoot();
-
-  mapTargetRectToTargetFrameCoordinates();
-
-  if (m_doesIntersect)
-    mapRootRectToTargetFrameCoordinates();
-  else
-    m_intersectionRect = LayoutRect();
-
-  // Small optimization: if we're not going to report root bounds, don't bother
-  // transforming them to the frame.
-  if (m_shouldReportRootBounds == ReportRootBounds::kShouldReportRootBounds)
-    mapRootRectToRootFrameCoordinates();
-}
-
-DEFINE_TRACE(IntersectionGeometry) {
-  visitor->trace(m_root);
-  visitor->trace(m_target);
-}
-
-}  // namespace blink
diff --git a/third_party/WebKit/Source/core/dom/IntersectionGeometry.h b/third_party/WebKit/Source/core/dom/IntersectionGeometry.h
deleted file mode 100644
index ba94456..0000000
--- a/third_party/WebKit/Source/core/dom/IntersectionGeometry.h
+++ /dev/null
@@ -1,73 +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 IntersectionGeometry_h
-#define IntersectionGeometry_h
-
-#include "platform/Length.h"
-#include "platform/geometry/LayoutRect.h"
-#include "platform/heap/Handle.h"
-#include "wtf/Vector.h"
-
-namespace blink {
-
-class Node;
-class Element;
-class LayoutObject;
-
-class IntersectionGeometry final
-    : public GarbageCollectedFinalized<IntersectionGeometry> {
- public:
-  enum ReportRootBounds {
-    kShouldReportRootBounds,
-    kShouldNotReportRootBounds,
-  };
-
-  IntersectionGeometry(Node* root,
-                       Element* target,
-                       const Vector<Length>& rootMargin,
-                       ReportRootBounds shouldReportRootBounds);
-  ~IntersectionGeometry();
-
-  void computeGeometry();
-  LayoutRect targetRect() const { return m_targetRect; }
-  LayoutRect intersectionRect() const { return m_intersectionRect; }
-  LayoutRect rootRect() const { return m_rootRect; }
-  bool doesIntersect() const { return m_doesIntersect; }
-
-  IntRect intersectionIntRect() const {
-    return pixelSnappedIntRect(m_intersectionRect);
-  }
-
-  IntRect targetIntRect() const { return pixelSnappedIntRect(m_targetRect); }
-
-  IntRect rootIntRect() const { return pixelSnappedIntRect(m_rootRect); }
-
-  DECLARE_TRACE();
-
- private:
-  void initializeGeometry();
-  void initializeTargetRect();
-  void initializeRootRect();
-  void clipToRoot();
-  void mapTargetRectToTargetFrameCoordinates();
-  void mapRootRectToRootFrameCoordinates();
-  void mapRootRectToTargetFrameCoordinates();
-  Element* root() const;
-  LayoutObject* getRootLayoutObject() const;
-  void applyRootMargin();
-
-  Member<Node> m_root;
-  Member<Element> m_target;
-  const Vector<Length> m_rootMargin;
-  const ReportRootBounds m_shouldReportRootBounds;
-  LayoutRect m_targetRect;
-  LayoutRect m_intersectionRect;
-  LayoutRect m_rootRect;
-  bool m_doesIntersect = false;
-};
-
-}  // namespace blink
-
-#endif  // IntersectionGeometry_h
diff --git a/third_party/WebKit/Source/core/dom/IntersectionObservation.cpp b/third_party/WebKit/Source/core/dom/IntersectionObservation.cpp
index f6d3ceaa..a179b02 100644
--- a/third_party/WebKit/Source/core/dom/IntersectionObservation.cpp
+++ b/third_party/WebKit/Source/core/dom/IntersectionObservation.cpp
@@ -6,18 +6,16 @@
 
 #include "core/dom/ElementRareData.h"
 #include "core/dom/IntersectionObserver.h"
+#include "core/layout/IntersectionGeometry.h"
 
 namespace blink {
 
-IntersectionObservation::IntersectionObservation(
-    IntersectionObserver& observer,
-    Element& target,
-    IntersectionGeometry::ReportRootBounds shouldReportRootBounds)
+IntersectionObservation::IntersectionObservation(IntersectionObserver& observer,
+                                                 Element& target,
+                                                 bool shouldReportRootBounds)
     : m_observer(observer),
       m_target(&target),
-      m_shouldReportRootBounds(
-          shouldReportRootBounds ==
-          IntersectionGeometry::ReportRootBounds::kShouldReportRootBounds),
+      m_shouldReportRootBounds(shouldReportRootBounds),
       m_lastThresholdIndex(0) {}
 
 void IntersectionObservation::computeIntersectionObservations(
@@ -29,11 +27,10 @@
   rootMargin[1] = m_observer->rightMargin();
   rootMargin[2] = m_observer->bottomMargin();
   rootMargin[3] = m_observer->leftMargin();
+  Node* rootNode = m_observer->rootNode();
   IntersectionGeometry geometry(
-      m_observer->rootNode(), target(), rootMargin,
-      m_shouldReportRootBounds
-          ? IntersectionGeometry::ReportRootBounds::kShouldReportRootBounds
-          : IntersectionGeometry::ReportRootBounds::kShouldNotReportRootBounds);
+      rootNode && !rootNode->isDocumentNode() ? toElement(rootNode) : nullptr,
+      *target(), rootMargin, m_shouldReportRootBounds);
   geometry.computeGeometry();
 
   // Some corner cases for threshold index:
diff --git a/third_party/WebKit/Source/core/dom/IntersectionObservation.h b/third_party/WebKit/Source/core/dom/IntersectionObservation.h
index 3b1ec65d..68fe7337 100644
--- a/third_party/WebKit/Source/core/dom/IntersectionObservation.h
+++ b/third_party/WebKit/Source/core/dom/IntersectionObservation.h
@@ -6,7 +6,6 @@
 #define IntersectionObservation_h
 
 #include "core/dom/DOMHighResTimeStamp.h"
-#include "core/dom/IntersectionGeometry.h"
 #include "platform/heap/Handle.h"
 
 namespace blink {
@@ -17,10 +16,9 @@
 class IntersectionObservation final
     : public GarbageCollected<IntersectionObservation> {
  public:
-  IntersectionObservation(
-      IntersectionObserver&,
-      Element&,
-      IntersectionGeometry::ReportRootBounds shouldReportRootBounds);
+  IntersectionObservation(IntersectionObserver&,
+                          Element&,
+                          bool shouldReportRootBounds);
 
   IntersectionObserver& observer() const { return *m_observer; }
   Element* target() const { return m_target; }
diff --git a/third_party/WebKit/Source/core/dom/IntersectionObserver.cpp b/third_party/WebKit/Source/core/dom/IntersectionObserver.cpp
index 09e1dc56f..bb69ebb0 100644
--- a/third_party/WebKit/Source/core/dom/IntersectionObserver.cpp
+++ b/third_party/WebKit/Source/core/dom/IntersectionObserver.cpp
@@ -270,11 +270,8 @@
     isDOMDescendant = (targetFrame->tree().top() == rootFrame);
   }
 
-  IntersectionObservation* observation = new IntersectionObservation(
-      *this, *target,
-      shouldReportRootBounds
-          ? IntersectionGeometry::ReportRootBounds::kShouldReportRootBounds
-          : IntersectionGeometry::ReportRootBounds::kShouldNotReportRootBounds);
+  IntersectionObservation* observation =
+      new IntersectionObservation(*this, *target, shouldReportRootBounds);
   target->ensureIntersectionObserverData().addObservation(*observation);
   m_observations.add(observation);
 
diff --git a/third_party/WebKit/Source/core/dom/custom/CustomElementRegistryTest.cpp b/third_party/WebKit/Source/core/dom/custom/CustomElementRegistryTest.cpp
index fbb93b6c..fc29919 100644
--- a/third_party/WebKit/Source/core/dom/custom/CustomElementRegistryTest.cpp
+++ b/third_party/WebKit/Source/core/dom/custom/CustomElementRegistryTest.cpp
@@ -35,7 +35,7 @@
   Document& document() { return m_page->document(); }
 
   CustomElementRegistry& registry() {
-    return *m_page->frame().localDOMWindow()->customElements();
+    return *m_page->frame().domWindow()->customElements();
   }
 
   ScriptState* scriptState() {
diff --git a/third_party/WebKit/Source/core/dom/custom/CustomElementTest.cpp b/third_party/WebKit/Source/core/dom/custom/CustomElementTest.cpp
index 672589a..d414e65 100644
--- a/third_party/WebKit/Source/core/dom/custom/CustomElementTest.cpp
+++ b/third_party/WebKit/Source/core/dom/custom/CustomElementTest.cpp
@@ -208,7 +208,7 @@
   // register a definition
   std::unique_ptr<DummyPageHolder> holder(DummyPageHolder::create());
   CustomElementRegistry* registry =
-      holder->frame().localDOMWindow()->customElements();
+      holder->frame().domWindow()->customElements();
   NonThrowableExceptionState shouldNotThrow;
   {
     CEReactionsScope reactions;
diff --git a/third_party/WebKit/Source/core/editing/FrameSelection.cpp b/third_party/WebKit/Source/core/editing/FrameSelection.cpp
index 6cf39773..efaf58b 100644
--- a/third_party/WebKit/Source/core/editing/FrameSelection.cpp
+++ b/third_party/WebKit/Source/core/editing/FrameSelection.cpp
@@ -276,7 +276,7 @@
   notifyAccessibilityForSelectionChange();
   notifyCompositorForSelectionChange();
   notifyEventHandlerForSelectionChange();
-  m_frame->localDOMWindow()->enqueueDocumentEvent(
+  m_frame->domWindow()->enqueueDocumentEvent(
       Event::create(EventTypeNames::selectionchange));
 }
 
diff --git a/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp b/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp
index 3450d97..e54aa91 100644
--- a/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp
+++ b/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp
@@ -103,6 +103,18 @@
   return !originB->isSameSchemeHostPort(originA.get());
 }
 
+void addRedirectsToTimingInfo(Resource* resource, ResourceTimingInfo* info) {
+  // Store redirect responses that were packed inside the final response.
+  const auto& responses = resource->response().redirectResponses();
+  for (size_t i = 0; i < responses.size(); ++i) {
+    const KURL& newURL = i + 1 < responses.size()
+                             ? KURL(responses[i + 1].url())
+                             : resource->resourceRequest().url();
+    bool crossOrigin = IsCrossOrigin(responses[i].url(), newURL);
+    info->addRedirect(responses[i], crossOrigin);
+  }
+}
+
 }  // namespace
 
 static void RecordSriResourceIntegrityMismatchEvent(
@@ -597,7 +609,6 @@
         resource->setLinkPreload(false);
       break;
   }
-
   if (!resource)
     return nullptr;
   if (resource->getType() != factory.type()) {
@@ -641,7 +652,6 @@
 
   if (!startLoad(resource))
     return nullptr;
-
   scopedResourceLoadTracker.resourceLoadContinuesBeyondScope();
 
   DCHECK(!resource->errorOccurred() ||
@@ -757,7 +767,7 @@
   return resource;
 }
 
-void ResourceFetcher::storeResourceTimingInitiatorInformation(
+void ResourceFetcher::storePerformanceTimingInitiatorInformation(
     Resource* resource) {
   const AtomicString& fetchInitiator = resource->options().initiatorInfo.name;
   if (fetchInitiator == FetchInitiatorTypeNames::internal)
@@ -771,6 +781,14 @@
                          ? resource->resourceRequest().navigationStartTime()
                          : monotonicallyIncreasingTime();
 
+  // This buffer is created and populated for providing transferSize
+  // and redirect timing opt-in information.
+  if (isMainResource) {
+    DCHECK(!m_navigationTimingInfo);
+    m_navigationTimingInfo =
+        ResourceTimingInfo::create(fetchInitiator, startTime, isMainResource);
+  }
+
   std::unique_ptr<ResourceTimingInfo> info =
       ResourceTimingInfo::create(fetchInitiator, startTime, isMainResource);
 
@@ -782,8 +800,9 @@
   }
 
   if (!isMainResource ||
-      context().updateTimingInfoForIFrameNavigation(info.get()))
+      context().updateTimingInfoForIFrameNavigation(info.get())) {
     m_resourceTimingInfoMap.add(resource, std::move(info));
+  }
 }
 
 ResourceFetcher::RevalidationPolicy
@@ -1125,6 +1144,10 @@
   return m_archive ? m_archive->mainResource() : nullptr;
 }
 
+ResourceTimingInfo* ResourceFetcher::getNavigationTimingInfo() {
+  return m_navigationTimingInfo.get();
+}
+
 void ResourceFetcher::didFinishLoading(Resource* resource,
                                        double finishTime,
                                        DidFinishLoadingReason finishReason) {
@@ -1143,18 +1166,19 @@
   DCHECK(finishReason == DidFinishFirstPartInMultipart ||
          !m_nonBlockingLoaders.contains(resource->loader()));
 
+  if (resource->getType() == Resource::MainResource) {
+    DCHECK(m_navigationTimingInfo);
+    // Store redirect responses that were packed inside the final response.
+    addRedirectsToTimingInfo(resource, m_navigationTimingInfo.get());
+    if (resource->response().isHTTP()) {
+      m_navigationTimingInfo->addFinalTransferSize(
+          encodedDataLength == -1 ? 0 : encodedDataLength);
+    }
+  }
   if (std::unique_ptr<ResourceTimingInfo> info =
           m_resourceTimingInfoMap.take(resource)) {
     // Store redirect responses that were packed inside the final response.
-    const Vector<ResourceResponse>& responses =
-        resource->response().redirectResponses();
-    for (size_t i = 0; i < responses.size(); ++i) {
-      const KURL& newURL = i + 1 < responses.size()
-                               ? KURL(responses[i + 1].url())
-                               : resource->resourceRequest().url();
-      bool crossOrigin = IsCrossOrigin(responses[i].url(), newURL);
-      info->addRedirect(responses[i], crossOrigin);
-    }
+    addRedirectsToTimingInfo(resource, info.get());
 
     if (resource->response().isHTTP() &&
         resource->response().httpStatusCode() < 400) {
@@ -1326,7 +1350,7 @@
   else
     m_nonBlockingLoaders.add(loader);
 
-  storeResourceTimingInitiatorInformation(resource);
+  storePerformanceTimingInitiatorInformation(resource);
   resource->setFetcherSecurityOrigin(sourceOrigin);
 
   loader->activateCacheAwareLoadingIfNeeded(request);
@@ -1419,6 +1443,13 @@
     bool crossOrigin = IsCrossOrigin(redirectResponse.url(), newRequest.url());
     it->value->addRedirect(redirectResponse, crossOrigin);
   }
+
+  if (resource->getType() == Resource::MainResource) {
+    DCHECK(m_navigationTimingInfo);
+    bool crossOrigin = IsCrossOrigin(redirectResponse.url(), newRequest.url());
+    m_navigationTimingInfo->addRedirect(redirectResponse, crossOrigin);
+  }
+
   newRequest.setAllowStoredCredentials(resource->options().allowCredentials ==
                                        AllowStoredCredentials);
   willSendRequest(resource->identifier(), newRequest, redirectResponse,
diff --git a/third_party/WebKit/Source/core/fetch/ResourceFetcher.h b/third_party/WebKit/Source/core/fetch/ResourceFetcher.h
index efe804a..08972762 100644
--- a/third_party/WebKit/Source/core/fetch/ResourceFetcher.h
+++ b/third_party/WebKit/Source/core/fetch/ResourceFetcher.h
@@ -152,6 +152,9 @@
 
   void reloadLoFiImages();
 
+  // Calling this method before main document resource is fetched is invalid.
+  ResourceTimingInfo* getNavigationTimingInfo();
+
   // This is only exposed for testing purposes.
   HeapListHashSet<Member<Resource>>* preloads() { return m_preloads.get(); }
 
@@ -171,7 +174,7 @@
   Resource* createResourceForLoading(FetchRequest&,
                                      const String& charset,
                                      const ResourceFactory&);
-  void storeResourceTimingInitiatorInformation(Resource*);
+  void storePerformanceTimingInitiatorInformation(Resource*);
   ResourceLoadPriority computeLoadPriority(Resource::Type,
                                            const FetchRequest&,
                                            ResourcePriority::VisibilityStatus);
@@ -237,6 +240,8 @@
       HeapHashMap<Member<Resource>, std::unique_ptr<ResourceTimingInfo>>;
   ResourceTimingInfoMap m_resourceTimingInfoMap;
 
+  std::unique_ptr<ResourceTimingInfo> m_navigationTimingInfo;
+
   Vector<std::unique_ptr<ResourceTimingInfo>> m_scheduledResourceTimingReports;
 
   HeapHashSet<Member<ResourceLoader>> m_loaders;
diff --git a/third_party/WebKit/Source/core/fetch/ResourceFetcherTest.cpp b/third_party/WebKit/Source/core/fetch/ResourceFetcherTest.cpp
index 80ff9d0..83c82de 100644
--- a/third_party/WebKit/Source/core/fetch/ResourceFetcherTest.cpp
+++ b/third_party/WebKit/Source/core/fetch/ResourceFetcherTest.cpp
@@ -144,6 +144,47 @@
   memoryCache()->remove(resource);
 }
 
+TEST_F(ResourceFetcherTest, NavigationTimingInfo) {
+  KURL url(ParsedURLString, "http://127.0.0.1:8000/foo.html");
+  ResourceResponse response;
+  response.setURL(url);
+  response.setHTTPStatusCode(200);
+
+  ResourceFetcher* fetcher = ResourceFetcher::create(
+      MockFetchContext::create(MockFetchContext::kShouldLoadNewResource));
+  ResourceRequest resourceRequest(url);
+  resourceRequest.setFrameType(WebURLRequest::FrameTypeNested);
+  resourceRequest.setRequestContext(WebURLRequest::RequestContextForm);
+  FetchRequest fetchRequest =
+      FetchRequest(resourceRequest, FetchInitiatorInfo());
+  Platform::current()->getURLLoaderMockFactory()->registerURL(
+      url, WebURLResponse(), "");
+  Resource* resource =
+      RawResource::fetchMainResource(fetchRequest, fetcher, SubstituteData());
+  resource->responseReceived(response, nullptr);
+  EXPECT_EQ(resource->getType(), Resource::MainResource);
+
+  ResourceTimingInfo* navigationTimingInfo = fetcher->getNavigationTimingInfo();
+  ASSERT_TRUE(navigationTimingInfo);
+  long long encodedDataLength = 123;
+  resource->loader()->didFinishLoading(0.0, encodedDataLength, 0);
+  EXPECT_EQ(navigationTimingInfo->transferSize(), encodedDataLength);
+
+  // When there are redirects.
+  KURL redirectURL(ParsedURLString, "http://127.0.0.1:8000/redirect.html");
+  ResourceResponse redirectResponse;
+  redirectResponse.setURL(redirectURL);
+  redirectResponse.setHTTPStatusCode(200);
+  long long redirectEncodedDataLength = 123;
+  redirectResponse.setEncodedDataLength(redirectEncodedDataLength);
+  ResourceRequest redirectResourceRequest(url);
+  fetcher->willFollowRedirect(resource, redirectResourceRequest,
+                              redirectResponse);
+  EXPECT_EQ(navigationTimingInfo->transferSize(),
+            encodedDataLength + redirectEncodedDataLength);
+  Platform::current()->getURLLoaderMockFactory()->unregisterURL(url);
+}
+
 TEST_F(ResourceFetcherTest, VaryOnBack) {
   MockFetchContext* context =
       MockFetchContext::create(MockFetchContext::kShouldLoadNewResource);
diff --git a/third_party/WebKit/Source/core/frame/DOMTimer.cpp b/third_party/WebKit/Source/core/frame/DOMTimer.cpp
index a6140804..0a4bc85 100644
--- a/third_party/WebKit/Source/core/frame/DOMTimer.cpp
+++ b/third_party/WebKit/Source/core/frame/DOMTimer.cpp
@@ -47,7 +47,7 @@
 static const double minimumInterval = 0.004;
 
 static inline bool shouldForwardUserGesture(int interval, int nestingLevel) {
-  return UserGestureIndicator::processingUserGesture() &&
+  return UserGestureIndicator::processingUserGestureThreadSafe() &&
          interval <= maxIntervalForUserGestureForwarding &&
          nestingLevel ==
              1;  // Gestures should not be forwarded to nested timers.
@@ -90,8 +90,11 @@
       m_nestingLevel(context->timers()->timerNestingLevel() + 1),
       m_action(action) {
   ASSERT(timeoutID > 0);
-  if (shouldForwardUserGesture(interval, m_nestingLevel))
+  if (shouldForwardUserGesture(interval, m_nestingLevel)) {
+    // Thread safe because shouldForwardUserGesture will only return true if
+    // execution is on the the main thread.
     m_userGestureToken = UserGestureIndicator::currentToken();
+  }
 
   InspectorInstrumentation::asyncTaskScheduled(
       context, singleShot ? "setTimeout" : "setInterval", this, !singleShot);
@@ -107,10 +110,7 @@
     startRepeating(intervalMilliseconds, BLINK_FROM_HERE);
 }
 
-DOMTimer::~DOMTimer() {
-  if (m_action)
-    m_action->dispose();
-}
+DOMTimer::~DOMTimer() {}
 
 void DOMTimer::stop() {
   InspectorInstrumentation::asyncTaskCanceled(getExecutionContext(), this);
@@ -118,8 +118,6 @@
   // Need to release JS objects potentially protected by ScheduledAction
   // because they can form circular references back to the ExecutionContext
   // which will cause a memory leak.
-  if (m_action)
-    m_action->dispose();
   m_action = nullptr;
   SuspendableTimer::stop();
 }
@@ -177,8 +175,6 @@
   executionContext->timers()->setTimerNestingLevel(0);
   // Eagerly unregister as ExecutionContext observer.
   clearContext();
-  // Eagerly clear out |action|'s resources.
-  action->dispose();
 }
 
 WebTaskRunner* DOMTimer::timerTaskRunner() const {
diff --git a/third_party/WebKit/Source/core/frame/DOMWindowProperty.cpp b/third_party/WebKit/Source/core/frame/DOMWindowProperty.cpp
index 312beaa..fef480ff 100644
--- a/third_party/WebKit/Source/core/frame/DOMWindowProperty.cpp
+++ b/third_party/WebKit/Source/core/frame/DOMWindowProperty.cpp
@@ -38,7 +38,7 @@
   if (m_frame) {
     // FIXME: Need to figure out what to do with DOMWindowProperties on
     // remote DOM windows.
-    m_frame->localDOMWindow()->registerProperty(this);
+    m_frame->domWindow()->registerProperty(this);
   }
 }
 
diff --git a/third_party/WebKit/Source/core/frame/Frame.cpp b/third_party/WebKit/Source/core/frame/Frame.cpp
index 9680704..aa43af8 100644
--- a/third_party/WebKit/Source/core/frame/Frame.cpp
+++ b/third_party/WebKit/Source/core/frame/Frame.cpp
@@ -64,6 +64,7 @@
   visitor->trace(m_treeNode);
   visitor->trace(m_host);
   visitor->trace(m_owner);
+  visitor->trace(m_domWindow);
   visitor->trace(m_client);
 }
 
diff --git a/third_party/WebKit/Source/core/frame/Frame.h b/third_party/WebKit/Source/core/frame/Frame.h
index 098c603..2abf68fc 100644
--- a/third_party/WebKit/Source/core/frame/Frame.h
+++ b/third_party/WebKit/Source/core/frame/Frame.h
@@ -74,7 +74,6 @@
   virtual bool isLocalFrame() const = 0;
   virtual bool isRemoteFrame() const = 0;
 
-  virtual DOMWindow* domWindow() const = 0;
   virtual WindowProxy* windowProxy(DOMWrapperWorld&) = 0;
 
   virtual void navigate(Document& originDocument,
@@ -107,6 +106,8 @@
   void setOwner(FrameOwner* owner) { m_owner = owner; }
   HTMLFrameOwnerElement* deprecatedLocalOwner() const;
 
+  DOMWindow* domWindow() const { return m_domWindow; }
+
   FrameTree& tree() const;
   ChromeClient& chromeClient() const;
 
@@ -153,6 +154,7 @@
 
   Member<FrameHost> m_host;
   Member<FrameOwner> m_owner;
+  Member<DOMWindow> m_domWindow;
 
   bool m_isDetaching = false;
 
diff --git a/third_party/WebKit/Source/core/frame/FrameClient.h b/third_party/WebKit/Source/core/frame/FrameClient.h
index 4af7581..6b8af79 100644
--- a/third_party/WebKit/Source/core/frame/FrameClient.h
+++ b/third_party/WebKit/Source/core/frame/FrameClient.h
@@ -35,8 +35,6 @@
 
   virtual void frameFocused() const = 0;
 
-  virtual BlameContext* frameBlameContext() { return nullptr; }
-
   virtual ~FrameClient() {}
 
   DEFINE_INLINE_VIRTUAL_TRACE() {}
diff --git a/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp b/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp
index 603823a..b3d3098 100644
--- a/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp
+++ b/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp
@@ -532,7 +532,7 @@
     if (!frames[i]->isLocalFrame())
       continue;
     toLocalFrame(frames[i].get())
-        ->localDOMWindow()
+        ->domWindow()
         ->dispatchEvent(Event::create(EventTypeNames::orientationchange));
   }
 }
diff --git a/third_party/WebKit/Source/core/frame/LocalFrame.cpp b/third_party/WebKit/Source/core/frame/LocalFrame.cpp
index eff2a0c..c5b21581 100644
--- a/third_party/WebKit/Source/core/frame/LocalFrame.cpp
+++ b/third_party/WebKit/Source/core/frame/LocalFrame.cpp
@@ -349,10 +349,6 @@
   Supplementable<LocalFrame>::trace(visitor);
 }
 
-DOMWindow* LocalFrame::domWindow() const {
-  return m_domWindow.get();
-}
-
 WindowProxy* LocalFrame::windowProxy(DOMWrapperWorld& world) {
   return m_script->windowProxy(world);
 }
@@ -429,9 +425,9 @@
   script().clearForClose();
   setView(nullptr);
 
-  m_host->eventHandlerRegistry().didRemoveAllEventHandlers(*localDOMWindow());
+  m_host->eventHandlerRegistry().didRemoveAllEventHandlers(*domWindow());
 
-  localDOMWindow()->frameDestroyed();
+  domWindow()->frameDestroyed();
 
   // TODO: Page should take care of updating focus/scrolling instead of Frame.
   // TODO: It's unclear as to why this is called more than once, but it is,
@@ -474,7 +470,7 @@
       targetFrameDescription + " from frame with URL '" +
       document()->url().getString() + "'. " + reason + "\n";
 
-  localDOMWindow()->printErrorMessage(message);
+  domWindow()->printErrorMessage(message);
 }
 
 WindowProxyManager* LocalFrame::getWindowProxyManager() const {
@@ -500,6 +496,10 @@
   inputMethodController().documentAttached(document());
 }
 
+LocalDOMWindow* LocalFrame::domWindow() const {
+  return toLocalDOMWindow(m_domWindow);
+}
+
 void LocalFrame::setDOMWindow(LocalDOMWindow* domWindow) {
   // TODO(haraken): Update this comment.
   // Oilpan: setDOMWindow() cannot be used when finalizing. Which
@@ -519,8 +519,8 @@
   if (domWindow)
     script().clearWindowProxy();
 
-  if (m_domWindow)
-    m_domWindow->reset();
+  if (this->domWindow())
+    this->domWindow()->reset();
   m_domWindow = domWindow;
 }
 
diff --git a/third_party/WebKit/Source/core/frame/LocalFrame.h b/third_party/WebKit/Source/core/frame/LocalFrame.h
index c979b7b..fb15870 100644
--- a/third_party/WebKit/Source/core/frame/LocalFrame.h
+++ b/third_party/WebKit/Source/core/frame/LocalFrame.h
@@ -106,7 +106,6 @@
   // Frame overrides:
   ~LocalFrame() override;
   DECLARE_VIRTUAL_TRACE();
-  DOMWindow* domWindow() const override;
   WindowProxy* windowProxy(DOMWrapperWorld&) override;
   void navigate(Document& originDocument,
                 const KURL&,
@@ -125,7 +124,7 @@
   void detachChildren();
   void documentAttached();
 
-  LocalDOMWindow* localDOMWindow() const;
+  LocalDOMWindow* domWindow() const;
   void setDOMWindow(LocalDOMWindow*);
   FrameView* view() const;
   Document* document() const;
@@ -249,7 +248,6 @@
   Member<NavigationScheduler> m_navigationScheduler;
 
   Member<FrameView> m_view;
-  Member<LocalDOMWindow> m_domWindow;
   // Usually 0. Non-null if this is the top frame of PagePopup.
   Member<Element> m_pagePopupOwner;
 
@@ -279,10 +277,6 @@
   m_loader.init();
 }
 
-inline LocalDOMWindow* LocalFrame::localDOMWindow() const {
-  return m_domWindow.get();
-}
-
 inline FrameLoader& LocalFrame::loader() const {
   return m_loader;
 }
diff --git a/third_party/WebKit/Source/core/frame/RemoteDOMWindow.h b/third_party/WebKit/Source/core/frame/RemoteDOMWindow.h
index 2507461..13c6538 100644
--- a/third_party/WebKit/Source/core/frame/RemoteDOMWindow.h
+++ b/third_party/WebKit/Source/core/frame/RemoteDOMWindow.h
@@ -7,6 +7,7 @@
 
 #include "core/frame/DOMWindow.h"
 #include "core/frame/RemoteFrame.h"
+#include "wtf/Assertions.h"
 
 namespace blink {
 
@@ -109,6 +110,12 @@
   Member<RemoteFrame> m_frame;
 };
 
+DEFINE_TYPE_CASTS(RemoteDOMWindow,
+                  DOMWindow,
+                  x,
+                  x->isRemoteDOMWindow(),
+                  x.isRemoteDOMWindow());
+
 }  // namespace blink
 
 #endif  // DOMWindow_h
diff --git a/third_party/WebKit/Source/core/frame/RemoteFrame.cpp b/third_party/WebKit/Source/core/frame/RemoteFrame.cpp
index 4abb8f84..730c0173 100644
--- a/third_party/WebKit/Source/core/frame/RemoteFrame.cpp
+++ b/third_party/WebKit/Source/core/frame/RemoteFrame.cpp
@@ -30,8 +30,9 @@
                                 FrameOwner* owner)
     : Frame(client, host, owner),
       m_securityContext(RemoteSecurityContext::create()),
-      m_domWindow(RemoteDOMWindow::create(*this)),
-      m_windowProxyManager(WindowProxyManager::create(*this)) {}
+      m_windowProxyManager(WindowProxyManager::create(*this)) {
+  m_domWindow = RemoteDOMWindow::create(*this);
+}
 
 RemoteFrame* RemoteFrame::create(RemoteFrameClient* client,
                                  FrameHost* host,
@@ -46,15 +47,10 @@
 DEFINE_TRACE(RemoteFrame) {
   visitor->trace(m_view);
   visitor->trace(m_securityContext);
-  visitor->trace(m_domWindow);
   visitor->trace(m_windowProxyManager);
   Frame::trace(visitor);
 }
 
-DOMWindow* RemoteFrame::domWindow() const {
-  return m_domWindow.get();
-}
-
 WindowProxy* RemoteFrame::windowProxy(DOMWrapperWorld& world) {
   WindowProxy* windowProxy = m_windowProxyManager->windowProxy(world);
   ASSERT(windowProxy);
@@ -155,7 +151,7 @@
   // persistent strong references to RemoteDOMWindow will prevent the GCing
   // of all these objects. Break the cycle by notifying of detachment.
   if (!m_view)
-    m_domWindow->frameDetached();
+    toRemoteDOMWindow(m_domWindow)->frameDetached();
 }
 
 void RemoteFrame::createView() {
diff --git a/third_party/WebKit/Source/core/frame/RemoteFrame.h b/third_party/WebKit/Source/core/frame/RemoteFrame.h
index 9d55b14..9c1c8094 100644
--- a/third_party/WebKit/Source/core/frame/RemoteFrame.h
+++ b/third_party/WebKit/Source/core/frame/RemoteFrame.h
@@ -15,7 +15,6 @@
 class Event;
 class IntRect;
 class LocalFrame;
-class RemoteDOMWindow;
 class RemoteFrameClient;
 class RemoteFrameView;
 class WebLayer;
@@ -30,7 +29,6 @@
 
   // Frame overrides:
   DECLARE_VIRTUAL_TRACE();
-  DOMWindow* domWindow() const override;
   WindowProxy* windowProxy(DOMWrapperWorld&) override;
   void navigate(Document& originDocument,
                 const KURL&,
@@ -81,7 +79,6 @@
 
   Member<RemoteFrameView> m_view;
   Member<RemoteSecurityContext> m_securityContext;
-  Member<RemoteDOMWindow> m_domWindow;
   Member<WindowProxyManager> m_windowProxyManager;
   WebLayer* m_webLayer = nullptr;
 };
diff --git a/third_party/WebKit/Source/core/html/AutoplayUmaHelper.cpp b/third_party/WebKit/Source/core/html/AutoplayUmaHelper.cpp
index 0ab3aad..bf2d6ff 100644
--- a/third_party/WebKit/Source/core/html/AutoplayUmaHelper.cpp
+++ b/third_party/WebKit/Source/core/html/AutoplayUmaHelper.cpp
@@ -210,6 +210,7 @@
 
 void AutoplayUmaHelper::handlePauseEvent() {
   maybeStopRecordingMutedVideoOffscreenDuration();
+  maybeRecordUserPausedAutoplayingCrossOriginVideo();
 }
 
 void AutoplayUmaHelper::contextDestroyed() {
@@ -299,21 +300,55 @@
   m_mutedVideoOffscreenDurationVisibilityObserver->stop();
   m_mutedVideoOffscreenDurationVisibilityObserver = nullptr;
   m_mutedVideoAutoplayOffscreenDurationMS = 0;
-  m_element->removeEventListener(EventTypeNames::pause, this, false);
+  maybeUnregisterMediaElementPauseListener();
   maybeUnregisterContextDestroyedObserver();
 }
 
+void AutoplayUmaHelper::maybeRecordUserPausedAutoplayingCrossOriginVideo() {
+  if (!shouldRecordUserPausedAutoplayingCrossOriginVideo())
+    return;
+
+  if (m_element->ended() || m_element->seeking())
+    return;
+
+  Platform::current()->recordRapporURL(
+      "Media.Autoplay.CrossOrigin.UserPausedAutoplayingVideo.ChildFrame",
+      m_element->document().url());
+  Platform::current()->recordRapporURL(
+      "Media.Autoplay.CrossOrigin.UserPausedAutoplayingVideo."
+      "TopLevelFrame",
+      m_element->document().topDocument().url());
+
+  m_hasRecordedUserPausedAutoplayingCrossOriginVideo = true;
+  maybeUnregisterMediaElementPauseListener();
+}
+
 void AutoplayUmaHelper::maybeUnregisterContextDestroyedObserver() {
   if (!shouldListenToContextDestroyed()) {
     setContext(nullptr);
   }
 }
 
+void AutoplayUmaHelper::maybeUnregisterMediaElementPauseListener() {
+  if (m_mutedVideoOffscreenDurationVisibilityObserver)
+    return;
+  if (shouldRecordUserPausedAutoplayingCrossOriginVideo())
+    return;
+  m_element->removeEventListener(EventTypeNames::pause, this, false);
+}
+
 bool AutoplayUmaHelper::shouldListenToContextDestroyed() const {
   return m_mutedVideoPlayMethodVisibilityObserver ||
          m_mutedVideoOffscreenDurationVisibilityObserver;
 }
 
+bool AutoplayUmaHelper::shouldRecordUserPausedAutoplayingCrossOriginVideo()
+    const {
+  return m_element->isInCrossOriginFrame() && m_element->isHTMLVideoElement() &&
+         m_source != AutoplaySource::NumberOfSources &&
+         !m_hasRecordedUserPausedAutoplayingCrossOriginVideo;
+}
+
 DEFINE_TRACE(AutoplayUmaHelper) {
   EventListener::trace(visitor);
   ContextLifecycleObserver::trace(visitor);
diff --git a/third_party/WebKit/Source/core/html/AutoplayUmaHelper.h b/third_party/WebKit/Source/core/html/AutoplayUmaHelper.h
index aafa273..88bd8df 100644
--- a/third_party/WebKit/Source/core/html/AutoplayUmaHelper.h
+++ b/third_party/WebKit/Source/core/html/AutoplayUmaHelper.h
@@ -86,6 +86,7 @@
   virtual void handleContextDestroyed();  // Make virtual for testing.
 
   void maybeUnregisterContextDestroyedObserver();
+  void maybeUnregisterMediaElementPauseListener();
 
   void maybeStartRecordingMutedVideoPlayMethodBecomeVisible();
   void maybeStopRecordingMutedVideoPlayMethodBecomeVisible(bool isVisible);
@@ -93,10 +94,13 @@
   void maybeStartRecordingMutedVideoOffscreenDuration();
   void maybeStopRecordingMutedVideoOffscreenDuration();
 
+  void maybeRecordUserPausedAutoplayingCrossOriginVideo();
+
   void onVisibilityChangedForMutedVideoOffscreenDuration(bool isVisibile);
   void onVisibilityChangedForMutedVideoPlayMethodBecomeVisible(bool isVisible);
 
   bool shouldListenToContextDestroyed() const;
+  bool shouldRecordUserPausedAutoplayingCrossOriginVideo() const;
 
   // The autoplay source. Use AutoplaySource::NumberOfSources for invalid
   // source.
@@ -126,6 +130,9 @@
 
   std::set<CrossOriginAutoplayResult> m_recordedCrossOriginAutoplayResults;
 
+  // Whether the UMA helper has recorded user pausing a cross-origin video.
+  bool m_hasRecordedUserPausedAutoplayingCrossOriginVideo;
+
   // The observer is used to observer an autoplaying muted video changing it's
   // visibility, which is used for offscreen duration UMA.  The UMA is pending
   // for recording as long as this observer is non-null.
diff --git a/third_party/WebKit/Source/core/html/AutoplayUmaHelperTest.cpp b/third_party/WebKit/Source/core/html/AutoplayUmaHelperTest.cpp
index 77f75ad..f5be095 100644
--- a/third_party/WebKit/Source/core/html/AutoplayUmaHelperTest.cpp
+++ b/third_party/WebKit/Source/core/html/AutoplayUmaHelperTest.cpp
@@ -45,37 +45,34 @@
     return toHTMLVideoElement(*element);
   }
 
-  MockAutoplayUmaHelper& umaHelper() {
-    return *(static_cast<MockAutoplayUmaHelper*>(
-        mediaElement().m_autoplayUmaHelper.get()));
-  }
+  MockAutoplayUmaHelper& umaHelper() { return *m_umaHelper; }
 
   std::unique_ptr<DummyPageHolder>& pageHolder() { return m_pageHolder; }
 
-  MOCK_METHOD0(TestEnded, void());
-
  private:
   void SetUp() override {
     m_pageHolder = DummyPageHolder::create(IntSize(800, 600));
     document().documentElement()->setInnerHTML("<video id=video></video>",
                                                ASSERT_NO_EXCEPTION);
     HTMLMediaElement& element = mediaElement();
-    element.m_autoplayUmaHelper = new MockAutoplayUmaHelper(&element);
+    m_umaHelper = new MockAutoplayUmaHelper(&element);
+    element.m_autoplayUmaHelper = m_umaHelper;
   }
 
+  void TearDown() override { m_umaHelper.clear(); }
+
   std::unique_ptr<DummyPageHolder> m_pageHolder;
+  Persistent<MockAutoplayUmaHelper> m_umaHelper;
 };
 
 TEST_F(AutoplayUmaHelperTest, VisibilityChangeWhenUnload) {
-  // This is to avoid handleContextDestroyed() to be called during TearDown().
-  EXPECT_CALL(*this, TestEnded())
-      .After(EXPECT_CALL(umaHelper(), handleContextDestroyed()));
+  EXPECT_CALL(umaHelper(), handleContextDestroyed());
 
   mediaElement().setMuted(true);
   umaHelper().onAutoplayInitiated(AutoplaySource::Attribute);
   umaHelper().handlePlayingEvent();
   pageHolder().reset();
-  TestEnded();
+  ::testing::Mock::VerifyAndClear(&umaHelper());
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp b/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
index 3dc61ac..6bea516 100644
--- a/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
@@ -39,7 +39,6 @@
 #include "core/dom/ElementTraversal.h"
 #include "core/dom/ElementVisibilityObserver.h"
 #include "core/dom/Fullscreen.h"
-#include "core/dom/IntersectionGeometry.h"
 #include "core/dom/TaskRunnerHelper.h"
 #include "core/dom/shadow/ShadowRoot.h"
 #include "core/events/Event.h"
@@ -66,6 +65,7 @@
 #include "core/html/track/VideoTrack.h"
 #include "core/html/track/VideoTrackList.h"
 #include "core/inspector/ConsoleMessage.h"
+#include "core/layout/IntersectionGeometry.h"
 #include "core/layout/LayoutMedia.h"
 #include "core/layout/api/LayoutViewItem.h"
 #include "core/layout/compositing/PaintLayerCompositor.h"
@@ -4069,9 +4069,9 @@
 void HTMLMediaElement::checkViewportIntersectionChanged() {
   // TODO(xjz): Early return if we not in tab mirroring.
 
-  IntersectionGeometry geometry(
-      document().frame()->localFrameRoot()->document(), this, Vector<Length>(),
-      IntersectionGeometry::ReportRootBounds::kShouldReportRootBounds);
+  bool shouldReportRootBounds = true;
+  IntersectionGeometry geometry(nullptr, *this, Vector<Length>(),
+                                shouldReportRootBounds);
   geometry.computeGeometry();
   IntRect intersectRect = geometry.intersectionIntRect();
   if (m_currentIntersectRect == intersectRect)
diff --git a/third_party/WebKit/Source/core/html/ImageDocumentTest.cpp b/third_party/WebKit/Source/core/html/ImageDocumentTest.cpp
index 9873d8db..28b344e 100644
--- a/third_party/WebKit/Source/core/html/ImageDocumentTest.cpp
+++ b/third_party/WebKit/Source/core/html/ImageDocumentTest.cpp
@@ -98,7 +98,7 @@
   LocalFrame& frame = m_dummyPageHolder->frame();
   frame.document()->shutdown();
   DocumentInit init(KURL(), &frame);
-  frame.localDOMWindow()->installNewDocument("image/jpeg", init);
+  frame.domWindow()->installNewDocument("image/jpeg", init);
 }
 
 void ImageDocumentTest::createDocument(int viewWidth, int viewHeight) {
diff --git a/third_party/WebKit/Source/core/layout/BUILD.gn b/third_party/WebKit/Source/core/layout/BUILD.gn
index fad269e2..24b609a 100644
--- a/third_party/WebKit/Source/core/layout/BUILD.gn
+++ b/third_party/WebKit/Source/core/layout/BUILD.gn
@@ -39,6 +39,8 @@
     "HitTestingTransformState.h",
     "ImageQualityController.cpp",
     "ImageQualityController.h",
+    "IntersectionGeometry.cpp",
+    "IntersectionGeometry.h",
     "LayoutAnalyzer.cpp",
     "LayoutAnalyzer.h",
     "LayoutBR.cpp",
diff --git a/third_party/WebKit/Source/core/layout/IntersectionGeometry.cpp b/third_party/WebKit/Source/core/layout/IntersectionGeometry.cpp
new file mode 100644
index 0000000..8274879
--- /dev/null
+++ b/third_party/WebKit/Source/core/layout/IntersectionGeometry.cpp
@@ -0,0 +1,215 @@
+// 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/IntersectionGeometry.h"
+
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
+#include "core/html/HTMLFrameOwnerElement.h"
+#include "core/layout/LayoutBox.h"
+#include "core/layout/LayoutView.h"
+#include "core/layout/api/LayoutAPIShim.h"
+#include "core/layout/api/LayoutViewItem.h"
+#include "core/paint/PaintLayer.h"
+
+namespace blink {
+
+namespace {
+
+bool isContainingBlockChainDescendant(LayoutObject* descendant,
+                                      LayoutObject* ancestor) {
+  LocalFrame* ancestorFrame = ancestor->document().frame();
+  LocalFrame* descendantFrame = descendant->document().frame();
+  if (ancestorFrame != descendantFrame)
+    return false;
+
+  while (descendant && descendant != ancestor)
+    descendant = descendant->containingBlock();
+  return descendant;
+}
+
+void mapRectUpToDocument(LayoutRect& rect,
+                         const LayoutObject& descendant,
+                         const Document& document) {
+  FloatQuad mappedQuad = descendant.localToAncestorQuad(
+      FloatQuad(FloatRect(rect)), document.layoutView(),
+      UseTransforms | ApplyContainerFlip);
+  rect = LayoutRect(mappedQuad.boundingBox());
+}
+
+void mapRectDownToDocument(LayoutRect& rect,
+                           LayoutBoxModelObject* ancestor,
+                           const Document& document) {
+  FloatQuad mappedQuad = document.layoutView()->ancestorToLocalQuad(
+      ancestor, FloatQuad(FloatRect(rect)),
+      UseTransforms | ApplyContainerFlip | TraverseDocumentBoundaries);
+  rect = LayoutRect(mappedQuad.boundingBox());
+}
+
+LayoutUnit computeMargin(const Length& length, LayoutUnit referenceLength) {
+  if (length.type() == Percent) {
+    return LayoutUnit(
+        static_cast<int>(referenceLength.toFloat() * length.percent() / 100.0));
+  }
+  DCHECK_EQ(length.type(), Fixed);
+  return LayoutUnit(length.intValue());
+}
+
+LayoutView* localRootView(Element& element) {
+  LocalFrame* frame = element.document().frame();
+  LocalFrame* frameRoot = frame ? frame->localFrameRoot() : nullptr;
+  return frameRoot ? frameRoot->contentLayoutObject() : nullptr;
+}
+
+}  // namespace
+
+IntersectionGeometry::IntersectionGeometry(Element* root,
+                                           Element& target,
+                                           const Vector<Length>& rootMargin,
+                                           bool shouldReportRootBounds)
+    : m_root(root ? root->layoutObject() : localRootView(target)),
+      m_target(target.layoutObject()),
+      m_rootMargin(rootMargin),
+      m_doesIntersect(0),
+      m_shouldReportRootBounds(shouldReportRootBounds),
+      m_rootIsImplicit(!root),
+      m_canComputeGeometry(initializeCanComputeGeometry(root, target)) {
+  if (m_canComputeGeometry)
+    initializeGeometry();
+}
+
+IntersectionGeometry::~IntersectionGeometry() {}
+
+bool IntersectionGeometry::initializeCanComputeGeometry(Element* root,
+                                                        Element& target) const {
+  DCHECK(m_rootMargin.isEmpty() || m_rootMargin.size() == 4);
+  if (root && !root->isConnected())
+    return false;
+  if (!m_root || !m_root->isBox())
+    return false;
+  if (!target.isConnected())
+    return false;
+  if (!m_target || (!m_target->isBoxModelObject() && !m_target->isText()))
+    return false;
+  if (root && !isContainingBlockChainDescendant(m_target, m_root))
+    return false;
+  return true;
+}
+
+void IntersectionGeometry::initializeGeometry() {
+  initializeTargetRect();
+  m_intersectionRect = m_targetRect;
+  initializeRootRect();
+}
+
+void IntersectionGeometry::initializeTargetRect() {
+  m_targetRect =
+      LayoutRect(toLayoutBoxModelObject(target())->borderBoundingBox());
+}
+
+void IntersectionGeometry::initializeRootRect() {
+  // TODO(szager): In OOPIF, m_root will be the LayoutView of the
+  // localFrameRoot().  Once viewport intersection support lands,
+  // add a call to mapToVisualRectInAncestorSpace to map the rect up to
+  // top-level frame coordinates.
+  if (m_root->isLayoutView()) {
+    m_rootRect =
+        LayoutRect(toLayoutView(m_root)->frameView()->visibleContentRect());
+  } else if (m_root->isBox() && m_root->hasOverflowClip()) {
+    m_rootRect = LayoutRect(toLayoutBox(m_root)->contentBoxRect());
+  } else {
+    m_rootRect =
+        LayoutRect(toLayoutBoxModelObject(m_root)->borderBoundingBox());
+  }
+  applyRootMargin();
+}
+
+void IntersectionGeometry::applyRootMargin() {
+  if (m_rootMargin.isEmpty())
+    return;
+
+  // TODO(szager): Make sure the spec is clear that left/right margins are
+  // resolved against width and not height.
+  LayoutUnit topMargin = computeMargin(m_rootMargin[0], m_rootRect.height());
+  LayoutUnit rightMargin = computeMargin(m_rootMargin[1], m_rootRect.width());
+  LayoutUnit bottomMargin = computeMargin(m_rootMargin[2], m_rootRect.height());
+  LayoutUnit leftMargin = computeMargin(m_rootMargin[3], m_rootRect.width());
+
+  m_rootRect.setX(m_rootRect.x() - leftMargin);
+  m_rootRect.setWidth(m_rootRect.width() + leftMargin + rightMargin);
+  m_rootRect.setY(m_rootRect.y() - topMargin);
+  m_rootRect.setHeight(m_rootRect.height() + topMargin + bottomMargin);
+}
+
+void IntersectionGeometry::clipToRoot() {
+  // Map and clip rect into root element coordinates.
+  // TODO(szager): the writing mode flipping needs a test.
+  // TODO(szager): Once the OOPIF viewport intersection code lands,
+  // use nullptr for ancestor to map to the top frame.
+  LayoutBox* ancestor = toLayoutBox(m_root);
+  m_doesIntersect = m_target->mapToVisualRectInAncestorSpace(
+      ancestor, m_intersectionRect, EdgeInclusive);
+  if (ancestor && ancestor->hasOverflowClip())
+    m_intersectionRect.move(-ancestor->scrolledContentOffset());
+  if (!m_doesIntersect)
+    return;
+  LayoutRect rootClipRect(m_rootRect);
+  if (ancestor)
+    ancestor->flipForWritingMode(rootClipRect);
+  m_doesIntersect &= m_intersectionRect.inclusiveIntersect(rootClipRect);
+}
+
+void IntersectionGeometry::mapTargetRectToTargetFrameCoordinates() {
+  Document& targetDocument = m_target->document();
+  LayoutSize scrollPosition =
+      LayoutSize(targetDocument.view()->getScrollOffset());
+  mapRectUpToDocument(m_targetRect, *m_target, targetDocument);
+  m_targetRect.move(-scrollPosition);
+}
+
+void IntersectionGeometry::mapRootRectToRootFrameCoordinates() {
+  Document& rootDocument = m_root->document();
+  if (!rootIsImplicit())
+    mapRectUpToDocument(m_rootRect, *m_root, rootDocument);
+  // TODO(szager): When OOPIF support lands, this scroll offset adjustment
+  // will probably be wrong.
+  LayoutSize scrollPosition =
+      LayoutSize(rootDocument.view()->getScrollOffset());
+  m_rootRect.move(-scrollPosition);
+}
+
+void IntersectionGeometry::mapIntersectionRectToTargetFrameCoordinates() {
+  Document& targetDocument = m_target->document();
+  if (rootIsImplicit()) {
+    LocalFrame* targetFrame = targetDocument.frame();
+    Frame* rootFrame = targetFrame->tree().top();
+    LayoutSize scrollPosition =
+        LayoutSize(targetDocument.view()->getScrollOffset());
+    if (targetFrame != rootFrame)
+      mapRectDownToDocument(m_intersectionRect, nullptr, targetDocument);
+    m_intersectionRect.move(-scrollPosition);
+  } else {
+    LayoutSize scrollPosition =
+        LayoutSize(targetDocument.view()->getScrollOffset());
+    mapRectUpToDocument(m_intersectionRect, *m_root, m_root->document());
+    m_intersectionRect.move(-scrollPosition);
+  }
+}
+
+void IntersectionGeometry::computeGeometry() {
+  if (!canComputeGeometry())
+    return;
+  clipToRoot();
+  mapTargetRectToTargetFrameCoordinates();
+  if (m_doesIntersect)
+    mapIntersectionRectToTargetFrameCoordinates();
+  else
+    m_intersectionRect = LayoutRect();
+  // Small optimization: if we're not going to report root bounds, don't bother
+  // transforming them to the frame.
+  if (shouldReportRootBounds())
+    mapRootRectToRootFrameCoordinates();
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/IntersectionGeometry.h b/third_party/WebKit/Source/core/layout/IntersectionGeometry.h
new file mode 100644
index 0000000..6244ddd
--- /dev/null
+++ b/third_party/WebKit/Source/core/layout/IntersectionGeometry.h
@@ -0,0 +1,88 @@
+// 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 IntersectionGeometry_h
+#define IntersectionGeometry_h
+
+#include "platform/Length.h"
+#include "platform/geometry/LayoutRect.h"
+#include "platform/heap/Handle.h"
+#include "wtf/Vector.h"
+
+namespace blink {
+
+class Element;
+class LayoutObject;
+
+// Computes the intersection between an ancestor (root) element and a
+// descendant (target) element, with overflow and CSS clipping applied, but not
+// paint occlusion.
+//
+// If the root argument to the constructor is null, computes the intersection
+// of the target with the top-level frame viewport (AKA the "implicit root").
+class IntersectionGeometry {
+  STACK_ALLOCATED()
+ public:
+  IntersectionGeometry(Element* root,
+                       Element& target,
+                       const Vector<Length>& rootMargin,
+                       bool shouldReportRootBounds);
+  ~IntersectionGeometry();
+
+  void computeGeometry();
+
+  LayoutObject* root() const { return m_root; }
+  LayoutObject* target() const { return m_target; }
+
+  // Client rect in the coordinate system of the frame containing target.
+  LayoutRect targetRect() const { return m_targetRect; }
+
+  // Client rect in the coordinate system of the frame containing target.
+  LayoutRect intersectionRect() const { return m_intersectionRect; }
+
+  // Client rect in the coordinate system of the frame containing root.
+  LayoutRect rootRect() const { return m_rootRect; }
+
+  bool doesIntersect() const { return m_doesIntersect; }
+
+  IntRect intersectionIntRect() const {
+    return pixelSnappedIntRect(m_intersectionRect);
+  }
+
+  IntRect targetIntRect() const { return pixelSnappedIntRect(m_targetRect); }
+
+  IntRect rootIntRect() const { return pixelSnappedIntRect(m_rootRect); }
+
+ private:
+  bool initializeCanComputeGeometry(Element* root, Element& target) const;
+  void initializeGeometry();
+  void initializeTargetRect();
+  void initializeRootRect();
+  void clipToRoot();
+  void mapTargetRectToTargetFrameCoordinates();
+  void mapRootRectToRootFrameCoordinates();
+  void mapIntersectionRectToTargetFrameCoordinates();
+  void applyRootMargin();
+
+  // Returns true iff it's possible to compute an intersection between root
+  // and target.
+  bool canComputeGeometry() const { return m_canComputeGeometry; }
+  bool rootIsImplicit() const { return m_rootIsImplicit; }
+  bool shouldReportRootBounds() const { return m_shouldReportRootBounds; }
+
+  LayoutObject* m_root;
+  LayoutObject* m_target;
+  const Vector<Length> m_rootMargin;
+  LayoutRect m_targetRect;
+  LayoutRect m_intersectionRect;
+  LayoutRect m_rootRect;
+  unsigned m_doesIntersect : 1;
+  const unsigned m_shouldReportRootBounds : 1;
+  const unsigned m_rootIsImplicit : 1;
+  const unsigned m_canComputeGeometry : 1;
+};
+
+}  // namespace blink
+
+#endif  // IntersectionGeometry_h
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp
index 03b3619..da28bc8 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp
@@ -1709,10 +1709,10 @@
 
   LayoutObject* prev = child.previousSibling();
   LayoutBlockFlow* previousBlockFlow =
-      prev && prev->isLayoutBlockFlow() &&
-              !prev->isFloatingOrOutOfFlowPositioned()
-          ? toLayoutBlockFlow(prev)
-          : 0;
+      prev && prev->isLayoutBlockFlow() ? toLayoutBlockFlow(prev) : nullptr;
+  bool previousBlockFlowCanSelfCollapse =
+      previousBlockFlow &&
+      !previousBlockFlow->isFloatingOrOutOfFlowPositioned();
   // If the child's previous sibling is a self-collapsing block that cleared a
   // float then its top border edge has been set at the bottom border edge of
   // the float. Since we want to collapse the child's top margin with the self-
@@ -1720,7 +1720,8 @@
   // height to match the margin top of the self-collapsing block. If the
   // resulting collapsed margin leaves the child still intruding into the float
   // then we will want to clear it.
-  if (!marginInfo.canCollapseWithMarginBefore() && previousBlockFlow &&
+  if (!marginInfo.canCollapseWithMarginBefore() &&
+      previousBlockFlowCanSelfCollapse &&
       marginInfo.lastChildIsSelfCollapsingBlockWithClearance())
     setLogicalHeight(
         logicalHeight() -
@@ -1801,18 +1802,28 @@
     setLogicalHeight(logicalHeight() + (logicalTop - oldLogicalTop));
   }
 
-  if (previousBlockFlow) {
-    // If |child| is a self-collapsing block it may have collapsed into a
-    // previous sibling and although it hasn't reduced the height of the parent
-    // yet any floats from the parent will now overhang.
+  // If |child| has moved up into previous siblings it needs to avoid or clear
+  // any floats they contain.
+  if (logicalTop < beforeCollapseLogicalTop) {
     LayoutUnit oldLogicalHeight = logicalHeight();
     setLogicalHeight(logicalTop);
-    if (!previousBlockFlow->avoidsFloats() &&
-        (previousBlockFlow->logicalTop() +
-         previousBlockFlow->lowestFloatLogicalBottom()) > logicalTop)
-      addOverhangingFloats(previousBlockFlow, false);
+    while (previousBlockFlow) {
+      auto lowestFloat = previousBlockFlow->logicalTop() +
+                         previousBlockFlow->lowestFloatLogicalBottom();
+      if (lowestFloat > logicalTop)
+        addOverhangingFloats(previousBlockFlow, false);
+      else
+        break;
+      LayoutObject* prev = previousBlockFlow->previousSibling();
+      if (prev && prev->isLayoutBlockFlow())
+        previousBlockFlow = toLayoutBlockFlow(prev);
+      else
+        previousBlockFlow = nullptr;
+    }
     setLogicalHeight(oldLogicalHeight);
+  }
 
+  if (previousBlockFlowCanSelfCollapse) {
     // If |child|'s previous sibling is or contains a self-collapsing block that
     // cleared a float and margin collapsing resulted in |child| moving up
     // into the margin area of the self-collapsing block then the float it
diff --git a/third_party/WebKit/Source/core/layout/LayoutBox.cpp b/third_party/WebKit/Source/core/layout/LayoutBox.cpp
index 894f7d8..f061939e 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBox.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBox.cpp
@@ -2257,6 +2257,13 @@
       return false;
   }
 
+  // If the box paints into its own backing, we can assume that it's painting
+  // may have some effect. For example, honoring the border-radius clip on
+  // a composited child paints into a mask for an otherwise non-painting
+  // element, because children of that element will require the mask.
+  if (hasLayer() && layer()->compositingState() == PaintsIntoOwnBacking)
+    return false;
+
   return true;
 }
 
@@ -4720,6 +4727,7 @@
   // just marking and bailing here.
   if (child.isFloating())
     return true;
+  const LayoutFlowThread* flowThread = child.flowThreadContainingBlock();
   LayoutUnit logicalTop = child.logicalTop();
   // Figure out if we really need to force re-layout of the child. We only need
   // to do this if there's a chance that we need to recalculate pagination
@@ -4733,6 +4741,10 @@
       // location as before.
       if (child.offsetToNextPage() != remainingSpace)
         return true;
+      // If column height isn't guaranteed to be uniform, we have no way of
+      // telling what has happened after the first break.
+      if (flowThread && flowThread->mayHaveNonUniformPageLogicalHeight())
+        return true;
     } else if (logicalHeight > remainingSpace) {
       // Last time we laid out this child, we didn't need to break, but now we
       // have to. So we need to relayout.
@@ -4747,7 +4759,6 @@
   // It seems that we can skip layout of this child, but we need to ask the flow
   // thread for permission first. We currently cannot skip over objects
   // containing column spanners.
-  LayoutFlowThread* flowThread = child.flowThreadContainingBlock();
   return flowThread && !flowThread->canSkipLayout(child);
 }
 
diff --git a/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.cpp b/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.cpp
index d35fc7f..f4b697b 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.cpp
@@ -129,12 +129,6 @@
   if (!style()->hasAutoClip())
     return BackgroundPaintInGraphicsLayer;
 
-  // TODO(flackr): Remove this when box shadows are still painted correctly when
-  // painting into the composited scrolling contents layer.
-  // https://crbug.com/646464
-  if (style()->boxShadow())
-    return BackgroundPaintInGraphicsLayer;
-
   // Assume optimistically that the background can be painted in the scrolling
   // contents until we find otherwise.
   BackgroundPaintLocation paintLocation = BackgroundPaintInScrollingContents;
diff --git a/third_party/WebKit/Source/core/layout/LayoutFlowThread.h b/third_party/WebKit/Source/core/layout/LayoutFlowThread.h
index 594eafd9..354991c 100644
--- a/third_party/WebKit/Source/core/layout/LayoutFlowThread.h
+++ b/third_party/WebKit/Source/core/layout/LayoutFlowThread.h
@@ -141,6 +141,7 @@
       LayoutUnit contentLogicalHeight) const;
 
   virtual bool isPageLogicalHeightKnown() const { return true; }
+  virtual bool mayHaveNonUniformPageLogicalHeight() const = 0;
   bool pageLogicalSizeChanged() const { return m_pageLogicalSizeChanged; }
 
   // Return the visual bounding box based on the supplied flow-thread bounding
diff --git a/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.cpp b/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.cpp
index 807fe96..f532eda6 100644
--- a/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.cpp
@@ -365,6 +365,15 @@
   return false;
 }
 
+bool LayoutMultiColumnFlowThread::mayHaveNonUniformPageLogicalHeight() const {
+  const LayoutMultiColumnSet* columnSet = firstMultiColumnSet();
+  if (!columnSet)
+    return false;
+  if (columnSet->nextSiblingMultiColumnSet())
+    return true;
+  return enclosingFragmentationContext();
+}
+
 LayoutSize LayoutMultiColumnFlowThread::flowThreadTranslationAtOffset(
     LayoutUnit offsetInFlowThread,
     PageBoundaryRule rule,
diff --git a/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.h b/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.h
index a1ad047..8264eb4 100644
--- a/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.h
+++ b/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.h
@@ -216,6 +216,7 @@
   virtual bool needsNewWidth() const;
 
   bool isPageLogicalHeightKnown() const final;
+  bool mayHaveNonUniformPageLogicalHeight() const final;
 
   LayoutSize flowThreadTranslationAtOffset(LayoutUnit,
                                            PageBoundaryRule,
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
index d238b39..2d831e1e 100644
--- a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
+++ b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
@@ -202,7 +202,7 @@
     }
   }
 
-  updateClippingLayers(false, false);
+  updateClippingLayers(false, false, false);
   updateOverflowControlsLayers(false, false, false, false);
   updateChildTransformLayer(false);
   updateForegroundLayer(false);
@@ -246,6 +246,7 @@
     m_graphicsLayer->removeFromParent();
 
   m_ancestorClippingLayer = nullptr;
+  m_ancestorClippingMaskLayer = nullptr;
   m_graphicsLayer = nullptr;
   m_foregroundLayer = nullptr;
   m_backgroundLayer = nullptr;
@@ -472,29 +473,34 @@
       m_owningLayer.getSquashingDisallowedReasons());
 }
 
-bool CompositedLayerMapping::
-    owningLayerClippedByLayerNotAboveCompositedAncestor(
-        const PaintLayer* scrollParent) {
+void CompositedLayerMapping::
+    owningLayerClippedOrMaskedByLayerNotAboveCompositedAncestor(
+        const PaintLayer* scrollParent,
+        bool& owningLayerIsClipped,
+        bool& owningLayerIsMasked) {
+  owningLayerIsClipped = false;
+  owningLayerIsMasked = false;
+
   if (!m_owningLayer.parent())
-    return false;
+    return;
 
   const PaintLayer* compositingAncestor =
       m_owningLayer.enclosingLayerWithCompositedLayerMapping(ExcludeSelf);
   if (!compositingAncestor)
-    return false;
+    return;
 
   const LayoutObject* clippingContainer = m_owningLayer.clippingContainer();
   if (!clippingContainer)
-    return false;
+    return;
 
   if (clippingContainer->enclosingLayer() == scrollParent)
-    return false;
+    return;
 
   if (clippingContainer->enclosingLayer()->hasRootScrollerAsDescendant())
-    return false;
+    return;
 
   if (compositingAncestor->layoutObject()->isDescendantOf(clippingContainer))
-    return false;
+    return;
 
   // We ignore overflow clip here; we want composited overflow content to
   // behave as if it lives in an unclipped universe so it can prepaint, etc.
@@ -509,7 +515,14 @@
   clipRectsContext.setIgnoreOverflowClip();
   IntRect parentClipRect = pixelSnappedIntRect(
       m_owningLayer.clipper().backgroundClipRect(clipRectsContext).rect());
-  return parentClipRect != LayoutRect::infiniteIntRect();
+  owningLayerIsClipped = parentClipRect != LayoutRect::infiniteIntRect();
+
+  // TODO(schenney): CSS clips are not applied to composited children, and
+  // should be via mask or by compositing the parent too.
+  // https://bugs.chromium.org/p/chromium/issues/detail?id=615870
+  DCHECK(clippingContainer->style());
+  owningLayerIsMasked =
+      owningLayerIsClipped && clippingContainer->style()->hasBorderRadius();
 }
 
 const PaintLayer* CompositedLayerMapping::scrollParent() {
@@ -565,10 +578,12 @@
   // layoutObject hierarchy, but a sibling in the z-order hierarchy. Further,
   // that sibling need not be composited at all. In such scenarios, an ancestor
   // clipping layer is necessary to apply the composited clip for this layer.
-  bool needsAncestorClip =
-      owningLayerClippedByLayerNotAboveCompositedAncestor(scrollParent);
-
-  if (updateClippingLayers(needsAncestorClip, needsDescendantsClippingLayer))
+  bool needsAncestorClip = false;
+  bool needsAncestorClippingMask = false;
+  owningLayerClippedOrMaskedByLayerNotAboveCompositedAncestor(
+      scrollParent, needsAncestorClip, needsAncestorClippingMask);
+  if (updateClippingLayers(needsAncestorClip, needsAncestorClippingMask,
+                           needsDescendantsClippingLayer))
     layerConfigChanged = true;
 
   bool scrollingConfigChanged = false;
@@ -1100,6 +1115,13 @@
   m_ancestorClippingLayer->setOffsetFromLayoutObject(
       parentClipRect.location() - snappedOffsetFromCompositedAncestor);
 
+  if (m_ancestorClippingMaskLayer) {
+    m_ancestorClippingMaskLayer->setOffsetFromLayoutObject(
+        m_ancestorClippingLayer->offsetFromLayoutObject());
+    m_ancestorClippingMaskLayer->setSize(m_ancestorClippingLayer->size());
+    m_ancestorClippingMaskLayer->setNeedsDisplay();
+  }
+
   // The primary layer is then parented in, and positioned relative to this
   // clipping layer.
   graphicsLayerParentLocation = parentClipRect.location();
@@ -1651,6 +1673,9 @@
   if (m_decorationOutlineLayer)
     m_decorationOutlineLayer->setDrawsContent(true);
 
+  if (m_ancestorClippingMaskLayer)
+    m_ancestorClippingMaskLayer->setDrawsContent(true);
+
   if (m_maskLayer)
     m_maskLayer->setDrawsContent(true);
 
@@ -1668,8 +1693,10 @@
 }
 
 // Return true if the layers changed.
-bool CompositedLayerMapping::updateClippingLayers(bool needsAncestorClip,
-                                                  bool needsDescendantClip) {
+bool CompositedLayerMapping::updateClippingLayers(
+    bool needsAncestorClip,
+    bool needsAncestorClippingMask,
+    bool needsDescendantClip) {
   bool layersChanged = false;
 
   if (needsAncestorClip) {
@@ -1681,11 +1708,32 @@
       layersChanged = true;
     }
   } else if (m_ancestorClippingLayer) {
+    if (m_ancestorClippingMaskLayer) {
+      m_ancestorClippingMaskLayer->removeFromParent();
+      m_ancestorClippingMaskLayer = nullptr;
+    }
     m_ancestorClippingLayer->removeFromParent();
     m_ancestorClippingLayer = nullptr;
     layersChanged = true;
   }
 
+  if (needsAncestorClippingMask) {
+    DCHECK(m_ancestorClippingLayer);
+    if (!m_ancestorClippingMaskLayer) {
+      m_ancestorClippingMaskLayer =
+          createGraphicsLayer(CompositingReasonLayerForAncestorClippingMask);
+      m_ancestorClippingMaskLayer->setPaintingPhase(
+          GraphicsLayerPaintAncestorClippingMask);
+      m_ancestorClippingLayer->setMaskLayer(m_ancestorClippingMaskLayer.get());
+      layersChanged = true;
+    }
+  } else if (m_ancestorClippingMaskLayer) {
+    m_ancestorClippingMaskLayer->removeFromParent();
+    m_ancestorClippingMaskLayer = nullptr;
+    m_ancestorClippingLayer->setMaskLayer(nullptr);
+    layersChanged = true;
+  }
+
   if (needsDescendantClip) {
     // We don't need a child containment layer if we're the main frame layout
     // view layer. It's redundant as the frame clip above us will handle this
@@ -1915,6 +1963,10 @@
        (mode & ApplyToNonScrollingContentLayers)) &&
       mapping->childClippingMaskLayer())
     f(mapping->childClippingMaskLayer());
+  if (((mode & ApplyToMaskLayers) || (mode & ApplyToContentLayers) ||
+       (mode & ApplyToNonScrollingContentLayers)) &&
+      mapping->ancestorClippingMaskLayer())
+    f(mapping->ancestorClippingMaskLayer());
 
   if (((mode & ApplyToBackgroundLayer) || (mode & ApplyToContentLayers) ||
        (mode & ApplyToNonScrollingContentLayers)) &&
@@ -1950,7 +2002,7 @@
   // Some compositing reasons depend on the compositing state of ancestors. So
   // if we want a rendering context id for the context root, we cannot ask for
   // the id of its associated WebLayer now; it may not have one yet. We could do
-  // a second past after doing the compositing updates to get these ids, but
+  // a second pass after doing the compositing updates to get these ids, but
   // this would actually be harmful. We do not want to attach any semantic
   // meaning to the context id other than the fact that they group a number of
   // layers together for the sake of 3d sorting. So instead we will ask the
@@ -2254,7 +2306,11 @@
 
 void CompositedLayerMapping::updateClipParent(const PaintLayer* scrollParent) {
   const PaintLayer* clipParent = nullptr;
-  if (!owningLayerClippedByLayerNotAboveCompositedAncestor(scrollParent)) {
+  bool haveAncestorClipLayer = false;
+  bool haveAncestorMaskLayer = false;
+  owningLayerClippedOrMaskedByLayerNotAboveCompositedAncestor(
+      scrollParent, haveAncestorClipLayer, haveAncestorMaskLayer);
+  if (!haveAncestorClipLayer) {
     clipParent = m_owningLayer.clipParent();
     if (clipParent)
       clipParent =
@@ -2794,6 +2850,8 @@
   if (!(paintLayerFlags & PaintLayerPaintingOverflowContents)) {
     LayoutRect bounds = paintInfo.compositedBounds;
     bounds.move(paintInfo.paintLayer->subpixelAccumulation());
+    if (paintLayerFlags & PaintLayerPaintingAncestorClippingMaskPhase)
+      bounds.move(offset);
     dirtyRect.intersect(pixelSnappedIntRect(bounds));
   } else {
     dirtyRect.move(
@@ -3071,6 +3129,8 @@
     paintLayerFlags |= PaintLayerPaintingCompositingMaskPhase;
   if (graphicsLayerPaintingPhase & GraphicsLayerPaintChildClippingMask)
     paintLayerFlags |= PaintLayerPaintingChildClippingMaskPhase;
+  if (graphicsLayerPaintingPhase & GraphicsLayerPaintAncestorClippingMask)
+    paintLayerFlags |= PaintLayerPaintingAncestorClippingMaskPhase;
   if (graphicsLayerPaintingPhase & GraphicsLayerPaintOverflowContents)
     paintLayerFlags |= PaintLayerPaintingOverflowContents;
   if (graphicsLayerPaintingPhase & GraphicsLayerPaintCompositedScroll)
@@ -3090,7 +3150,8 @@
       graphicsLayer == m_maskLayer.get() ||
       graphicsLayer == m_childClippingMaskLayer.get() ||
       graphicsLayer == m_scrollingContentsLayer.get() ||
-      graphicsLayer == m_decorationOutlineLayer.get()) {
+      graphicsLayer == m_decorationOutlineLayer.get() ||
+      graphicsLayer == m_ancestorClippingMaskLayer.get()) {
     bool paintRootBackgroundOntoScrollingContentsLayer =
         m_backgroundPaintsOntoScrollingContentsLayer;
     DCHECK(!paintRootBackgroundOntoScrollingContentsLayer ||
@@ -3345,6 +3406,8 @@
            ")";
   } else if (graphicsLayer == m_ancestorClippingLayer.get()) {
     name = "Ancestor Clipping Layer";
+  } else if (graphicsLayer == m_ancestorClippingMaskLayer.get()) {
+    name = "Ancestor Clipping Mask Layer";
   } else if (graphicsLayer == m_foregroundLayer.get()) {
     name = m_owningLayer.debugName() + " (foreground) Layer";
   } else if (graphicsLayer == m_backgroundLayer.get()) {
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.h b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.h
index 6ee087cb..3e98bde 100644
--- a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.h
+++ b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.h
@@ -117,6 +117,10 @@
     return m_ancestorClippingLayer.get();
   }
 
+  GraphicsLayer* ancestorClippingMaskLayer() const {
+    return m_ancestorClippingMaskLayer.get();
+  }
+
   GraphicsLayer* foregroundLayer() const { return m_foregroundLayer.get(); }
 
   GraphicsLayer* backgroundLayer() const { return m_backgroundLayer.get(); }
@@ -383,6 +387,9 @@
   void updateInternalHierarchy();
   void updatePaintingPhases();
   bool updateClippingLayers(bool needsAncestorClip, bool needsDescendantClip);
+  bool updateClippingLayers(bool needsAncestorClip,
+                            bool needsAncestorClippingMask,
+                            bool needsDescendantClip);
   bool updateChildTransformLayer(bool needsChildTransformLayer);
   bool updateOverflowControlsLayers(bool needsHorizontalScrollbarLayer,
                                     bool needsVerticalScrollbarLayer,
@@ -477,10 +484,16 @@
       const GraphicsLayerPaintInfo&,
       const Vector<GraphicsLayerPaintInfo>& layers);
 
-  // Return true if |m_owningLayer|'s compositing ancestor is not a descendant
-  // (inclusive) of the clipping container for |m_owningLayer|.
-  bool owningLayerClippedByLayerNotAboveCompositedAncestor(
-      const PaintLayer* scrollParent);
+  // Return true in |owningLayerIsClipped| iff |m_owningLayer|'s compositing
+  // ancestor is not a descendant (inclusive) of the clipping container for
+  // |m_owningLayer|. Return true in |owningLayerIsMasked| iff
+  // |owningLayerIsClipped| is true and |m_owningLayer|'s compositing ancestor
+  // is not a descendant (inclusive) of a container that applies a mask for
+  // |m_owningLayer|.
+  void owningLayerClippedOrMaskedByLayerNotAboveCompositedAncestor(
+      const PaintLayer* scrollParent,
+      bool& owningLayerIsClipped,
+      bool& owningLayerIsMasked);
 
   const PaintLayer* scrollParent();
 
@@ -529,9 +542,20 @@
   // In this case B is clipped by another layer that doesn't happen to be its
   // ancestor: A.  So we create an ancestor clipping layer for B, [+], which
   // ensures that B is clipped as if it had been A's descendant.
+  // In addition, the m_ancestorClippingLayer will have an associated
+  // mask layer if the ancestor, A, has a border radius that requires a
+  // rounded corner clip rect. The mask is not part of the layer tree; rather
+  // it is attached to the m_ancestorClippingLayer itself.
+  //
+  // Layers that require a CSS mask also have a mask layer attached to them.
 
   // Only used if we are clipped by an ancestor which is not a stacking context.
   std::unique_ptr<GraphicsLayer> m_ancestorClippingLayer;
+
+  // Only used is there is an m_ancestorClippingLayer that also needs to apply
+  // a clipping mask (for CSS clips or border radius).
+  std::unique_ptr<GraphicsLayer> m_ancestorClippingMaskLayer;
+
   std::unique_ptr<GraphicsLayer> m_graphicsLayer;
 
   // Only used if we have clipping on a stacking context with compositing
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMappingTest.cpp b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMappingTest.cpp
index b5087ac..f20e8160 100644
--- a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMappingTest.cpp
+++ b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMappingTest.cpp
@@ -1084,4 +1084,85 @@
   }
 }
 
+TEST_P(CompositedLayerMappingTest, AncestorClippingMaskLayerUpdates) {
+  setBodyInnerHTML(
+      "<style>"
+      "#ancestor { width: 100px; height: 100px; overflow: hidden; }"
+      "#child { width: 120px; height: 120px; background-color: green; }"
+      "</style>"
+      "<div id='ancestor'><div id='child'></div></div>");
+  document().view()->updateAllLifecyclePhases();
+
+  Element* ancestor = document().getElementById("ancestor");
+  ASSERT_TRUE(ancestor);
+  PaintLayer* ancestorPaintLayer =
+      toLayoutBoxModelObject(ancestor->layoutObject())->layer();
+  ASSERT_TRUE(ancestorPaintLayer);
+
+  CompositedLayerMapping* ancestorMapping =
+      ancestorPaintLayer->compositedLayerMapping();
+  ASSERT_FALSE(ancestorMapping);
+
+  Element* child = document().getElementById("child");
+  ASSERT_TRUE(child);
+  PaintLayer* childPaintLayer =
+      toLayoutBoxModelObject(child->layoutObject())->layer();
+  ASSERT_FALSE(childPaintLayer);
+
+  // Making the child conposited causes creation of an AncestorClippingLayer.
+  child->setAttribute(HTMLNames::styleAttr, "will-change: transform");
+  document().view()->updateAllLifecyclePhases();
+
+  childPaintLayer = toLayoutBoxModelObject(child->layoutObject())->layer();
+  ASSERT_TRUE(childPaintLayer);
+  CompositedLayerMapping* childMapping =
+      childPaintLayer->compositedLayerMapping();
+  ASSERT_TRUE(childMapping);
+  EXPECT_TRUE(childMapping->ancestorClippingLayer());
+  EXPECT_FALSE(childMapping->ancestorClippingLayer()->maskLayer());
+  EXPECT_FALSE(childMapping->ancestorClippingMaskLayer());
+
+  // Adding border radius to the ancestor requires an
+  // ancestorClippingMaskLayer for the child
+  ancestor->setAttribute(HTMLNames::styleAttr, "border-radius: 40px;");
+  document().view()->updateAllLifecyclePhases();
+
+  childPaintLayer = toLayoutBoxModelObject(child->layoutObject())->layer();
+  ASSERT_TRUE(childPaintLayer);
+  childMapping = childPaintLayer->compositedLayerMapping();
+  ASSERT_TRUE(childMapping);
+  EXPECT_TRUE(childMapping->ancestorClippingLayer());
+  EXPECT_TRUE(childMapping->ancestorClippingLayer()->maskLayer());
+  EXPECT_TRUE(childMapping->ancestorClippingMaskLayer());
+
+  // Removing the border radius should remove the ancestorClippingMaskLayer
+  // for the child
+  ancestor->setAttribute(HTMLNames::styleAttr, "border-radius: 0px;");
+  document().view()->updateAllLifecyclePhases();
+
+  childPaintLayer = toLayoutBoxModelObject(child->layoutObject())->layer();
+  ASSERT_TRUE(childPaintLayer);
+  childMapping = childPaintLayer->compositedLayerMapping();
+  ASSERT_TRUE(childMapping);
+  EXPECT_TRUE(childMapping->ancestorClippingLayer());
+  EXPECT_FALSE(childMapping->ancestorClippingLayer()->maskLayer());
+  EXPECT_FALSE(childMapping->ancestorClippingMaskLayer());
+
+  // Add border radius back so we can test one more case
+  ancestor->setAttribute(HTMLNames::styleAttr, "border-radius: 40px;");
+  document().view()->updateAllLifecyclePhases();
+
+  // Now change the overflow to remove the need for an ancestor clip
+  // on the child
+  ancestor->setAttribute(HTMLNames::styleAttr, "overflow: visible");
+  document().view()->updateAllLifecyclePhases();
+
+  childPaintLayer = toLayoutBoxModelObject(child->layoutObject())->layer();
+  ASSERT_TRUE(childPaintLayer);
+  childMapping = childPaintLayer->compositedLayerMapping();
+  ASSERT_TRUE(childMapping);
+  EXPECT_FALSE(childMapping->ancestorClippingLayer());
+  EXPECT_FALSE(childMapping->ancestorClippingMaskLayer());
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceMarker.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceMarker.cpp
index b314112..38e0dc2 100644
--- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceMarker.cpp
+++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceMarker.cpp
@@ -27,7 +27,7 @@
 namespace blink {
 
 LayoutSVGResourceMarker::LayoutSVGResourceMarker(SVGMarkerElement* node)
-    : LayoutSVGResourceContainer(node) {}
+    : LayoutSVGResourceContainer(node), m_needsTransformUpdate(true) {}
 
 LayoutSVGResourceMarker::~LayoutSVGResourceMarker() {}
 
@@ -72,10 +72,6 @@
   return markerTransformation.mapRect(coordinates);
 }
 
-AffineTransform LayoutSVGResourceMarker::localToSVGParentTransform() const {
-  return viewportTransform();
-}
-
 FloatPoint LayoutSVGResourceMarker::referencePoint() const {
   SVGMarkerElement* marker = toSVGMarkerElement(element());
   ASSERT(marker);
@@ -119,7 +115,7 @@
   // The reference point (refX, refY) is in the coordinate space of the marker's
   // contents so we include the value in each marker's transform.
   FloatPoint mappedReferencePoint =
-      viewportTransform().mapPoint(referencePoint());
+      localToSVGParentTransform().mapPoint(referencePoint());
   transform.translate(-mappedReferencePoint.x(), -mappedReferencePoint.y());
   return transform;
 }
@@ -133,17 +129,19 @@
          !marker->viewBox()->currentValue()->value().isEmpty();
 }
 
-AffineTransform LayoutSVGResourceMarker::viewportTransform() const {
-  SVGMarkerElement* marker = toSVGMarkerElement(element());
-  ASSERT(marker);
-
-  return marker->viewBoxToViewTransform(m_viewportSize.width(),
-                                        m_viewportSize.height());
+void LayoutSVGResourceMarker::setNeedsTransformUpdate() {
+  setMayNeedPaintInvalidationSubtree();
+  if (RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled()) {
+    // The transform paint property relies on the SVG transform being up-to-date
+    // (see: PaintPropertyTreeBuilder::updateTransformForNonRootSVG).
+    setNeedsPaintPropertyUpdate();
+  }
+  m_needsTransformUpdate = true;
 }
 
-void LayoutSVGResourceMarker::calcViewport() {
-  if (!selfNeedsLayout())
-    return;
+SVGTransformChange LayoutSVGResourceMarker::calculateLocalTransform() {
+  if (!m_needsTransformUpdate)
+    return SVGTransformChange::None;
 
   SVGMarkerElement* marker = toSVGMarkerElement(element());
   ASSERT(marker);
@@ -152,14 +150,13 @@
   float width = marker->markerWidth()->currentValue()->value(lengthContext);
   float height = marker->markerHeight()->currentValue()->value(lengthContext);
   m_viewportSize = FloatSize(width, height);
-}
 
-SVGTransformChange LayoutSVGResourceMarker::calculateLocalTransform() {
-  // TODO(fs): Temporarily, needing a layout implies that the local transform
-  // has changed. This should be updated to be more precise and factor in the
-  // actual (relevant) changes to the computed user-space transform.
-  return selfNeedsLayout() ? SVGTransformChange::Full
-                           : SVGTransformChange::None;
+  SVGTransformChangeDetector changeDetector(m_localToParentTransform);
+  m_localToParentTransform = marker->viewBoxToViewTransform(
+      m_viewportSize.width(), m_viewportSize.height());
+
+  m_needsTransformUpdate = false;
+  return changeDetector.computeChange(m_localToParentTransform);
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceMarker.h b/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceMarker.h
index 63fe310..bf5def6 100644
--- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceMarker.h
+++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceMarker.h
@@ -42,11 +42,19 @@
   // Calculates marker boundaries, mapped to the target element's coordinate
   // space.
   FloatRect markerBoundaries(const AffineTransform& markerTransformation) const;
-
-  AffineTransform localToSVGParentTransform() const override;
   AffineTransform markerTransformation(const FloatPoint& origin,
                                        float angle,
                                        float strokeWidth) const;
+
+  AffineTransform localToSVGParentTransform() const final {
+    return m_localToParentTransform;
+  }
+  void setNeedsTransformUpdate() final;
+
+  // The viewport origin is (0,0) and not the reference point because each
+  // marker instance includes the reference in markerTransformation().
+  FloatRect viewport() const { return FloatRect(FloatPoint(), m_viewportSize); }
+
   bool shouldPaint() const;
 
   FloatPoint referencePoint() const;
@@ -54,21 +62,16 @@
   SVGMarkerUnitsType markerUnits() const;
   SVGMarkerOrientType orientType() const;
 
-  // The viewport origin is (0,0) and not the reference point because each
-  // marker instance includes the reference in markerTransformation().
-  FloatRect viewport() const { return FloatRect(FloatPoint(), m_viewportSize); }
-
   static const LayoutSVGResourceType s_resourceType = MarkerResourceType;
   LayoutSVGResourceType resourceType() const override { return s_resourceType; }
 
  private:
   void layout() override;
-  void calcViewport() override;
-  SVGTransformChange calculateLocalTransform() override;
+  SVGTransformChange calculateLocalTransform() final;
 
-  AffineTransform viewportTransform() const;
-
+  AffineTransform m_localToParentTransform;
   FloatSize m_viewportSize;
+  bool m_needsTransformUpdate;
 };
 
 DEFINE_LAYOUT_SVG_RESOURCE_TYPE_CASTS(LayoutSVGResourceMarker,
diff --git a/third_party/WebKit/Source/core/loader/DocumentLoader.cpp b/third_party/WebKit/Source/core/loader/DocumentLoader.cpp
index cd0ad37..06af2d1 100644
--- a/third_party/WebKit/Source/core/loader/DocumentLoader.cpp
+++ b/third_party/WebKit/Source/core/loader/DocumentLoader.cpp
@@ -148,6 +148,10 @@
   return m_mainResource ? m_mainResource->identifier() : 0;
 }
 
+ResourceTimingInfo* DocumentLoader::getNavigationTimingInfo() const {
+  return fetcher()->getNavigationTimingInfo();
+}
+
 const ResourceRequest& DocumentLoader::originalRequest() const {
   return m_originalRequest;
 }
@@ -764,8 +768,7 @@
   if (!init.shouldReuseDefaultView())
     frame->setDOMWindow(LocalDOMWindow::create(*frame));
 
-  Document* document =
-      frame->localDOMWindow()->installNewDocument(mimeType, init);
+  Document* document = frame->domWindow()->installNewDocument(mimeType, init);
 
   if (!init.shouldReuseDefaultView())
     frame->page()->chromeClient().installSupplements(*frame);
diff --git a/third_party/WebKit/Source/core/loader/DocumentLoader.h b/third_party/WebKit/Source/core/loader/DocumentLoader.h
index fd1ebf4..cf8dbc2 100644
--- a/third_party/WebKit/Source/core/loader/DocumentLoader.h
+++ b/third_party/WebKit/Source/core/loader/DocumentLoader.h
@@ -60,6 +60,7 @@
 class DocumentInit;
 class LocalFrame;
 class FrameLoader;
+class ResourceTimingInfo;
 class WebDocumentSubresourceFilter;
 struct ViewportDescriptionWrapper;
 
@@ -79,6 +80,8 @@
 
   LocalFrame* frame() const { return m_frame; }
 
+  ResourceTimingInfo* getNavigationTimingInfo() const;
+
   virtual void detachFromFrame();
 
   unsigned long mainResourceIdentifier() const;
diff --git a/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp b/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp
index 928aa32..e6aa7c4 100644
--- a/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp
+++ b/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp
@@ -322,9 +322,7 @@
     InspectorInstrumentation::
         documentThreadableLoaderFailedToStartLoadingForClient(m_document,
                                                               m_client);
-    ThreadableLoaderClient* client = m_client;
-    clear();
-    client->didFailAccessControlCheck(ResourceError(
+    dispatchDidFailAccessControlCheck(ResourceError(
         errorDomainBlinkInternal, 0, request.url().getString(),
         "Cross origin requests are only supported for protocol schemes: " +
             SchemeRegistry::listOfCORSEnabledURLSchemes() + "."));
@@ -334,9 +332,7 @@
   // Non-secure origins may not make "external requests":
   // https://mikewest.github.io/cors-rfc1918/#integration-fetch
   if (!document().isSecureContext() && request.isExternalRequest()) {
-    ThreadableLoaderClient* client = m_client;
-    clear();
-    client->didFailAccessControlCheck(
+    dispatchDidFailAccessControlCheck(
         ResourceError(errorDomainBlinkInternal, 0, request.url().getString(),
                       "Requests to internal network resources are not allowed "
                       "from non-secure contexts (see https://goo.gl/Y0ZkNV). "
@@ -439,29 +435,20 @@
 }
 
 void DocumentThreadableLoader::cancel() {
-  cancelWithError(ResourceError());
-}
-
-void DocumentThreadableLoader::cancelWithError(const ResourceError& error) {
-  // Cancel can re-enter and m_resource might be null here as a result.
+  // Cancel can re-enter, and therefore |resource()| might be null here as a
+  // result.
   if (!m_client || !resource()) {
     clear();
     return;
   }
 
-  ResourceError errorForCallback = error;
-  if (errorForCallback.isNull()) {
-    // FIXME: This error is sent to the client in didFail(), so it should not be
-    // an internal one. Use FrameLoaderClient::cancelledError() instead.
-    errorForCallback =
-        ResourceError(errorDomainBlinkInternal, 0,
-                      resource()->url().getString(), "Load cancelled");
-    errorForCallback.setIsCancellation(true);
-  }
+  // FIXME: This error is sent to the client in didFail(), so it should not be
+  // an internal one. Use FrameLoaderClient::cancelledError() instead.
+  ResourceError error(errorDomainBlinkInternal, 0, resource()->url(),
+                      "Load cancelled");
+  error.setIsCancellation(true);
 
-  ThreadableLoaderClient* client = m_client;
-  clear();
-  client->didFail(errorForCallback);
+  dispatchDidFail(error);
 }
 
 void DocumentThreadableLoader::setDefersLoading(bool value) {
@@ -580,9 +567,7 @@
   }
 
   if (!allowRedirect) {
-    ThreadableLoaderClient* client = m_client;
-    clear();
-    client->didFailAccessControlCheck(ResourceError(
+    dispatchDidFailAccessControlCheck(ResourceError(
         errorDomainBlinkInternal, 0, redirectResponse.url().getString(),
         accessControlErrorDescription));
     return false;
@@ -809,9 +794,7 @@
             accessControlErrorDescription, m_requestContext)) {
       reportResponseReceived(identifier, response);
 
-      ThreadableLoaderClient* client = m_client;
-      clear();
-      client->didFailAccessControlCheck(
+      dispatchDidFailAccessControlCheck(
           ResourceError(errorDomainBlinkInternal, 0, response.url().getString(),
                         accessControlErrorDescription));
       return;
@@ -868,7 +851,7 @@
   m_checker.notifyFinished(resource);
 
   if (resource->errorOccurred()) {
-    handleError(resource->resourceError());
+    dispatchDidFail(resource->resourceError());
   } else {
     handleSuccessfulFinish(resource->identifier(), resource->loadFinishTime());
   }
@@ -897,7 +880,16 @@
 }
 
 void DocumentThreadableLoader::didTimeout(TimerBase* timer) {
+  DCHECK(m_async);
   DCHECK_EQ(timer, &m_timeoutTimer);
+  // clearResource() may be called in clear() and some other places. clear()
+  // calls stop() on |m_timeoutTimer|. In the other places, the resource is set
+  // again. If the creation fails, clear() is called. So, here, resource() is
+  // always non-nullptr.
+  DCHECK(resource());
+  // When |m_client| is set to nullptr only in clear() where |m_timeoutTimer|
+  // is stopped. So, |m_client| is always non-nullptr here.
+  DCHECK(m_client);
 
   // Using values from net/base/net_error_list.h ERR_TIMED_OUT, Same as existing
   // FIXME above - this error should be coming from FrameLoaderClient to be
@@ -905,7 +897,8 @@
   static const int timeoutError = -7;
   ResourceError error("net", timeoutError, resource()->url(), String());
   error.setIsTimeout(true);
-  cancelWithError(error);
+
+  dispatchDidFail(error);
 }
 
 void DocumentThreadableLoader::loadFallbackRequestForServiceWorker() {
@@ -941,12 +934,17 @@
   // Prevent handleSuccessfulFinish() from bypassing access check.
   m_actualRequest = ResourceRequest();
 
+  dispatchDidFailAccessControlCheck(error);
+}
+
+void DocumentThreadableLoader::dispatchDidFailAccessControlCheck(
+    const ResourceError& error) {
   ThreadableLoaderClient* client = m_client;
   clear();
   client->didFailAccessControlCheck(error);
 }
 
-void DocumentThreadableLoader::handleError(const ResourceError& error) {
+void DocumentThreadableLoader::dispatchDidFail(const ResourceError& error) {
   ThreadableLoaderClient* client = m_client;
   clear();
   client->didFail(error);
diff --git a/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.h b/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.h
index 8af7fc9..bf1fb5c 100644
--- a/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.h
+++ b/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.h
@@ -110,8 +110,6 @@
   void dataDownloaded(Resource*, int) override;
   void didReceiveResourceTiming(Resource*, const ResourceTimingInfo&) override;
 
-  void cancelWithError(const ResourceError&);
-
   // Notify Inspector and log to console about resource response. Use this
   // method if response is not going to be finished normally.
   void reportResponseReceived(unsigned long identifier,
@@ -142,7 +140,9 @@
   // Investigates the response for the preflight request. If successful,
   // the actual request will be made later in handleSuccessfulFinish().
   void handlePreflightResponse(const ResourceResponse&);
-  void handleError(const ResourceError&);
+
+  void dispatchDidFailAccessControlCheck(const ResourceError&);
+  void dispatchDidFail(const ResourceError&);
 
   void loadRequestAsync(const ResourceRequest&, ResourceLoaderOptions);
   void loadRequestSync(const ResourceRequest&, ResourceLoaderOptions);
diff --git a/third_party/WebKit/Source/core/loader/FrameLoader.cpp b/third_party/WebKit/Source/core/loader/FrameLoader.cpp
index 4cbd51b..4ecd86a 100644
--- a/third_party/WebKit/Source/core/loader/FrameLoader.cpp
+++ b/third_party/WebKit/Source/core/loader/FrameLoader.cpp
@@ -515,7 +515,7 @@
 
   if (m_provisionalItem && isBackForwardLoadType(m_loadType)) {
     m_frame->document()->setStateForNewFormElements(
-        m_provisionalItem->documentState());
+        m_provisionalItem->getDocumentState());
   }
 }
 
@@ -747,7 +747,7 @@
     restoreScrollPositionAndViewState();
 
     m_loadType = FrameLoadTypeStandard;
-    m_frame->localDOMWindow()->finishedLoading();
+    m_frame->domWindow()->finishedLoading();
   }
 
   Frame* parent = m_frame->tree().parent();
@@ -870,7 +870,7 @@
     // If we were in the autoscroll/middleClickAutoscroll mode we want to stop
     // it before following the link to the anchor
     m_frame->eventHandler().stopAutoscroll();
-    m_frame->localDOMWindow()->enqueueHashchangeEvent(oldURL, url);
+    m_frame->domWindow()->enqueueHashchangeEvent(oldURL, url);
   }
   m_documentLoader->setIsClientRedirect(clientRedirect ==
                                         ClientRedirectPolicy::ClientRedirect);
@@ -882,9 +882,9 @@
 
   checkCompleted();
 
-  m_frame->localDOMWindow()->statePopped(
-      stateObject ? std::move(stateObject)
-                  : SerializedScriptValue::nullValue());
+  m_frame->domWindow()->statePopped(stateObject
+                                        ? std::move(stateObject)
+                                        : SerializedScriptValue::nullValue());
 
   if (historyLoadType == HistorySameDocumentLoad)
     restoreScrollPositionAndViewState();
diff --git a/third_party/WebKit/Source/core/loader/FrameLoaderClient.h b/third_party/WebKit/Source/core/loader/FrameLoaderClient.h
index 79694244..c445ac17 100644
--- a/third_party/WebKit/Source/core/loader/FrameLoaderClient.h
+++ b/third_party/WebKit/Source/core/loader/FrameLoaderClient.h
@@ -342,6 +342,8 @@
   // Overwrites the given URL to use an HTML5 embed if possible. An empty URL is
   // returned if the URL is not overriden.
   virtual KURL overrideFlashEmbedWithHTML(const KURL&) { return KURL(); }
+
+  virtual BlameContext* frameBlameContext() { return nullptr; }
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/loader/HistoryItem.cpp b/third_party/WebKit/Source/core/loader/HistoryItem.cpp
index 872b52e2..28340e4 100644
--- a/third_party/WebKit/Source/core/loader/HistoryItem.cpp
+++ b/third_party/WebKit/Source/core/loader/HistoryItem.cpp
@@ -118,14 +118,14 @@
   m_documentState = state;
 }
 
-const Vector<String>& HistoryItem::documentState() {
+const Vector<String>& HistoryItem::getDocumentState() {
   if (m_documentState)
     m_documentStateVector = m_documentState->toStateVector();
   return m_documentStateVector;
 }
 
 Vector<String> HistoryItem::getReferencedFilePaths() {
-  return FormController::getReferencedFilePaths(documentState());
+  return FormController::getReferencedFilePaths(getDocumentState());
 }
 
 void HistoryItem::clearDocumentState() {
diff --git a/third_party/WebKit/Source/core/loader/HistoryItem.h b/third_party/WebKit/Source/core/loader/HistoryItem.h
index a231512..35ca7fa 100644
--- a/third_party/WebKit/Source/core/loader/HistoryItem.h
+++ b/third_party/WebKit/Source/core/loader/HistoryItem.h
@@ -69,7 +69,7 @@
   void setPageScaleFactor(float);
 
   Vector<String> getReferencedFilePaths();
-  const Vector<String>& documentState();
+  const Vector<String>& getDocumentState();
   void setDocumentState(const Vector<String>&);
   void setDocumentState(DocumentState*);
   void clearDocumentState();
diff --git a/third_party/WebKit/Source/core/loader/PingLoader.cpp b/third_party/WebKit/Source/core/loader/PingLoader.cpp
index d32a134..956cc97 100644
--- a/third_party/WebKit/Source/core/loader/PingLoader.cpp
+++ b/third_party/WebKit/Source/core/loader/PingLoader.cpp
@@ -187,9 +187,7 @@
 };
 
 class PingLoaderImpl : public GarbageCollectedFinalized<PingLoaderImpl>,
-                       public DOMWindowProperty,
                        private WebURLLoaderClient {
-  USING_GARBAGE_COLLECTED_MIXIN(PingLoaderImpl);
   WTF_MAKE_NONCOPYABLE(PingLoaderImpl);
 
  public:
@@ -216,6 +214,7 @@
 
   void didFailLoading(LocalFrame*);
 
+  WeakMember<LocalFrame> m_frame;
   std::unique_ptr<WebURLLoader> m_loader;
   Timer<PingLoaderImpl> m_timeout;
   String m_url;
@@ -233,7 +232,7 @@
                                const AtomicString& initiator,
                                StoredCredentials credentialsAllowed,
                                bool isBeacon)
-    : DOMWindowProperty(frame),
+    : m_frame(frame),
       m_timeout(this, &PingLoaderImpl::timeout),
       m_url(request.url()),
       m_identifier(createUniqueIdentifier()),
@@ -313,9 +312,9 @@
   if (!CrossOriginAccessControl::handleRedirect(
           m_origin, newRequest, redirectResponse, AllowStoredCredentials,
           options, errorDescription)) {
-    if (LocalFrame* localFrame = frame()) {
-      if (localFrame->document()) {
-        localFrame->document()->addConsoleMessage(ConsoleMessage::create(
+    if (m_frame) {
+      if (m_frame->document()) {
+        m_frame->document()->addConsoleMessage(ConsoleMessage::create(
             JSMessageSource, ErrorMessageLevel, errorDescription));
       }
     }
@@ -331,31 +330,31 @@
 }
 
 void PingLoaderImpl::didReceiveResponse(const WebURLResponse& response) {
-  if (LocalFrame* frame = this->frame()) {
+  if (m_frame) {
     TRACE_EVENT1("devtools.timeline", "ResourceFinish", "data",
                  InspectorResourceFinishEvent::data(m_identifier, 0, true));
     const ResourceResponse& resourceResponse = response.toResourceResponse();
-    InspectorInstrumentation::didReceiveResourceResponse(frame, m_identifier, 0,
-                                                         resourceResponse, 0);
-    didFailLoading(frame);
+    InspectorInstrumentation::didReceiveResourceResponse(
+        m_frame, m_identifier, 0, resourceResponse, 0);
+    didFailLoading(m_frame);
   }
   dispose();
 }
 
 void PingLoaderImpl::didReceiveData(const char*, int) {
-  if (LocalFrame* frame = this->frame()) {
+  if (m_frame) {
     TRACE_EVENT1("devtools.timeline", "ResourceFinish", "data",
                  InspectorResourceFinishEvent::data(m_identifier, 0, true));
-    didFailLoading(frame);
+    didFailLoading(m_frame);
   }
   dispose();
 }
 
 void PingLoaderImpl::didFinishLoading(double, int64_t, int64_t) {
-  if (LocalFrame* frame = this->frame()) {
+  if (m_frame) {
     TRACE_EVENT1("devtools.timeline", "ResourceFinish", "data",
                  InspectorResourceFinishEvent::data(m_identifier, 0, true));
-    didFailLoading(frame);
+    didFailLoading(m_frame);
   }
   dispose();
 }
@@ -363,19 +362,19 @@
 void PingLoaderImpl::didFail(const WebURLError& resourceError,
                              int64_t,
                              int64_t) {
-  if (LocalFrame* frame = this->frame()) {
+  if (m_frame) {
     TRACE_EVENT1("devtools.timeline", "ResourceFinish", "data",
                  InspectorResourceFinishEvent::data(m_identifier, 0, true));
-    didFailLoading(frame);
+    didFailLoading(m_frame);
   }
   dispose();
 }
 
 void PingLoaderImpl::timeout(TimerBase*) {
-  if (LocalFrame* frame = this->frame()) {
+  if (m_frame) {
     TRACE_EVENT1("devtools.timeline", "ResourceFinish", "data",
                  InspectorResourceFinishEvent::data(m_identifier, 0, true));
-    didFailLoading(frame);
+    didFailLoading(m_frame);
   }
   dispose();
 }
@@ -388,7 +387,7 @@
 }
 
 DEFINE_TRACE(PingLoaderImpl) {
-  DOMWindowProperty::trace(visitor);
+  visitor->trace(m_frame);
 }
 
 void finishPingRequestInitialization(
diff --git a/third_party/WebKit/Source/core/loader/PingLoader.h b/third_party/WebKit/Source/core/loader/PingLoader.h
index ae6d269..8b8dd8e 100644
--- a/third_party/WebKit/Source/core/loader/PingLoader.h
+++ b/third_party/WebKit/Source/core/loader/PingLoader.h
@@ -34,7 +34,6 @@
 
 #include "core/CoreExport.h"
 #include "core/fetch/ResourceLoaderOptions.h"
-#include "core/frame/DOMWindowProperty.h"
 #include "platform/Timer.h"
 #include "platform/heap/Handle.h"
 #include "platform/heap/SelfKeepAlive.h"
diff --git a/third_party/WebKit/Source/core/page/Page.cpp b/third_party/WebKit/Source/core/page/Page.cpp
index 0fb7492..c16fb04 100644
--- a/third_party/WebKit/Source/core/page/Page.cpp
+++ b/third_party/WebKit/Source/core/page/Page.cpp
@@ -481,7 +481,7 @@
   }
 
   for (unsigned i = 0; i < frames.size(); ++i)
-    frames[i]->localDOMWindow()->acceptLanguagesChanged();
+    frames[i]->domWindow()->acceptLanguagesChanged();
 }
 
 DEFINE_TRACE(Page) {
diff --git a/third_party/WebKit/Source/core/paint/FilterPainter.cpp b/third_party/WebKit/Source/core/paint/FilterPainter.cpp
index 46e28f27..5646e1a 100644
--- a/third_party/WebKit/Source/core/paint/FilterPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/FilterPainter.cpp
@@ -56,7 +56,7 @@
   if (clipRect.rect() != paintingInfo.paintDirtyRect || clipRect.hasRadius()) {
     m_clipRecorder = WTF::wrapUnique(new LayerClipRecorder(
         context, *layer.layoutObject(), DisplayItem::kClipLayerFilter, clipRect,
-        &paintingInfo, LayoutPoint(), paintFlags));
+        paintingInfo.rootLayer, LayoutPoint(), paintFlags));
   }
 
   if (!context.getPaintController().displayItemConstructionIsDisabled()) {
diff --git a/third_party/WebKit/Source/core/paint/LayerClipRecorder.cpp b/third_party/WebKit/Source/core/paint/LayerClipRecorder.cpp
index bd8878a30..3d85217 100644
--- a/third_party/WebKit/Source/core/paint/LayerClipRecorder.cpp
+++ b/third_party/WebKit/Source/core/paint/LayerClipRecorder.cpp
@@ -15,24 +15,22 @@
 
 namespace blink {
 
-LayerClipRecorder::LayerClipRecorder(
-    GraphicsContext& graphicsContext,
-    const LayoutBoxModelObject& layoutObject,
-    DisplayItem::Type clipType,
-    const ClipRect& clipRect,
-    const PaintLayerPaintingInfo* localPaintingInfo,
-    const LayoutPoint& fragmentOffset,
-    PaintLayerFlags paintFlags,
-    BorderRadiusClippingRule rule)
+LayerClipRecorder::LayerClipRecorder(GraphicsContext& graphicsContext,
+                                     const LayoutBoxModelObject& layoutObject,
+                                     DisplayItem::Type clipType,
+                                     const ClipRect& clipRect,
+                                     const PaintLayer* clipRoot,
+                                     const LayoutPoint& fragmentOffset,
+                                     PaintLayerFlags paintFlags,
+                                     BorderRadiusClippingRule rule)
     : m_graphicsContext(graphicsContext),
       m_layoutObject(layoutObject),
       m_clipType(clipType) {
   IntRect snappedClipRect = pixelSnappedIntRect(clipRect.rect());
   Vector<FloatRoundedRect> roundedRects;
-  if (localPaintingInfo && clipRect.hasRadius()) {
-    collectRoundedRectClips(*layoutObject.layer(), *localPaintingInfo,
-                            graphicsContext, fragmentOffset, paintFlags, rule,
-                            roundedRects);
+  if (clipRoot && clipRect.hasRadius()) {
+    collectRoundedRectClips(*layoutObject.layer(), clipRoot, graphicsContext,
+                            fragmentOffset, paintFlags, rule, roundedRects);
   }
 
   m_graphicsContext.getPaintController().createAndAppend<ClipDisplayItem>(
@@ -58,7 +56,7 @@
 
 void LayerClipRecorder::collectRoundedRectClips(
     PaintLayer& paintLayer,
-    const PaintLayerPaintingInfo& localPaintingInfo,
+    const PaintLayer* clipRoot,
     GraphicsContext& context,
     const LayoutPoint& fragmentOffset,
     PaintLayerFlags paintFlags,
@@ -79,14 +77,15 @@
     // is properly clipped so that it can in turn clip the scrolled contents in
     // the compositor.
     if (layer->needsCompositedScrolling() &&
-        !(paintFlags & PaintLayerPaintingChildClippingMaskPhase))
+        !(paintFlags & PaintLayerPaintingChildClippingMaskPhase ||
+          paintFlags & PaintLayerPaintingAncestorClippingMaskPhase))
       break;
 
     if (layer->layoutObject()->hasOverflowClip() &&
         layer->layoutObject()->style()->hasBorderRadius() &&
         inContainingBlockChain(&paintLayer, layer)) {
       LayoutPoint delta(fragmentOffset);
-      layer->convertToLayerCoords(localPaintingInfo.rootLayer, delta);
+      layer->convertToLayerCoords(clipRoot, delta);
 
       // The PaintLayer's size is pixel-snapped if it is a LayoutBox. We can't
       // use a pre-snapped border rect for clipping, since
@@ -99,7 +98,7 @@
               LayoutRect(delta, size)));
     }
 
-    if (layer == localPaintingInfo.rootLayer)
+    if (layer == clipRoot)
       break;
   }
 }
diff --git a/third_party/WebKit/Source/core/paint/LayerClipRecorder.h b/third_party/WebKit/Source/core/paint/LayerClipRecorder.h
index b8e3aca..7601ca2a0 100644
--- a/third_party/WebKit/Source/core/paint/LayerClipRecorder.h
+++ b/third_party/WebKit/Source/core/paint/LayerClipRecorder.h
@@ -46,7 +46,7 @@
       const LayoutBoxModelObject&,
       DisplayItem::Type,
       const ClipRect&,
-      const PaintLayerPaintingInfo* localPaintingInfo,
+      const PaintLayer* clipRoot,
       const LayoutPoint& fragmentOffset,
       PaintLayerFlags,
       BorderRadiusClippingRule = IncludeSelfForBorderRadius);
@@ -55,7 +55,7 @@
 
  private:
   void collectRoundedRectClips(PaintLayer&,
-                               const PaintLayerPaintingInfo& localPaintingInfo,
+                               const PaintLayer* clipRoot,
                                GraphicsContext&,
                                const LayoutPoint& fragmentOffset,
                                PaintLayerFlags,
diff --git a/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.cpp b/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.cpp
index abca3af..256584c 100644
--- a/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintControllerPaintTest.cpp
@@ -32,17 +32,26 @@
       *toLayoutText(div.firstChild()->layoutObject())->firstTextBox();
 
   if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
-    EXPECT_DISPLAY_LIST(
-        rootPaintController().getDisplayItemList(), 6,
-        TestDisplayItem(layoutView(),
-                        DisplayItem::kClipFrameToVisibleContentRect),
-        TestDisplayItem(*layoutView().layer(), DisplayItem::kSubsequence),
-        TestDisplayItem(layoutView(), documentBackgroundType),
-        TestDisplayItem(textInlineBox, foregroundType),
-        TestDisplayItem(*layoutView().layer(), DisplayItem::kEndSubsequence),
-        TestDisplayItem(layoutView(),
-                        DisplayItem::clipTypeToEndClipType(
-                            DisplayItem::kClipFrameToVisibleContentRect)));
+    if (RuntimeEnabledFeatures::rootLayerScrollingEnabled()) {
+      EXPECT_DISPLAY_LIST(
+          rootPaintController().getDisplayItemList(), 4,
+          TestDisplayItem(*layoutView().layer(), DisplayItem::kSubsequence),
+          TestDisplayItem(layoutView(), documentBackgroundType),
+          TestDisplayItem(textInlineBox, foregroundType),
+          TestDisplayItem(*layoutView().layer(), DisplayItem::kEndSubsequence));
+    } else {
+      EXPECT_DISPLAY_LIST(
+          rootPaintController().getDisplayItemList(), 6,
+          TestDisplayItem(layoutView(),
+                          DisplayItem::kClipFrameToVisibleContentRect),
+          TestDisplayItem(*layoutView().layer(), DisplayItem::kSubsequence),
+          TestDisplayItem(layoutView(), documentBackgroundType),
+          TestDisplayItem(textInlineBox, foregroundType),
+          TestDisplayItem(*layoutView().layer(), DisplayItem::kEndSubsequence),
+          TestDisplayItem(layoutView(),
+                          DisplayItem::clipTypeToEndClipType(
+                              DisplayItem::kClipFrameToVisibleContentRect)));
+    }
   } else {
     EXPECT_DISPLAY_LIST(rootPaintController().getDisplayItemList(), 2,
                         TestDisplayItem(layoutView(), documentBackgroundType),
@@ -53,19 +62,30 @@
   document().view()->updateAllLifecyclePhases();
 
   if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
-    EXPECT_DISPLAY_LIST(
-        rootPaintController().getDisplayItemList(), 7,
-        TestDisplayItem(layoutView(),
-                        DisplayItem::kClipFrameToVisibleContentRect),
-        TestDisplayItem(*layoutView().layer(), DisplayItem::kSubsequence),
-        TestDisplayItem(layoutView(), documentBackgroundType),
-        TestDisplayItem(textInlineBox, foregroundType),
-        TestDisplayItem(*document().frame()->selection().m_frameCaret,
-                        DisplayItem::kCaret),  // New!
-        TestDisplayItem(*layoutView().layer(), DisplayItem::kEndSubsequence),
-        TestDisplayItem(layoutView(),
-                        DisplayItem::clipTypeToEndClipType(
-                            DisplayItem::kClipFrameToVisibleContentRect)));
+    if (RuntimeEnabledFeatures::rootLayerScrollingEnabled()) {
+      EXPECT_DISPLAY_LIST(
+          rootPaintController().getDisplayItemList(), 5,
+          TestDisplayItem(*layoutView().layer(), DisplayItem::kSubsequence),
+          TestDisplayItem(layoutView(), documentBackgroundType),
+          TestDisplayItem(textInlineBox, foregroundType),
+          TestDisplayItem(*document().frame()->selection().m_frameCaret,
+                          DisplayItem::kCaret),  // New!
+          TestDisplayItem(*layoutView().layer(), DisplayItem::kEndSubsequence));
+    } else {
+      EXPECT_DISPLAY_LIST(
+          rootPaintController().getDisplayItemList(), 7,
+          TestDisplayItem(layoutView(),
+                          DisplayItem::kClipFrameToVisibleContentRect),
+          TestDisplayItem(*layoutView().layer(), DisplayItem::kSubsequence),
+          TestDisplayItem(layoutView(), documentBackgroundType),
+          TestDisplayItem(textInlineBox, foregroundType),
+          TestDisplayItem(*document().frame()->selection().m_frameCaret,
+                          DisplayItem::kCaret),  // New!
+          TestDisplayItem(*layoutView().layer(), DisplayItem::kEndSubsequence),
+          TestDisplayItem(layoutView(),
+                          DisplayItem::clipTypeToEndClipType(
+                              DisplayItem::kClipFrameToVisibleContentRect)));
+    }
   } else {
     EXPECT_DISPLAY_LIST(
         rootPaintController().getDisplayItemList(), 3,
@@ -87,17 +107,26 @@
   InlineTextBox& firstTextBox = *text.firstTextBox();
 
   if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
-    EXPECT_DISPLAY_LIST(
-        rootPaintController().getDisplayItemList(), 6,
-        TestDisplayItem(layoutView(),
-                        DisplayItem::kClipFrameToVisibleContentRect),
-        TestDisplayItem(*layoutView().layer(), DisplayItem::kSubsequence),
-        TestDisplayItem(layoutView(), documentBackgroundType),
-        TestDisplayItem(firstTextBox, foregroundType),
-        TestDisplayItem(*layoutView().layer(), DisplayItem::kEndSubsequence),
-        TestDisplayItem(layoutView(),
-                        DisplayItem::clipTypeToEndClipType(
-                            DisplayItem::kClipFrameToVisibleContentRect)));
+    if (RuntimeEnabledFeatures::rootLayerScrollingEnabled()) {
+      EXPECT_DISPLAY_LIST(
+          rootPaintController().getDisplayItemList(), 4,
+          TestDisplayItem(*layoutView().layer(), DisplayItem::kSubsequence),
+          TestDisplayItem(layoutView(), documentBackgroundType),
+          TestDisplayItem(firstTextBox, foregroundType),
+          TestDisplayItem(*layoutView().layer(), DisplayItem::kEndSubsequence));
+    } else {
+      EXPECT_DISPLAY_LIST(
+          rootPaintController().getDisplayItemList(), 6,
+          TestDisplayItem(layoutView(),
+                          DisplayItem::kClipFrameToVisibleContentRect),
+          TestDisplayItem(*layoutView().layer(), DisplayItem::kSubsequence),
+          TestDisplayItem(layoutView(), documentBackgroundType),
+          TestDisplayItem(firstTextBox, foregroundType),
+          TestDisplayItem(*layoutView().layer(), DisplayItem::kEndSubsequence),
+          TestDisplayItem(layoutView(),
+                          DisplayItem::clipTypeToEndClipType(
+                              DisplayItem::kClipFrameToVisibleContentRect)));
+    }
   } else {
     EXPECT_DISPLAY_LIST(rootPaintController().getDisplayItemList(), 2,
                         TestDisplayItem(layoutView(), documentBackgroundType),
@@ -112,18 +141,28 @@
   InlineTextBox& secondTextBox = *newText.firstTextBox()->nextTextBox();
 
   if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
-    EXPECT_DISPLAY_LIST(
-        rootPaintController().getDisplayItemList(), 7,
-        TestDisplayItem(layoutView(),
-                        DisplayItem::kClipFrameToVisibleContentRect),
-        TestDisplayItem(*layoutView().layer(), DisplayItem::kSubsequence),
-        TestDisplayItem(layoutView(), documentBackgroundType),
-        TestDisplayItem(newFirstTextBox, foregroundType),
-        TestDisplayItem(secondTextBox, foregroundType),
-        TestDisplayItem(*layoutView().layer(), DisplayItem::kEndSubsequence),
-        TestDisplayItem(layoutView(),
-                        DisplayItem::clipTypeToEndClipType(
-                            DisplayItem::kClipFrameToVisibleContentRect)));
+    if (RuntimeEnabledFeatures::rootLayerScrollingEnabled()) {
+      EXPECT_DISPLAY_LIST(
+          rootPaintController().getDisplayItemList(), 5,
+          TestDisplayItem(*layoutView().layer(), DisplayItem::kSubsequence),
+          TestDisplayItem(layoutView(), documentBackgroundType),
+          TestDisplayItem(newFirstTextBox, foregroundType),
+          TestDisplayItem(secondTextBox, foregroundType),
+          TestDisplayItem(*layoutView().layer(), DisplayItem::kEndSubsequence));
+    } else {
+      EXPECT_DISPLAY_LIST(
+          rootPaintController().getDisplayItemList(), 7,
+          TestDisplayItem(layoutView(),
+                          DisplayItem::kClipFrameToVisibleContentRect),
+          TestDisplayItem(*layoutView().layer(), DisplayItem::kSubsequence),
+          TestDisplayItem(layoutView(), documentBackgroundType),
+          TestDisplayItem(newFirstTextBox, foregroundType),
+          TestDisplayItem(secondTextBox, foregroundType),
+          TestDisplayItem(*layoutView().layer(), DisplayItem::kEndSubsequence),
+          TestDisplayItem(layoutView(),
+                          DisplayItem::clipTypeToEndClipType(
+                              DisplayItem::kClipFrameToVisibleContentRect)));
+    }
   } else {
     EXPECT_DISPLAY_LIST(rootPaintController().getDisplayItemList(), 3,
                         TestDisplayItem(layoutView(), documentBackgroundType),
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerClipper.h b/third_party/WebKit/Source/core/paint/PaintLayerClipper.h
index 51232a6..df71e64 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayerClipper.h
+++ b/third_party/WebKit/Source/core/paint/PaintLayerClipper.h
@@ -182,7 +182,7 @@
   LayoutRect localClipRect(const PaintLayer* ancestorLayer) const;
 
   // Computes the same thing as backgroundRect in calculateRects(), but skips
-  // apllying CSS clip and the visualOverflowRect() of |m_layer|.
+  // applying CSS clip and the visualOverflowRect() of |m_layer|.
   ClipRect backgroundClipRect(const ClipRectsContext&) const;
 
   // This method figures out our layerBounds in coordinates relative to
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp b/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp
index 18d5d0ad..e5cafe6 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp
@@ -371,7 +371,8 @@
   // scrolling contents and scrollbars.
   if (m_paintLayer.layoutObject()->hasClipPath() &&
       (!m_paintLayer.needsCompositedScrolling() ||
-       (paintFlags & PaintLayerPaintingChildClippingMaskPhase))) {
+       (paintFlags & (PaintLayerPaintingChildClippingMaskPhase |
+                      PaintLayerPaintingAncestorClippingMaskPhase)))) {
     paintingInfo.ancestorHasClipPathClipping = true;
 
     LayoutRect referenceBox(m_paintLayer.boxForClipPath());
@@ -427,22 +428,51 @@
     ClipRectsCacheSlot cacheSlot = (paintFlags & PaintLayerUncachedClipRects)
                                        ? UncachedClipRects
                                        : PaintingClipRects;
+    LayoutPoint offsetToClipper;
+    PaintLayer* paintLayerForFragments = &m_paintLayer;
+    if (paintFlags & PaintLayerPaintingAncestorClippingMaskPhase) {
+      // Compute fragments and their clips with respect to the clipping
+      // container. The paint rect is in this layer's space, so convert it
+      // to the clipper's layer's space. The rootLayer is also changed to
+      // the clipper's layer to simplify coordinate system adjustments.
+      // The change to rootLayer must persist to correctly record the clips.
+      paintLayerForFragments =
+          m_paintLayer.clippingContainer()->enclosingLayer();
+      localPaintingInfo.rootLayer = paintLayerForFragments;
+      m_paintLayer.convertToLayerCoords(localPaintingInfo.rootLayer,
+                                        offsetToClipper);
+      localPaintingInfo.paintDirtyRect.moveBy(offsetToClipper);
+    }
+
     // TODO(trchen): We haven't decided how to handle visual fragmentation with
     // SPv2.  Related thread
     // https://groups.google.com/a/chromium.org/forum/#!topic/graphics-dev/81XuWFf-mxM
     if (fragmentPolicy == ForceSingleFragment ||
-        RuntimeEnabledFeatures::slimmingPaintV2Enabled())
-      m_paintLayer.appendSingleFragmentIgnoringPagination(
+        RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
+      paintLayerForFragments->appendSingleFragmentIgnoringPagination(
           layerFragments, localPaintingInfo.rootLayer,
           localPaintingInfo.paintDirtyRect, cacheSlot,
           IgnoreOverlayScrollbarSize, respectOverflowClip, &offsetFromRoot,
           localPaintingInfo.subPixelAccumulation);
-    else
-      m_paintLayer.collectFragments(layerFragments, localPaintingInfo.rootLayer,
-                                    localPaintingInfo.paintDirtyRect, cacheSlot,
-                                    IgnoreOverlayScrollbarSize,
-                                    respectOverflowClip, &offsetFromRoot,
-                                    localPaintingInfo.subPixelAccumulation);
+    } else {
+      paintLayerForFragments->collectFragments(
+          layerFragments, localPaintingInfo.rootLayer,
+          localPaintingInfo.paintDirtyRect, cacheSlot,
+          IgnoreOverlayScrollbarSize, respectOverflowClip, &offsetFromRoot,
+          localPaintingInfo.subPixelAccumulation);
+    }
+
+    if (paintFlags & PaintLayerPaintingAncestorClippingMaskPhase) {
+      // Fragment offsets have been computed in the clipping container's
+      // layer's coordinate system, but for the rest of painting we need
+      // them in the layer coordinate. So move them and the foreground rect
+      // that is also in the clipper's space.
+      LayoutSize negativeOffset(-offsetToClipper.x(), -offsetToClipper.y());
+      for (auto& fragment : layerFragments) {
+        fragment.foregroundRect.move(negativeOffset);
+        fragment.paginationOffset.move(negativeOffset);
+      }
+    }
 
     if (shouldPaintContent) {
       // TODO(wangxianzhu): This is for old slow scrolling. Implement similar
@@ -546,7 +576,8 @@
       shouldPaintContent && m_paintLayer.layoutObject()->hasMask() &&
       !selectionOnly;
   bool shouldPaintClippingMask =
-      (paintFlags & PaintLayerPaintingChildClippingMaskPhase) &&
+      (paintFlags & (PaintLayerPaintingChildClippingMaskPhase |
+                     PaintLayerPaintingAncestorClippingMaskPhase)) &&
       shouldPaintContent && !selectionOnly;
 
   if (shouldPaintMask)
@@ -721,7 +752,7 @@
                             UseCounter::ClipCssOfFixedPositionElement);
         clipRecorder.emplace(context, *parentLayer->layoutObject(),
                              DisplayItem::kClipLayerParent, clipRectForFragment,
-                             &paintingInfo, fragment.paginationOffset,
+                             paintingInfo.rootLayer, fragment.paginationOffset,
                              paintFlags);
       }
     }
@@ -859,7 +890,7 @@
     if (needsToClip(localPaintingInfo, fragment.backgroundRect)) {
       clipRecorder.emplace(context, *m_paintLayer.layoutObject(),
                            DisplayItem::kClipLayerOverflowControls,
-                           fragment.backgroundRect, &localPaintingInfo,
+                           fragment.backgroundRect, localPaintingInfo.rootLayer,
                            fragment.paginationOffset, paintFlags);
     }
 
@@ -909,9 +940,12 @@
         break;
     }
 
+    // TODO(schenney): Nested border-radius clips are not applied to composited
+    // children, probably due to an incorrect clipRoot.
+    // https://bugs.chromium.org/p/chromium/issues/detail?id=672561
     clipRecorder.emplace(context, *m_paintLayer.layoutObject(), clipType,
-                         clipRect, &paintingInfo, fragment.paginationOffset,
-                         paintFlags, clippingRule);
+                         clipRect, paintingInfo.rootLayer,
+                         fragment.paginationOffset, paintFlags, clippingRule);
   }
 
   LayoutRect newCullRect(clipRect.rect());
@@ -983,7 +1017,8 @@
       needsToClip(localPaintingInfo, layerFragments[0].foregroundRect)) {
     clipRecorder.emplace(context, *m_paintLayer.layoutObject(),
                          DisplayItem::kClipLayerForeground,
-                         layerFragments[0].foregroundRect, &localPaintingInfo,
+                         layerFragments[0].foregroundRect,
+                         localPaintingInfo.rootLayer,
                          layerFragments[0].paginationOffset, paintFlags);
     clipState = HasClipped;
   }
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerPaintingInfo.h b/third_party/WebKit/Source/core/paint/PaintLayerPaintingInfo.h
index d907091..f0980bc 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayerPaintingInfo.h
+++ b/third_party/WebKit/Source/core/paint/PaintLayerPaintingInfo.h
@@ -67,8 +67,9 @@
   PaintLayerPaintingRootBackgroundOnly = 1 << 9,
   PaintLayerPaintingSkipRootBackground = 1 << 10,
   PaintLayerPaintingChildClippingMaskPhase = 1 << 11,
-  PaintLayerPaintingRenderingClipPathAsMask = 1 << 12,
-  PaintLayerPaintingCompositingDecorationPhase = 1 << 13,
+  PaintLayerPaintingAncestorClippingMaskPhase = 1 << 12,
+  PaintLayerPaintingRenderingClipPathAsMask = 1 << 13,
+  PaintLayerPaintingCompositingDecorationPhase = 1 << 14,
   PaintLayerPaintingCompositingAllPhases =
       (PaintLayerPaintingCompositingBackgroundPhase |
        PaintLayerPaintingCompositingForegroundPhase |
diff --git a/third_party/WebKit/Source/core/svg/SVGElement.cpp b/third_party/WebKit/Source/core/svg/SVGElement.cpp
index 41faa266..967313ce 100644
--- a/third_party/WebKit/Source/core/svg/SVGElement.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGElement.cpp
@@ -331,42 +331,40 @@
     TransformationMatrix transform;
     float zoom = style->effectiveZoom();
 
+    FloatRect boundingBox = layoutObject()->objectBoundingBox();
+    ComputedStyle::ApplyTransformOrigin applyTransformOrigin =
+        ComputedStyle::IncludeTransformOrigin;
     // SVGTextElements need special handling for the text positioning code.
     if (isSVGTextElement(this)) {
-      // Do not take into account SVG's zoom rules, transform-origin, or
-      // percentage values.
+      // Do not take into account transform-origin, or percentage values.
+      boundingBox = FloatRect();
+      applyTransformOrigin = ComputedStyle::ExcludeTransformOrigin;
+    }
+
+    // CSS transforms operate with pre-scaled lengths. To make this work with
+    // SVG (which applies the zoom factor globally, at the root level) we
+    //
+    //   * pre-scale the bounding box (to bring it into the same space as the
+    //     other CSS values)
+    //   * invert the zoom factor (to effectively compute the CSS transform
+    //     under a 1.0 zoom)
+    //
+    // Note: objectBoundingBox is an emptyRect for elements like pattern or
+    // clipPath. See the "Object bounding box units" section of
+    // http://dev.w3.org/csswg/css3-transforms/
+    if (zoom != 1) {
+      boundingBox.scale(zoom);
+      transform.scale(1 / zoom);
       style->applyTransform(
-          transform, LayoutSize(0, 0), ComputedStyle::ExcludeTransformOrigin,
+          transform, boundingBox, applyTransformOrigin,
           ComputedStyle::IncludeMotionPath,
           ComputedStyle::IncludeIndependentTransformProperties);
+      transform.scale(zoom);
     } else {
-      // CSS transforms operate with pre-scaled lengths. To make this work with
-      // SVG (which applies the zoom factor globally, at the root level) we
-      //
-      //   * pre-scale the bounding box (to bring it into the same space as the
-      //     other CSS values)
-      //   * invert the zoom factor (to effectively compute the CSS transform
-      //     under a 1.0 zoom)
-      //
-      // Note: objectBoundingBox is an emptyRect for elements like pattern or
-      // clipPath.  See the "Object bounding box units" section of
-      // http://dev.w3.org/csswg/css3-transforms/
-      if (zoom != 1) {
-        FloatRect scaledBBox = layoutObject()->objectBoundingBox();
-        scaledBBox.scale(zoom);
-        transform.scale(1 / zoom);
-        style->applyTransform(
-            transform, scaledBBox, ComputedStyle::IncludeTransformOrigin,
-            ComputedStyle::IncludeMotionPath,
-            ComputedStyle::IncludeIndependentTransformProperties);
-        transform.scale(zoom);
-      } else {
-        style->applyTransform(
-            transform, layoutObject()->objectBoundingBox(),
-            ComputedStyle::IncludeTransformOrigin,
-            ComputedStyle::IncludeMotionPath,
-            ComputedStyle::IncludeIndependentTransformProperties);
-      }
+      style->applyTransform(
+          transform, boundingBox, applyTransformOrigin,
+          ComputedStyle::IncludeMotionPath,
+          ComputedStyle::IncludeIndependentTransformProperties);
     }
     // Flatten any 3D transform.
     matrix = transform.toAffineTransform();
diff --git a/third_party/WebKit/Source/core/svg/SVGMarkerElement.cpp b/third_party/WebKit/Source/core/svg/SVGMarkerElement.cpp
index 55a4970..06e7d146 100644
--- a/third_party/WebKit/Source/core/svg/SVGMarkerElement.cpp
+++ b/third_party/WebKit/Source/core/svg/SVGMarkerElement.cpp
@@ -99,22 +99,26 @@
 }
 
 void SVGMarkerElement::svgAttributeChanged(const QualifiedName& attrName) {
-  bool isLengthAttr = attrName == SVGNames::refXAttr ||
-                      attrName == SVGNames::refYAttr ||
-                      attrName == SVGNames::markerWidthAttr ||
-                      attrName == SVGNames::markerHeightAttr;
-
-  if (isLengthAttr)
+  bool viewboxAttributeChanged = SVGFitToViewBox::isKnownAttribute(attrName);
+  bool lengthAttributeChanged = attrName == SVGNames::refXAttr ||
+                                attrName == SVGNames::refYAttr ||
+                                attrName == SVGNames::markerWidthAttr ||
+                                attrName == SVGNames::markerHeightAttr;
+  if (lengthAttributeChanged)
     updateRelativeLengthsInformation();
 
-  if (isLengthAttr || attrName == SVGNames::markerUnitsAttr ||
-      attrName == SVGNames::orientAttr ||
-      SVGFitToViewBox::isKnownAttribute(attrName)) {
+  if (viewboxAttributeChanged || lengthAttributeChanged ||
+      attrName == SVGNames::markerUnitsAttr ||
+      attrName == SVGNames::orientAttr) {
     SVGElement::InvalidationGuard invalidationGuard(this);
-    LayoutSVGResourceContainer* layoutObject =
-        toLayoutSVGResourceContainer(this->layoutObject());
-    if (layoutObject)
-      layoutObject->invalidateCacheAndMarkForLayout();
+    auto* resourceContainer = toLayoutSVGResourceContainer(layoutObject());
+    if (resourceContainer) {
+      // The marker transform depends on both viewbox attributes, and the marker
+      // size attributes (width, height).
+      if (viewboxAttributeChanged || lengthAttributeChanged)
+        resourceContainer->setNeedsTransformUpdate();
+      resourceContainer->invalidateCacheAndMarkForLayout();
+    }
 
     return;
   }
diff --git a/third_party/WebKit/Source/core/testing/Internals.cpp b/third_party/WebKit/Source/core/testing/Internals.cpp
index 3c842d1..4fc499f 100644
--- a/third_party/WebKit/Source/core/testing/Internals.cpp
+++ b/third_party/WebKit/Source/core/testing/Internals.cpp
@@ -869,7 +869,7 @@
                                      "No history item is available.");
     return Vector<String>();
   }
-  return mainItem->documentState();
+  return mainItem->getDocumentState();
 }
 
 void Internals::setFormControlStateOfHistoryItem(
diff --git a/third_party/WebKit/Source/core/timing/PerformanceBase.cpp b/third_party/WebKit/Source/core/timing/PerformanceBase.cpp
index 39a7e30..f4f2607a 100644
--- a/third_party/WebKit/Source/core/timing/PerformanceBase.cpp
+++ b/third_party/WebKit/Source/core/timing/PerformanceBase.cpp
@@ -336,12 +336,17 @@
   DCHECK(frame);
   const DocumentLoader* documentLoader = frame->loader().documentLoader();
   DCHECK(documentLoader);
+
   const DocumentLoadTiming& documentLoadTiming = documentLoader->timing();
 
   const DocumentTiming* documentTiming =
       frame->document() ? &(frame->document()->timing()) : nullptr;
 
   const ResourceResponse& finalResponse = documentLoader->response();
+  ResourceTimingInfo* navigationTimingInfo =
+      documentLoader->getNavigationTimingInfo();
+  if (!navigationTimingInfo)
+    return;
 
   ResourceLoadTiming* resourceLoadTiming = finalResponse.resourceLoadTiming();
   // Don't create a navigation timing instance when
@@ -352,8 +357,7 @@
   double lastRedirectEndTime = documentLoadTiming.redirectEnd();
   double finishTime = documentLoadTiming.loadEventEnd();
 
-  // TODO(sunjian) Implement transfer size. crbug/663187
-  unsigned long long transferSize = 0;
+  unsigned long long transferSize = navigationTimingInfo->transferSize();
   unsigned long long encodedBodyLength = finalResponse.encodedBodyLength();
   unsigned long long decodedBodyLength = finalResponse.decodedBodyLength();
   bool didReuseConnection = finalResponse.connectionReused();
diff --git a/third_party/WebKit/Source/core/xml/XSLTProcessor.cpp b/third_party/WebKit/Source/core/xml/XSLTProcessor.cpp
index b8fb6995..c2aaba3 100644
--- a/third_party/WebKit/Source/core/xml/XSLTProcessor.cpp
+++ b/third_party/WebKit/Source/core/xml/XSLTProcessor.cpp
@@ -84,8 +84,8 @@
     // Re-create the FrameView if needed.
     if (hasView)
       frame->loader().client()->transitionToCommittedForNewPage();
-    result = frame->localDOMWindow()->installNewDocument(sourceMIMEType, init,
-                                                         forceXHTML);
+    result = frame->domWindow()->installNewDocument(sourceMIMEType, init,
+                                                    forceXHTML);
 
     if (oldDocument) {
       DocumentXSLT::from(*result).setTransformSourceDocument(oldDocument);
diff --git a/third_party/WebKit/Source/devtools/.eslintignore b/third_party/WebKit/Source/devtools/.eslintignore
index 1df83afc..0f522c2 100644
--- a/third_party/WebKit/Source/devtools/.eslintignore
+++ b/third_party/WebKit/Source/devtools/.eslintignore
@@ -9,3 +9,4 @@
 front_end/InspectorBackendCommands.js
 front_end/SupportedCSSProperties.js
 front_end/terminal/xterm.js/**
+front_end/protocol_externs.js
diff --git a/third_party/WebKit/Source/devtools/BUILD.gn b/third_party/WebKit/Source/devtools/BUILD.gn
index 5df7907..9131241e 100644
--- a/third_party/WebKit/Source/devtools/BUILD.gn
+++ b/third_party/WebKit/Source/devtools/BUILD.gn
@@ -738,6 +738,7 @@
 devtools_timeline_js_files = [
   "front_end/timeline/invalidationsTree.css",
   "front_end/timeline/timelineFlamechartPopover.css",
+  "front_end/timeline/timelineLandingPage.css",
   "front_end/timeline/timelinePaintProfiler.css",
   "front_end/timeline/timelinePanel.css",
   "front_end/timeline/timelineStatusDialog.css",
@@ -748,6 +749,7 @@
   "front_end/timeline/TimelineFlameChart.js",
   "front_end/timeline/TimelineFlameChartView.js",
   "front_end/timeline/TimelineNetworkFlameChart.js",
+  "front_end/timeline/TimelineLandingPage.js",
   "front_end/timeline/TimelineLayersView.js",
   "front_end/timeline/TimelineLoader.js",
   "front_end/timeline/TimelinePaintProfilerView.js",
diff --git a/third_party/WebKit/Source/devtools/front_end/animation/AnimationTimeline.js b/third_party/WebKit/Source/devtools/front_end/animation/AnimationTimeline.js
index 643e914..fc102c3 100644
--- a/third_party/WebKit/Source/devtools/front_end/animation/AnimationTimeline.js
+++ b/third_party/WebKit/Source/devtools/front_end/animation/AnimationTimeline.js
@@ -112,12 +112,12 @@
     var toolbarContainer = this.contentElement.createChild('div', 'animation-timeline-toolbar-container');
     var topToolbar = new UI.Toolbar('animation-timeline-toolbar', toolbarContainer);
     var clearButton = new UI.ToolbarButton(Common.UIString('Clear all'), 'largeicon-clear');
-    clearButton.addEventListener('click', this._reset.bind(this));
+    clearButton.addEventListener(UI.ToolbarButton.Events.Click, this._reset.bind(this));
     topToolbar.appendToolbarItem(clearButton);
     topToolbar.appendSeparator();
 
     this._pauseButton = new UI.ToolbarToggle(Common.UIString('Pause all'), 'largeicon-pause', 'largeicon-resume');
-    this._pauseButton.addEventListener('click', this._togglePauseAll.bind(this));
+    this._pauseButton.addEventListener(UI.ToolbarButton.Events.Click, this._togglePauseAll.bind(this));
     topToolbar.appendToolbarItem(this._pauseButton);
 
     var playbackRateControl = toolbarContainer.createChild('div', 'animation-playback-rate-control');
@@ -147,7 +147,7 @@
     this._controlButton = new UI.ToolbarToggle(Common.UIString('Replay timeline'), 'largeicon-replay-animation');
     this._controlState = Animation.AnimationTimeline._ControlState.Replay;
     this._controlButton.setToggled(true);
-    this._controlButton.addEventListener('click', this._controlButtonToggle.bind(this));
+    this._controlButton.addEventListener(UI.ToolbarButton.Events.Click, this._controlButtonToggle.bind(this));
     toolbar.appendToolbarItem(this._controlButton);
 
     var gridHeader = container.createChild('div', 'animation-grid-header');
diff --git a/third_party/WebKit/Source/devtools/front_end/bindings/DebuggerWorkspaceBinding.js b/third_party/WebKit/Source/devtools/front_end/bindings/DebuggerWorkspaceBinding.js
index 72c0494..5d5080c9 100644
--- a/third_party/WebKit/Source/devtools/front_end/bindings/DebuggerWorkspaceBinding.js
+++ b/third_party/WebKit/Source/devtools/front_end/bindings/DebuggerWorkspaceBinding.js
@@ -21,8 +21,6 @@
     targetManager.addModelListener(
         SDK.DebuggerModel, SDK.DebuggerModel.Events.GlobalObjectCleared, this._globalObjectCleared, this);
     targetManager.addModelListener(
-        SDK.DebuggerModel, SDK.DebuggerModel.Events.BeforeDebuggerPaused, this._beforeDebuggerPaused, this);
-    targetManager.addModelListener(
         SDK.DebuggerModel, SDK.DebuggerModel.Events.DebuggerResumed, this._debuggerResumed, this);
     workspace.addEventListener(Workspace.Workspace.Events.UISourceCodeRemoved, this._uiSourceCodeRemoved, this);
     workspace.addEventListener(Workspace.Workspace.Events.ProjectRemoved, this._projectRemoved, this);
@@ -327,18 +325,6 @@
     var debuggerModel = /** @type {!SDK.DebuggerModel} */ (event.target);
     this._reset(debuggerModel.target());
   }
-
-  /**
-   * @param {!Common.Event} event
-   */
-  _beforeDebuggerPaused(event) {
-    var rawLocation = event.data.callFrames[0].location();
-    var targetData = this._targetToData.get(rawLocation.target());
-    if (!targetData._compilerMapping.mapsToSourceCode(rawLocation)) {
-      event.stopPropagation();
-      event.preventDefault();
-    }
-  }
 };
 
 /**
@@ -350,7 +336,7 @@
    * @param {!Bindings.DebuggerWorkspaceBinding} debuggerWorkspaceBinding
    */
   constructor(debuggerModel, debuggerWorkspaceBinding) {
-    this._target = debuggerModel.target();
+    this._debuggerModel = debuggerModel;
 
     /** @type {!Map.<string, !Bindings.DebuggerWorkspaceBinding.ScriptInfo>} */
     this.scriptDataMap = new Map();
@@ -363,11 +349,13 @@
     this._defaultMapping = new Bindings.DefaultScriptMapping(debuggerModel, workspace, debuggerWorkspaceBinding);
     this._resourceMapping = new Bindings.ResourceScriptMapping(debuggerModel, workspace, debuggerWorkspaceBinding);
     this._compilerMapping = new Bindings.CompilerScriptMapping(
-        debuggerModel, workspace, Bindings.NetworkProject.forTarget(this._target), debuggerWorkspaceBinding);
+        debuggerModel, workspace, Bindings.NetworkProject.forTarget(this._debuggerModel.target()),
+        debuggerWorkspaceBinding);
 
     /** @type {!Map.<!Workspace.UISourceCode, !Bindings.DebuggerSourceMapping>} */
     this._uiSourceCodeToSourceMapping = new Map();
 
+    debuggerModel.setBeforePausedCallback(this._beforePaused.bind(this));
     this._eventListeners = [
       debuggerModel.addEventListener(SDK.DebuggerModel.Events.ParsedScriptSource, this._parsedScriptSource, this),
       debuggerModel.addEventListener(SDK.DebuggerModel.Events.FailedToParseScriptSource, this._parsedScriptSource, this)
@@ -375,6 +363,14 @@
   }
 
   /**
+   * @param {!SDK.DebuggerPausedDetails} debuggerPausedDetails
+   * @return {boolean}
+   */
+  _beforePaused(debuggerPausedDetails) {
+    return !!this._compilerMapping.mapsToSourceCode(debuggerPausedDetails.callFrames[0].location());
+  }
+
+  /**
    * @param {!Common.Event} event
    */
   _parsedScriptSource(event) {
@@ -401,7 +397,7 @@
 
     uiSourceCode.dispatchEventToListeners(
         Workspace.UISourceCode.Events.SourceMappingChanged,
-        {target: this._target, isIdentity: sourceMapping ? sourceMapping.isIdentity() : false});
+        {target: this._debuggerModel.target(), isIdentity: sourceMapping ? sourceMapping.isIdentity() : false});
   }
 
   /**
@@ -433,6 +429,7 @@
   }
 
   _dispose() {
+    this._debuggerModel.setBeforePausedCallback(null);
     Common.EventTarget.removeEventListeners(this._eventListeners);
     this._compilerMapping.dispose();
     this._resourceMapping.dispose();
diff --git a/third_party/WebKit/Source/devtools/front_end/common/Object.js b/third_party/WebKit/Source/devtools/front_end/common/Object.js
index 8a308d9..fe01dd3 100644
--- a/third_party/WebKit/Source/devtools/front_end/common/Object.js
+++ b/third_party/WebKit/Source/devtools/front_end/common/Object.js
@@ -87,21 +87,15 @@
    * @override
    * @param {symbol} eventType
    * @param {*=} eventData
-   * @return {boolean}
    */
   dispatchEventToListeners(eventType, eventData) {
     if (!this._listeners || !this._listeners.has(eventType))
-      return false;
+      return;
 
-    var event = new Common.Event(this, eventType, eventData);
+    var event = new Common.Event(this, eventData);
     var listeners = this._listeners.get(eventType).slice(0);
-    for (var i = 0; i < listeners.length; ++i) {
+    for (var i = 0; i < listeners.length; ++i)
       listeners[i].listener.call(listeners[i].thisObject, event);
-      if (event._stoppedPropagation)
-        break;
-    }
-
-    return event.defaultPrevented;
   }
 };
 
@@ -111,32 +105,11 @@
 Common.Event = class {
   /**
    * @param {!Common.EventTarget} target
-   * @param {symbol} type
    * @param {*=} data
    */
-  constructor(target, type, data) {
+  constructor(target, data) {
     this.target = target;
-    this.type = type;
     this.data = data;
-    this.defaultPrevented = false;
-    this._stoppedPropagation = false;
-  }
-
-  stopPropagation() {
-    this._stoppedPropagation = true;
-  }
-
-  preventDefault() {
-    this.defaultPrevented = true;
-  }
-
-  /**
-   * @param {boolean=} preventDefault
-   */
-  consume(preventDefault) {
-    this.stopPropagation();
-    if (preventDefault)
-      this.preventDefault();
   }
 };
 
@@ -184,7 +157,6 @@
   /**
    * @param {symbol} eventType
    * @param {*=} eventData
-   * @return {boolean}
    */
   dispatchEventToListeners(eventType, eventData) {},
 };
diff --git a/third_party/WebKit/Source/devtools/front_end/components/DockController.js b/third_party/WebKit/Source/devtools/front_end/components/DockController.js
index c4dfab20..0a1eab69 100644
--- a/third_party/WebKit/Source/devtools/front_end/components/DockController.js
+++ b/third_party/WebKit/Source/devtools/front_end/components/DockController.js
@@ -40,7 +40,8 @@
     this._canDock = canDock;
 
     this._closeButton = new UI.ToolbarButton(Common.UIString('Close'), 'largeicon-delete');
-    this._closeButton.addEventListener('click', InspectorFrontendHost.closeWindow.bind(InspectorFrontendHost));
+    this._closeButton.addEventListener(
+        UI.ToolbarButton.Events.Click, InspectorFrontendHost.closeWindow.bind(InspectorFrontendHost));
 
     if (!canDock) {
       this._dockSide = Components.DockController.State.Undocked;
diff --git a/third_party/WebKit/Source/devtools/front_end/components/EventListenersView.js b/third_party/WebKit/Source/devtools/front_end/components/EventListenersView.js
index 8f57990..ac68183 100644
--- a/third_party/WebKit/Source/devtools/front_end/components/EventListenersView.js
+++ b/third_party/WebKit/Source/devtools/front_end/components/EventListenersView.js
@@ -304,7 +304,7 @@
     }
 
     /**
-     * @param {!Common.Event} event
+     * @param {!Event} event
      * @this {Components.ObjectEventListenerBar}
      */
     function removeListener(event) {
@@ -314,7 +314,7 @@
     }
 
     /**
-     * @param {!Common.Event} event
+     * @param {!Event} event
      * @this {Components.ObjectEventListenerBar}
      */
     function togglePassiveListener(event) {
diff --git a/third_party/WebKit/Source/devtools/front_end/components/ObjectPopoverHelper.js b/third_party/WebKit/Source/devtools/front_end/components/ObjectPopoverHelper.js
index abbcb82..f892558 100644
--- a/third_party/WebKit/Source/devtools/front_end/components/ObjectPopoverHelper.js
+++ b/third_party/WebKit/Source/devtools/front_end/components/ObjectPopoverHelper.js
@@ -98,7 +98,7 @@
       if (rawLocation && Runtime.experiments.isEnabled('continueToFirstInvocation')) {
         var sectionToolbar = new UI.Toolbar('function-location-step-into', linkContainer);
         var stepInto = new UI.ToolbarButton(Common.UIString('Continue to first invocation'), 'largeicon-step-in');
-        stepInto.addEventListener('click', () => rawLocation.continueToLocation());
+        stepInto.addEventListener(UI.ToolbarButton.Events.Click, () => rawLocation.continueToLocation());
         sectionToolbar.appendToolbarItem(stepInto);
       }
       var sourceURL = rawLocation && rawLocation.script() ? rawLocation.script().sourceURL : null;
diff --git a/third_party/WebKit/Source/devtools/front_end/components/Spectrum.js b/third_party/WebKit/Source/devtools/front_end/components/Spectrum.js
index 30a63a34..c714b4a8 100644
--- a/third_party/WebKit/Source/devtools/front_end/components/Spectrum.js
+++ b/third_party/WebKit/Source/devtools/front_end/components/Spectrum.js
@@ -58,7 +58,8 @@
     var toolbar = new UI.Toolbar('spectrum-eye-dropper', this.contentElement);
     this._colorPickerButton = new UI.ToolbarToggle(Common.UIString('Toggle color picker'), 'largeicon-eyedropper');
     this._colorPickerButton.setToggled(true);
-    this._colorPickerButton.addEventListener('click', this._toggleColorPicker.bind(this, undefined));
+    this._colorPickerButton.addEventListener(
+        UI.ToolbarButton.Events.Click, this._toggleColorPicker.bind(this, undefined));
     toolbar.appendToolbarItem(this._colorPickerButton);
 
     var swatchElement = this.contentElement.createChild('span', 'swatch');
@@ -136,7 +137,7 @@
 
     this._addColorToolbar = new UI.Toolbar('add-color-toolbar');
     var addColorButton = new UI.ToolbarButton(Common.UIString('Add to palette'), 'largeicon-add');
-    addColorButton.addEventListener('click', this._addColorToCustomPalette.bind(this));
+    addColorButton.addEventListener(UI.ToolbarButton.Events.Click, this._addColorToCustomPalette, this);
     this._addColorToolbar.appendToolbarItem(addColorButton);
 
     this._loadPalettes();
@@ -208,7 +209,7 @@
     title.textContent = Common.UIString('Color Palettes');
     var toolbar = new UI.Toolbar('', this._palettePanel);
     var closeButton = new UI.ToolbarButton('Return to color picker', 'largeicon-delete');
-    closeButton.addEventListener('click', this._togglePalettePanel.bind(this, false));
+    closeButton.addEventListener(UI.ToolbarButton.Events.Click, this._togglePalettePanel.bind(this, false));
     toolbar.appendToolbarItem(closeButton);
     for (var palette of this._palettes.values())
       this._palettePanel.appendChild(this._createPreviewPaletteElement(palette));
@@ -524,7 +525,10 @@
         Components.Spectrum._ChangeSource.Other);
   }
 
-  _addColorToCustomPalette() {
+  /**
+   * @param {!Common.Event} event
+   */
+  _addColorToCustomPalette(event) {
     var palette = this._customPaletteSetting.get();
     palette.colors.push(this.colorString());
     this._customPaletteSetting.set(palette);
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/ClassesPaneWidget.js b/third_party/WebKit/Source/devtools/front_end/elements/ClassesPaneWidget.js
index c996dae..1b430f9 100644
--- a/third_party/WebKit/Source/devtools/front_end/elements/ClassesPaneWidget.js
+++ b/third_party/WebKit/Source/devtools/front_end/elements/ClassesPaneWidget.js
@@ -184,7 +184,7 @@
     this._button = new UI.ToolbarToggle(Common.UIString('Element Classes'), '');
     this._button.setText('.cls');
     this._button.element.classList.add('monospace');
-    this._button.addEventListener('click', this._clicked, this);
+    this._button.addEventListener(UI.ToolbarButton.Events.Click, this._clicked, this);
     this._view = new Elements.ClassesPaneWidget();
   }
 
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/ElementStatePaneWidget.js b/third_party/WebKit/Source/devtools/front_end/elements/ElementStatePaneWidget.js
index 77efe65..10c8b9f 100644
--- a/third_party/WebKit/Source/devtools/front_end/elements/ElementStatePaneWidget.js
+++ b/third_party/WebKit/Source/devtools/front_end/elements/ElementStatePaneWidget.js
@@ -108,7 +108,7 @@
   constructor() {
     this._button = new UI.ToolbarToggle(Common.UIString('Toggle Element State'), '');
     this._button.setText(Common.UIString(':hov'));
-    this._button.addEventListener('click', this._clicked, this);
+    this._button.addEventListener(UI.ToolbarButton.Events.Click, this._clicked, this);
     this._button.element.classList.add('monospace');
     this._view = new Elements.ElementStatePaneWidget();
   }
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/EventListenersWidget.js b/third_party/WebKit/Source/devtools/front_end/elements/EventListenersWidget.js
index 464cab1d..bd334a8 100644
--- a/third_party/WebKit/Source/devtools/front_end/elements/EventListenersWidget.js
+++ b/third_party/WebKit/Source/devtools/front_end/elements/EventListenersWidget.js
@@ -48,7 +48,7 @@
     this._eventListenersView = new Components.EventListenersView(this.element, this.update.bind(this));
 
     var refreshButton = new UI.ToolbarButton(Common.UIString('Refresh'), 'largeicon-refresh');
-    refreshButton.addEventListener('click', this.update.bind(this));
+    refreshButton.addEventListener(UI.ToolbarButton.Events.Click, this.update.bind(this));
     this._toolbarItems.push(refreshButton);
     this._toolbarItems.push(new UI.ToolbarCheckbox(
         Common.UIString('Ancestors'), Common.UIString('Show listeners on the ancestors'),
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/StylesSidebarPane.js b/third_party/WebKit/Source/devtools/front_end/elements/StylesSidebarPane.js
index 628d1132..2f41c11 100644
--- a/third_party/WebKit/Source/devtools/front_end/elements/StylesSidebarPane.js
+++ b/third_party/WebKit/Source/devtools/front_end/elements/StylesSidebarPane.js
@@ -719,25 +719,27 @@
     var items = [];
 
     var textShadowButton = new UI.ToolbarButton(Common.UIString('Add text-shadow'), 'largeicon-text-shadow');
-    textShadowButton.addEventListener('click', this._onInsertShadowPropertyClick.bind(this, 'text-shadow'));
+    textShadowButton.addEventListener(
+        UI.ToolbarButton.Events.Click, this._onInsertShadowPropertyClick.bind(this, 'text-shadow'));
     items.push(textShadowButton);
 
     var boxShadowButton = new UI.ToolbarButton(Common.UIString('Add box-shadow'), 'largeicon-box-shadow');
-    boxShadowButton.addEventListener('click', this._onInsertShadowPropertyClick.bind(this, 'box-shadow'));
+    boxShadowButton.addEventListener(
+        UI.ToolbarButton.Events.Click, this._onInsertShadowPropertyClick.bind(this, 'box-shadow'));
     items.push(boxShadowButton);
 
     var colorButton = new UI.ToolbarButton(Common.UIString('Add color'), 'largeicon-foreground-color');
-    colorButton.addEventListener('click', this._onInsertColorPropertyClick.bind(this));
+    colorButton.addEventListener(UI.ToolbarButton.Events.Click, this._onInsertColorPropertyClick, this);
     items.push(colorButton);
 
     var backgroundButton = new UI.ToolbarButton(Common.UIString('Add background-color'), 'largeicon-background-color');
-    backgroundButton.addEventListener('click', this._onInsertBackgroundColorPropertyClick.bind(this));
+    backgroundButton.addEventListener(UI.ToolbarButton.Events.Click, this._onInsertBackgroundColorPropertyClick, this);
     items.push(backgroundButton);
 
     var newRuleButton = null;
     if (this._style.parentRule) {
       newRuleButton = new UI.ToolbarButton(Common.UIString('Insert Style Rule Below'), 'largeicon-add');
-      newRuleButton.addEventListener('click', this._onNewRuleClick.bind(this));
+      newRuleButton.addEventListener(UI.ToolbarButton.Events.Click, this._onNewRuleClick, this);
       items.push(newRuleButton);
     }
 
@@ -880,7 +882,7 @@
    * @param {!Common.Event} event
    */
   _onNewRuleClick(event) {
-    event.consume();
+    event.data.consume();
     var rule = this._style.parentRule;
     var range = Common.TextRange.createFromLocation(rule.style.range.endLine, rule.style.range.endColumn + 1);
     this._parentPane._addBlankSection(this, /** @type {string} */ (rule.styleSheetId), range);
@@ -891,7 +893,7 @@
    * @param {!Common.Event} event
    */
   _onInsertShadowPropertyClick(propertyName, event) {
-    event.consume(true);
+    event.data.consume(true);
     var treeElement = this.addNewBlankProperty();
     treeElement.property.name = propertyName;
     treeElement.property.value = '0 0 black';
@@ -905,7 +907,7 @@
    * @param {!Common.Event} event
    */
   _onInsertColorPropertyClick(event) {
-    event.consume(true);
+    event.data.consume(true);
     var treeElement = this.addNewBlankProperty();
     treeElement.property.name = 'color';
     treeElement.property.value = 'black';
@@ -919,7 +921,7 @@
    * @param {!Common.Event} event
    */
   _onInsertBackgroundColorPropertyClick(event) {
-    event.consume(true);
+    event.data.consume(true);
     var treeElement = this.addNewBlankProperty();
     treeElement.property.name = 'background-color';
     treeElement.property.value = 'white';
@@ -3016,7 +3018,7 @@
 Elements.StylesSidebarPane.ButtonProvider = class {
   constructor() {
     this._button = new UI.ToolbarButton(Common.UIString('New Style Rule'), 'largeicon-add');
-    this._button.addEventListener('click', this._clicked, this);
+    this._button.addEventListener(UI.ToolbarButton.Events.Click, this._clicked, this);
     var longclickTriangle = UI.Icon.create('largeicon-longclick-triangle', 'long-click-glyph');
     this._button.element.appendChild(longclickTriangle);
 
@@ -3034,7 +3036,10 @@
     }
   }
 
-  _clicked() {
+  /**
+   * @param {!Common.Event} event
+   */
+  _clicked(event) {
     Elements.StylesSidebarPane._instance._createNewRuleInViaInspectorStyleSheet();
   }
 
diff --git a/third_party/WebKit/Source/devtools/front_end/emulation/DeviceModeToolbar.js b/third_party/WebKit/Source/devtools/front_end/emulation/DeviceModeToolbar.js
index a658424..b7dec58 100644
--- a/third_party/WebKit/Source/devtools/front_end/emulation/DeviceModeToolbar.js
+++ b/third_party/WebKit/Source/devtools/front_end/emulation/DeviceModeToolbar.js
@@ -170,7 +170,7 @@
     toolbar.appendToolbarItem(
         this._wrapToolbarItem(createElementWithClass('div', 'device-mode-empty-toolbar-element')));
     this._modeButton = new UI.ToolbarButton('', 'largeicon-rotate-screen');
-    this._modeButton.addEventListener('click', this._modeMenuClicked, this);
+    this._modeButton.addEventListener(UI.ToolbarButton.Events.Click, this._modeMenuClicked, this);
     toolbar.appendToolbarItem(this._modeButton);
   }
 
diff --git a/third_party/WebKit/Source/devtools/front_end/extensions/ExtensionPanel.js b/third_party/WebKit/Source/devtools/front_end/extensions/ExtensionPanel.js
index fc6ceb4..87c5b1b 100644
--- a/third_party/WebKit/Source/devtools/front_end/extensions/ExtensionPanel.js
+++ b/third_party/WebKit/Source/devtools/front_end/extensions/ExtensionPanel.js
@@ -133,7 +133,8 @@
     this._id = id;
 
     this._toolbarButton = new UI.ToolbarButton('', '');
-    this._toolbarButton.addEventListener('click', server.notifyButtonClicked.bind(server, this._id));
+    this._toolbarButton.addEventListener(
+        UI.ToolbarButton.Events.Click, server.notifyButtonClicked.bind(server, this._id));
     this.update(iconURL, tooltip, disabled);
   }
 
diff --git a/third_party/WebKit/Source/devtools/front_end/layer_viewer/TransformController.js b/third_party/WebKit/Source/devtools/front_end/layer_viewer/TransformController.js
index 821e50a..b7e5b80 100644
--- a/third_party/WebKit/Source/devtools/front_end/layer_viewer/TransformController.js
+++ b/third_party/WebKit/Source/devtools/front_end/layer_viewer/TransformController.js
@@ -33,19 +33,20 @@
     this._modeButtons = {};
     if (!disableRotate) {
       var panModeButton = new UI.ToolbarToggle(Common.UIString('Pan mode (X)'), 'largeicon-pan');
-      panModeButton.addEventListener('click', this._setMode.bind(this, LayerViewer.TransformController.Modes.Pan));
+      panModeButton.addEventListener(
+          UI.ToolbarButton.Events.Click, this._setMode.bind(this, LayerViewer.TransformController.Modes.Pan));
       this._modeButtons[LayerViewer.TransformController.Modes.Pan] = panModeButton;
       this._controlPanelToolbar.appendToolbarItem(panModeButton);
       var rotateModeButton = new UI.ToolbarToggle(Common.UIString('Rotate mode (V)'), 'largeicon-rotate');
       rotateModeButton.addEventListener(
-          'click', this._setMode.bind(this, LayerViewer.TransformController.Modes.Rotate));
+          UI.ToolbarButton.Events.Click, this._setMode.bind(this, LayerViewer.TransformController.Modes.Rotate));
       this._modeButtons[LayerViewer.TransformController.Modes.Rotate] = rotateModeButton;
       this._controlPanelToolbar.appendToolbarItem(rotateModeButton);
     }
     this._setMode(LayerViewer.TransformController.Modes.Pan);
 
     var resetButton = new UI.ToolbarButton(Common.UIString('Reset transform (0)'), 'largeicon-center');
-    resetButton.addEventListener('click', this.resetAndNotify.bind(this, undefined));
+    resetButton.addEventListener(UI.ToolbarButton.Events.Click, this.resetAndNotify.bind(this, undefined));
     this._controlPanelToolbar.appendToolbarItem(resetButton);
 
     this._reset();
diff --git a/third_party/WebKit/Source/devtools/front_end/main/Main.js b/third_party/WebKit/Source/devtools/front_end/main/Main.js
index c7e58b5b..5a877b01 100644
--- a/third_party/WebKit/Source/devtools/front_end/main/Main.js
+++ b/third_party/WebKit/Source/devtools/front_end/main/Main.js
@@ -112,6 +112,7 @@
     Runtime.experiments.register('sourceDiff', 'Source diff');
     Runtime.experiments.register('terminalInDrawer', 'Terminal in drawer', true);
     Runtime.experiments.register('timelineInvalidationTracking', 'Timeline invalidation tracking', true);
+    Runtime.experiments.register('timelineLandingPage', 'Timeline landing page', true);
     Runtime.experiments.register('timelineRecordingPerspectives', 'Timeline recording perspectives UI');
     Runtime.experiments.register('timelineTracingJSProfile', 'Timeline tracing based JS profiler', true);
     Runtime.experiments.register('timelineV8RuntimeCallStats', 'V8 Runtime Call Stats on Timeline', true);
@@ -675,7 +676,7 @@
 Main.Main.MainMenuItem = class {
   constructor() {
     this._item = new UI.ToolbarButton(Common.UIString('Customize and control DevTools'), 'largeicon-menu');
-    this._item.addEventListener('mousedown', this._mouseDown, this);
+    this._item.addEventListener(UI.ToolbarButton.Events.MouseDown, this._mouseDown, this);
   }
 
   /**
@@ -707,9 +708,12 @@
       var undock = new UI.ToolbarToggle(Common.UIString('Undock into separate window'), 'largeicon-undock');
       var bottom = new UI.ToolbarToggle(Common.UIString('Dock to bottom'), 'largeicon-dock-to-bottom');
       var right = new UI.ToolbarToggle(Common.UIString('Dock to right'), 'largeicon-dock-to-right');
-      undock.addEventListener('mouseup', setDockSide.bind(null, Components.DockController.State.Undocked));
-      bottom.addEventListener('mouseup', setDockSide.bind(null, Components.DockController.State.DockedToBottom));
-      right.addEventListener('mouseup', setDockSide.bind(null, Components.DockController.State.DockedToRight));
+      undock.addEventListener(
+          UI.ToolbarButton.Events.MouseUp, setDockSide.bind(null, Components.DockController.State.Undocked));
+      bottom.addEventListener(
+          UI.ToolbarButton.Events.MouseUp, setDockSide.bind(null, Components.DockController.State.DockedToBottom));
+      right.addEventListener(
+          UI.ToolbarButton.Events.MouseUp, setDockSide.bind(null, Components.DockController.State.DockedToRight));
       undock.setToggled(Components.dockController.dockSide() === Components.DockController.State.Undocked);
       bottom.setToggled(Components.dockController.dockSide() === Components.DockController.State.DockedToBottom);
       right.setToggled(Components.dockController.dockSide() === Components.DockController.State.DockedToRight);
diff --git a/third_party/WebKit/Source/devtools/front_end/network/BlockedURLsPane.js b/third_party/WebKit/Source/devtools/front_end/network/BlockedURLsPane.js
index 5e3690c..200b299 100644
--- a/third_party/WebKit/Source/devtools/front_end/network/BlockedURLsPane.js
+++ b/third_party/WebKit/Source/devtools/front_end/network/BlockedURLsPane.js
@@ -18,10 +18,10 @@
     this._toolbar = new UI.Toolbar('', this.contentElement);
     this._toolbar.element.addEventListener('click', (e) => e.consume());
     var addButton = new UI.ToolbarButton(Common.UIString('Add pattern'), 'largeicon-add');
-    addButton.addEventListener('click', this._addButtonClicked.bind(this));
+    addButton.addEventListener(UI.ToolbarButton.Events.Click, this._addButtonClicked, this);
     this._toolbar.appendToolbarItem(addButton);
     var clearButton = new UI.ToolbarButton(Common.UIString('Remove all'), 'largeicon-clear');
-    clearButton.addEventListener('click', this._removeAll.bind(this));
+    clearButton.addEventListener(UI.ToolbarButton.Events.Click, this._removeAll, this);
     this._toolbar.appendToolbarItem(clearButton);
 
     this._emptyElement = this.contentElement.createChild('div', 'no-blocked-urls');
diff --git a/third_party/WebKit/Source/devtools/front_end/network/NetworkPanel.js b/third_party/WebKit/Source/devtools/front_end/network/NetworkPanel.js
index 93f2900..2f78bf4c 100644
--- a/third_party/WebKit/Source/devtools/front_end/network/NetworkPanel.js
+++ b/third_party/WebKit/Source/devtools/front_end/network/NetworkPanel.js
@@ -140,7 +140,7 @@
     this._panelToolbar.appendToolbarItem(UI.Toolbar.createActionButton(this._toggleRecordAction));
 
     this._clearButton = new UI.ToolbarButton(Common.UIString('Clear'), 'largeicon-clear');
-    this._clearButton.addEventListener('click', this._onClearButtonClicked, this);
+    this._clearButton.addEventListener(UI.ToolbarButton.Events.Click, this._onClearButtonClicked, this);
     this._panelToolbar.appendToolbarItem(this._clearButton);
     this._panelToolbar.appendSeparator();
     var recordFilmStripButton = new UI.ToolbarSettingToggle(
diff --git a/third_party/WebKit/Source/devtools/front_end/profiler/BottomUpProfileDataGrid.js b/third_party/WebKit/Source/devtools/front_end/profiler/BottomUpProfileDataGrid.js
index b94e7260..c1752f4 100644
--- a/third_party/WebKit/Source/devtools/front_end/profiler/BottomUpProfileDataGrid.js
+++ b/third_party/WebKit/Source/devtools/front_end/profiler/BottomUpProfileDataGrid.js
@@ -175,6 +175,7 @@
    */
   constructor(formatter, searchableView, rootProfileNode, total) {
     super(formatter, searchableView, total);
+    this.deepSearch = false;
 
     // Iterate each node in pre-order.
     var profileNodeUIDs = 0;
@@ -291,28 +292,6 @@
 
   /**
    * @override
-   * @param {!UI.SearchableView.SearchConfig} searchConfig
-   * @param {boolean} shouldJump
-   * @param {boolean=} jumpBackwards
-   */
-  performSearch(searchConfig, shouldJump, jumpBackwards) {
-    this.searchCanceled();
-    var matchesQuery = this._matchFunction(searchConfig);
-    if (!matchesQuery)
-      return;
-
-    this._searchResults = [];
-    for (var current = this.children[0]; current; current = current.traverseNextNode(true, null, true)) {
-      if (matchesQuery(current))
-        this._searchResults.push({profileNode: current});
-    }
-    this._searchResultIndex = jumpBackwards ? 0 : this._searchResults.length - 1;
-    this._searchableView.updateSearchMatchesCount(this._searchResults.length);
-    this._searchableView.updateCurrentMatchIndex(this._searchResultIndex);
-  }
-
-  /**
-   * @override
    */
   populateChildren() {
     Profiler.BottomUpProfileDataGridNode._sharedPopulate(this);
diff --git a/third_party/WebKit/Source/devtools/front_end/profiler/CPUProfileFlameChart.js b/third_party/WebKit/Source/devtools/front_end/profiler/CPUProfileFlameChart.js
index d489167..7577cb7 100644
--- a/third_party/WebKit/Source/devtools/front_end/profiler/CPUProfileFlameChart.js
+++ b/third_party/WebKit/Source/devtools/front_end/profiler/CPUProfileFlameChart.js
@@ -33,12 +33,8 @@
  * @unrestricted
  */
 Profiler.ProfileFlameChartDataProvider = class {
-  /**
-   * @param {?SDK.Target} target
-   */
-  constructor(target) {
+  constructor() {
     UI.FlameChartDataProvider.call(this);
-    this._target = target;
     this._colorGenerator = Profiler.ProfileFlameChartDataProvider.colorGenerator();
   }
 
diff --git a/third_party/WebKit/Source/devtools/front_end/profiler/CPUProfileView.js b/third_party/WebKit/Source/devtools/front_end/profiler/CPUProfileView.js
index 010d83c..657eb562 100644
--- a/third_party/WebKit/Source/devtools/front_end/profiler/CPUProfileView.js
+++ b/third_party/WebKit/Source/devtools/front_end/profiler/CPUProfileView.js
@@ -190,7 +190,7 @@
 
   startRecordingProfile() {
     var target = UI.context.flavor(SDK.Target);
-    if (this._profileBeingRecorded || !target)
+    if (this.profileBeingRecorded() || !target)
       return;
     var profile = new Profiler.CPUProfileHeader(target, this);
     this.setProfileBeingRecorded(profile);
@@ -203,7 +203,7 @@
 
   stopRecordingProfile() {
     this._recording = false;
-    if (!this._profileBeingRecorded || !this._profileBeingRecorded.target())
+    if (!this.profileBeingRecorded() || !this.profileBeingRecorded().target())
       return;
 
     var recordedProfile;
@@ -213,12 +213,12 @@
      * @this {Profiler.CPUProfileType}
      */
     function didStopProfiling(profile) {
-      if (!this._profileBeingRecorded)
+      if (!this.profileBeingRecorded())
         return;
       console.assert(profile);
-      this._profileBeingRecorded.setProtocolProfile(profile);
-      this._profileBeingRecorded.updateStatus('');
-      recordedProfile = this._profileBeingRecorded;
+      this.profileBeingRecorded().setProtocolProfile(profile);
+      this.profileBeingRecorded().updateStatus('');
+      recordedProfile = this.profileBeingRecorded();
       this.setProfileBeingRecorded(null);
     }
 
@@ -229,7 +229,7 @@
       this.dispatchEventToListeners(Profiler.ProfileType.Events.ProfileComplete, recordedProfile);
     }
 
-    this._profileBeingRecorded.target()
+    this.profileBeingRecorded().target()
         .cpuProfilerModel.stopRecording()
         .then(didStopProfiling.bind(this))
         .then(SDK.targetManager.resumeAllTargets.bind(SDK.targetManager))
@@ -332,8 +332,9 @@
    * @param {?SDK.Target} target
    */
   constructor(cpuProfile, target) {
-    super(target);
+    super();
     this._cpuProfile = cpuProfile;
+    this._target = target;
   }
 
   /**
diff --git a/third_party/WebKit/Source/devtools/front_end/profiler/HeapProfileView.js b/third_party/WebKit/Source/devtools/front_end/profiler/HeapProfileView.js
index e10fb662..bcfb271a 100644
--- a/third_party/WebKit/Source/devtools/front_end/profiler/HeapProfileView.js
+++ b/third_party/WebKit/Source/devtools/front_end/profiler/HeapProfileView.js
@@ -97,7 +97,7 @@
 
   startRecordingProfile() {
     var target = UI.context.flavor(SDK.Target);
-    if (this._profileBeingRecorded || !target)
+    if (this.profileBeingRecorded() || !target)
       return;
     var profile = new Profiler.SamplingHeapProfileHeader(target, this);
     this.setProfileBeingRecorded(profile);
@@ -110,7 +110,7 @@
 
   stopRecordingProfile() {
     this._recording = false;
-    if (!this._profileBeingRecorded || !this._profileBeingRecorded.target())
+    if (!this.profileBeingRecorded() || !this.profileBeingRecorded().target())
       return;
 
     var recordedProfile;
@@ -120,12 +120,12 @@
      * @this {Profiler.SamplingHeapProfileType}
      */
     function didStopProfiling(profile) {
-      if (!this._profileBeingRecorded)
+      if (!this.profileBeingRecorded())
         return;
       console.assert(profile);
-      this._profileBeingRecorded.setProtocolProfile(profile);
-      this._profileBeingRecorded.updateStatus('');
-      recordedProfile = this._profileBeingRecorded;
+      this.profileBeingRecorded().setProtocolProfile(profile);
+      this.profileBeingRecorded().updateStatus('');
+      recordedProfile = this.profileBeingRecorded();
       this.setProfileBeingRecorded(null);
     }
 
@@ -136,7 +136,7 @@
       this.dispatchEventToListeners(Profiler.ProfileType.Events.ProfileComplete, recordedProfile);
     }
 
-    this._profileBeingRecorded.target()
+    this.profileBeingRecorded().target()
         .heapProfilerModel.stopSampling()
         .then(didStopProfiling.bind(this))
         .then(SDK.targetManager.resumeAllTargets.bind(SDK.targetManager))
@@ -294,8 +294,9 @@
    * @param {?SDK.Target} target
    */
   constructor(profile, target) {
-    super(target);
+    super();
     this._profile = profile;
+    this._target = target;
   }
 
   /**
diff --git a/third_party/WebKit/Source/devtools/front_end/profiler/HeapSnapshotProxy.js b/third_party/WebKit/Source/devtools/front_end/profiler/HeapSnapshotProxy.js
index a6ab8de1..0005305 100644
--- a/third_party/WebKit/Source/devtools/front_end/profiler/HeapSnapshotProxy.js
+++ b/third_party/WebKit/Source/devtools/front_end/profiler/HeapSnapshotProxy.js
@@ -157,7 +157,7 @@
         this._previousCallbacks.delete(callId);
     }
     var hasLongRunningCalls = !!this._previousCallbacks.size;
-    this.dispatchEventToListeners('wait', hasLongRunningCalls);
+    this.dispatchEventToListeners(Profiler.HeapSnapshotWorkerProxy.Events.Wait, hasLongRunningCalls);
     for (var callId of this._callbacks.keysArray())
       this._previousCallbacks.add(callId);
   }
@@ -193,6 +193,10 @@
   }
 };
 
+Profiler.HeapSnapshotWorkerProxy.Events = {
+  Wait: Symbol('Wait')
+};
+
 /**
  * @unrestricted
  */
diff --git a/third_party/WebKit/Source/devtools/front_end/profiler/HeapSnapshotView.js b/third_party/WebKit/Source/devtools/front_end/profiler/HeapSnapshotView.js
index 11f37c8..0c66cf8 100644
--- a/third_party/WebKit/Source/devtools/front_end/profiler/HeapSnapshotView.js
+++ b/third_party/WebKit/Source/devtools/front_end/profiler/HeapSnapshotView.js
@@ -1036,7 +1036,7 @@
      * @this {Profiler.HeapSnapshotProfileType}
      */
     function didTakeHeapSnapshot(error) {
-      var profile = this._profileBeingRecorded;
+      var profile = this.profileBeingRecorded();
       profile.title = Common.UIString('Snapshot %d', profile.uid);
       profile._finishLoad();
       this.setProfileBeingRecorded(null);
@@ -1070,11 +1070,11 @@
   }
 
   _resetProfiles() {
-    this._reset();
+    this.reset();
   }
 
   _snapshotReceived(profile) {
-    if (this._profileBeingRecorded === profile)
+    if (this.profileBeingRecorded() === profile)
       this.setProfileBeingRecorded(null);
     this.dispatchEventToListeners(Profiler.HeapSnapshotProfileType.SnapshotReceived, profile);
   }
@@ -1150,7 +1150,7 @@
     if (profileSamples.totalTime < data.timestamp - profileSamples.timestamps[0])
       profileSamples.totalTime *= 2;
     this.dispatchEventToListeners(Profiler.TrackingHeapSnapshotProfileType.HeapStatsUpdate, this._profileSamples);
-    this._profileBeingRecorded.updateStatus(null, true);
+    this.profileBeingRecorded().updateStatus(null, true);
   }
 
   /**
@@ -1194,15 +1194,15 @@
     var target = UI.context.flavor(SDK.Target);
     this.setProfileBeingRecorded(new Profiler.HeapProfileHeader(target, this, undefined));
     this._profileSamples = new Profiler.TrackingHeapSnapshotProfileType.Samples();
-    this._profileBeingRecorded._profileSamples = this._profileSamples;
+    this.profileBeingRecorded()._profileSamples = this._profileSamples;
     this._recording = true;
-    this.addProfile(this._profileBeingRecorded);
-    this._profileBeingRecorded.updateStatus(Common.UIString('Recording\u2026'));
+    this.addProfile(/** @type {!Profiler.ProfileHeader} */ (this.profileBeingRecorded()));
+    this.profileBeingRecorded().updateStatus(Common.UIString('Recording\u2026'));
     this.dispatchEventToListeners(Profiler.TrackingHeapSnapshotProfileType.TrackingStarted);
   }
 
   _stopRecordingProfile() {
-    this._profileBeingRecorded.updateStatus(Common.UIString('Snapshotting\u2026'));
+    this.profileBeingRecorded().updateStatus(Common.UIString('Snapshotting\u2026'));
     /**
      * @param {?string} error
      * @this {Profiler.HeapSnapshotProfileType}
@@ -1217,7 +1217,7 @@
       this.dispatchEventToListeners(Profiler.ProfileType.Events.ProfileComplete, profile);
     }
 
-    this._profileBeingRecorded.target().heapProfilerAgent().stopTrackingHeapObjects(
+    this.profileBeingRecorded().target().heapProfilerAgent().stopTrackingHeapObjects(
         true, didTakeHeapSnapshot.bind(this));
     this._recording = false;
     this.dispatchEventToListeners(Profiler.TrackingHeapSnapshotProfileType.TrackingStopped);
@@ -1391,7 +1391,7 @@
     }
     console.assert(!this._workerProxy, 'HeapSnapshotWorkerProxy already exists');
     this._workerProxy = new Profiler.HeapSnapshotWorkerProxy(this._handleWorkerEvent.bind(this));
-    this._workerProxy.addEventListener('wait', setProfileWait, this);
+    this._workerProxy.addEventListener(Profiler.HeapSnapshotWorkerProxy.Events.Wait, setProfileWait, this);
     this._receiver = this._workerProxy.createLoader(this.uid, this._snapshotReceived.bind(this));
   }
 
@@ -1453,7 +1453,7 @@
 
   notifySnapshotReceived() {
     this._fulfillLoad(this._snapshotProxy);
-    this._profileType._snapshotReceived(this);
+    this.profileType()._snapshotReceived(this);
     if (this.canSaveToFile())
       this.dispatchEventToListeners(Profiler.ProfileHeader.Events.ProfileReceived);
   }
@@ -1494,7 +1494,7 @@
         this._updateSaveProgress(0, 1);
       }
     }
-    this._fileName = this._fileName || 'Heap-' + new Date().toISO8601Compact() + this._profileType.fileExtension();
+    this._fileName = this._fileName || 'Heap-' + new Date().toISO8601Compact() + this.profileType().fileExtension();
     fileOutputStream.open(this._fileName, onOpen.bind(this));
   }
 
diff --git a/third_party/WebKit/Source/devtools/front_end/profiler/ProfileDataGrid.js b/third_party/WebKit/Source/devtools/front_end/profiler/ProfileDataGrid.js
index 9c50155..bd6cb3f 100644
--- a/third_party/WebKit/Source/devtools/front_end/profiler/ProfileDataGrid.js
+++ b/third_party/WebKit/Source/devtools/front_end/profiler/ProfileDataGrid.js
@@ -332,6 +332,7 @@
     this.total = total;
     this.lastComparator = null;
     this.childrenByCallUID = new Map();
+    this.deepSearch = true;
   }
 
   /**
@@ -547,7 +548,8 @@
       return;
 
     this._searchResults = [];
-    for (var current = this.children[0]; current; current = current.traverseNextNode(false, null, false)) {
+    const deepSearch = this.deepSearch;
+    for (var current = this.children[0]; current; current = current.traverseNextNode(!deepSearch, null, !deepSearch)) {
       if (matchesQuery(current))
         this._searchResults.push({profileNode: current});
     }
diff --git a/third_party/WebKit/Source/devtools/front_end/profiler/ProfileView.js b/third_party/WebKit/Source/devtools/front_end/profiler/ProfileView.js
index c30218d..e4d927c 100644
--- a/third_party/WebKit/Source/devtools/front_end/profiler/ProfileView.js
+++ b/third_party/WebKit/Source/devtools/front_end/profiler/ProfileView.js
@@ -34,15 +34,15 @@
 
     this.focusButton = new UI.ToolbarButton(Common.UIString('Focus selected function'), 'largeicon-visibility');
     this.focusButton.setEnabled(false);
-    this.focusButton.addEventListener('click', this._focusClicked, this);
+    this.focusButton.addEventListener(UI.ToolbarButton.Events.Click, this._focusClicked, this);
 
     this.excludeButton = new UI.ToolbarButton(Common.UIString('Exclude selected function'), 'largeicon-delete');
     this.excludeButton.setEnabled(false);
-    this.excludeButton.addEventListener('click', this._excludeClicked, this);
+    this.excludeButton.addEventListener(UI.ToolbarButton.Events.Click, this._excludeClicked, this);
 
     this.resetButton = new UI.ToolbarButton(Common.UIString('Restore all functions'), 'largeicon-refresh');
     this.resetButton.setEnabled(false);
-    this.resetButton.addEventListener('click', this._resetClicked, this);
+    this.resetButton.addEventListener(UI.ToolbarButton.Events.Click, this._resetClicked, this);
 
     this._linkifier = new Components.Linkifier(Profiler.ProfileView._maxLinkLength);
   }
@@ -325,6 +325,9 @@
     this.excludeButton.setEnabled(selected);
   }
 
+  /**
+   * @param {!Common.Event} event
+   */
   _focusClicked(event) {
     if (!this.dataGrid.selectedNode)
       return;
@@ -335,6 +338,9 @@
     this.refreshVisibleData();
   }
 
+  /**
+   * @param {!Common.Event} event
+   */
   _excludeClicked(event) {
     var selectedNode = this.dataGrid.selectedNode;
 
@@ -349,6 +355,9 @@
     this.refreshVisibleData();
   }
 
+  /**
+   * @param {!Common.Event} event
+   */
   _resetClicked(event) {
     this.resetButton.setEnabled(false);
     this.profileDataGridTree.restore();
@@ -419,8 +428,8 @@
     this._jsonifiedProfile = null;
     this.updateStatus(Common.UIString('Loaded'), false);
 
-    if (this._profileType.profileBeingRecorded() === this)
-      this._profileType.setProfileBeingRecorded(null);
+    if (this.profileType().profileBeingRecorded() === this)
+      this.profileType().setProfileBeingRecorded(null);
   }
 
   /**
@@ -512,7 +521,7 @@
       }
     }
     this._fileName = this._fileName ||
-        `${this._profileType.typeName()}-${new Date().toISO8601Compact()}${this._profileType.fileExtension()}`;
+        `${this.profileType().typeName()}-${new Date().toISO8601Compact()}${this.profileType().fileExtension()}`;
     fileOutputStream.open(this._fileName, onOpenForSave.bind(this));
   }
 
diff --git a/third_party/WebKit/Source/devtools/front_end/profiler/ProfilesPanel.js b/third_party/WebKit/Source/devtools/front_end/profiler/ProfilesPanel.js
index d30c0f9..96d66d1 100644
--- a/third_party/WebKit/Source/devtools/front_end/profiler/ProfilesPanel.js
+++ b/third_party/WebKit/Source/devtools/front_end/profiler/ProfilesPanel.js
@@ -220,12 +220,9 @@
   profileBeingRecordedRemoved() {
   }
 
-  _reset() {
-    var profiles = this._profiles.slice(0);
-    for (var i = 0; i < profiles.length; ++i)
-      this._disposeProfile(profiles[i]);
+  reset() {
+    this._profiles.slice(0).forEach(this._disposeProfile.bind(this));
     this._profiles = [];
-
     this._nextProfileUid = 1;
   }
 
@@ -429,7 +426,7 @@
     toolbar.appendToolbarItem(this._toggleRecordButton);
 
     this.clearResultsButton = new UI.ToolbarButton(Common.UIString('Clear all profiles'), 'largeicon-clear');
-    this.clearResultsButton.addEventListener('click', this._reset, this);
+    this.clearResultsButton.addEventListener(UI.ToolbarButton.Events.Click, this._reset, this);
     toolbar.appendToolbarItem(this.clearResultsButton);
     toolbar.appendSeparator();
     toolbar.appendToolbarItem(
@@ -598,9 +595,7 @@
   }
 
   _reset() {
-    var types = Profiler.ProfileTypeRegistry.instance.profileTypes();
-    for (var i = 0; i < types.length; i++)
-      types[i]._reset();
+    Profiler.ProfileTypeRegistry.instance.profileTypes().forEach(type => type.reset());
 
     delete this.visibleView;
 
diff --git a/third_party/WebKit/Source/devtools/front_end/resources/AppManifestView.js b/third_party/WebKit/Source/devtools/front_end/resources/AppManifestView.js
index 97f7c84..c99bed20c 100644
--- a/third_party/WebKit/Source/devtools/front_end/resources/AppManifestView.js
+++ b/third_party/WebKit/Source/devtools/front_end/resources/AppManifestView.js
@@ -19,7 +19,7 @@
     toolbar.renderAsLinks();
     var addToHomeScreen =
         new UI.ToolbarButton(Common.UIString('Add to homescreen'), undefined, Common.UIString('Add to homescreen'));
-    addToHomeScreen.addEventListener('click', this._addToHomescreen.bind(this));
+    addToHomeScreen.addEventListener(UI.ToolbarButton.Events.Click, this._addToHomescreen, this);
     toolbar.appendToolbarItem(addToHomeScreen);
 
     this._presentationSection = this._reportView.appendSection(Common.UIString('Presentation'));
@@ -136,7 +136,10 @@
     }
   }
 
-  _addToHomescreen() {
+  /**
+   * @param {!Common.Event} event
+   */
+  _addToHomescreen(event) {
     var target = SDK.targetManager.mainTarget();
     if (target && target.hasBrowserCapability()) {
       target.pageAgent().requestAppBanner();
diff --git a/third_party/WebKit/Source/devtools/front_end/resources/ApplicationCacheItemsView.js b/third_party/WebKit/Source/devtools/front_end/resources/ApplicationCacheItemsView.js
index fbe91d08..f154fd65 100644
--- a/third_party/WebKit/Source/devtools/front_end/resources/ApplicationCacheItemsView.js
+++ b/third_party/WebKit/Source/devtools/front_end/resources/ApplicationCacheItemsView.js
@@ -36,7 +36,7 @@
 
     this._deleteButton = new UI.ToolbarButton(Common.UIString('Delete'), 'largeicon-delete');
     this._deleteButton.setVisible(false);
-    this._deleteButton.addEventListener('click', this._deleteButtonClicked, this);
+    this._deleteButton.addEventListener(UI.ToolbarButton.Events.Click, this._deleteButtonClicked, this);
 
     this._connectivityIcon = createElement('label', 'dt-icon-label');
     this._connectivityIcon.style.margin = '0 2px 0 5px';
@@ -239,6 +239,9 @@
       this._dataGrid.rootNode().children[0].selected = true;
   }
 
+  /**
+   * @param {!Common.Event} event
+   */
   _deleteButtonClicked(event) {
     if (!this._dataGrid || !this._dataGrid.selectedNode)
       return;
diff --git a/third_party/WebKit/Source/devtools/front_end/resources/CookieItemsView.js b/third_party/WebKit/Source/devtools/front_end/resources/CookieItemsView.js
index c334644..42c424c 100644
--- a/third_party/WebKit/Source/devtools/front_end/resources/CookieItemsView.js
+++ b/third_party/WebKit/Source/devtools/front_end/resources/CookieItemsView.js
@@ -38,14 +38,14 @@
 
     this._deleteButton = new UI.ToolbarButton(Common.UIString('Delete'), 'largeicon-delete');
     this._deleteButton.setVisible(false);
-    this._deleteButton.addEventListener('click', this._deleteButtonClicked, this);
+    this._deleteButton.addEventListener(UI.ToolbarButton.Events.Click, this._deleteButtonClicked, this);
 
     this._clearButton = new UI.ToolbarButton(Common.UIString('Clear'), 'largeicon-clear');
     this._clearButton.setVisible(false);
-    this._clearButton.addEventListener('click', this._clearButtonClicked, this);
+    this._clearButton.addEventListener(UI.ToolbarButton.Events.Click, this._clearButtonClicked, this);
 
     this._refreshButton = new UI.ToolbarButton(Common.UIString('Refresh'), 'largeicon-refresh');
-    this._refreshButton.addEventListener('click', this._refreshButtonClicked, this);
+    this._refreshButton.addEventListener(UI.ToolbarButton.Events.Click, this._refreshButtonClicked, this);
 
     this._treeElement = treeElement;
     this._cookieDomain = cookieDomain;
@@ -156,7 +156,10 @@
     this._update();
   }
 
-  _clearButtonClicked() {
+  /**
+   * @param {!Common.Event} event
+   */
+  _clearButtonClicked(event) {
     this.clear();
   }
 
@@ -164,7 +167,10 @@
     this._deleteButton.setVisible(true);
   }
 
-  _deleteButtonClicked() {
+  /**
+   * @param {!Common.Event} event
+   */
+  _deleteButtonClicked(event) {
     var selectedCookie = this._cookiesTable.selectedCookie();
     if (selectedCookie) {
       selectedCookie.remove();
@@ -172,6 +178,9 @@
     }
   }
 
+  /**
+   * @param {!Common.Event} event
+   */
   _refreshButtonClicked(event) {
     this._update();
   }
diff --git a/third_party/WebKit/Source/devtools/front_end/resources/DOMStorageItemsView.js b/third_party/WebKit/Source/devtools/front_end/resources/DOMStorageItemsView.js
index 303f117..f4814b0 100644
--- a/third_party/WebKit/Source/devtools/front_end/resources/DOMStorageItemsView.js
+++ b/third_party/WebKit/Source/devtools/front_end/resources/DOMStorageItemsView.js
@@ -37,10 +37,10 @@
 
     this.deleteButton = new UI.ToolbarButton(Common.UIString('Delete'), 'largeicon-delete');
     this.deleteButton.setVisible(false);
-    this.deleteButton.addEventListener('click', this._deleteButtonClicked, this);
+    this.deleteButton.addEventListener(UI.ToolbarButton.Events.Click, this._deleteButtonClicked, this);
 
     this.refreshButton = new UI.ToolbarButton(Common.UIString('Refresh'), 'largeicon-refresh');
-    this.refreshButton.addEventListener('click', this._refreshButtonClicked, this);
+    this.refreshButton.addEventListener(UI.ToolbarButton.Events.Click, this._refreshButtonClicked, this);
 
     this.domStorage.addEventListener(
         Resources.DOMStorage.Events.DOMStorageItemsCleared, this._domStorageItemsCleared, this);
@@ -83,7 +83,6 @@
     this._dataGrid.rootNode().removeChildren();
     this._dataGrid.addCreationNode(false);
     this.deleteButton.setVisible(false);
-    event.consume(true);
   }
 
   /**
@@ -97,8 +96,6 @@
     var rootNode = this._dataGrid.rootNode();
     var children = rootNode.children;
 
-    event.consume(true);
-
     for (var i = 0; i < children.length; ++i) {
       var childNode = children[i];
       if (childNode.data.key === storageData.key) {
@@ -120,7 +117,6 @@
     var rootNode = this._dataGrid.rootNode();
     var children = rootNode.children;
 
-    event.consume(true);
     this.deleteButton.setVisible(true);
 
     for (var i = 0; i < children.length; ++i) {
@@ -143,8 +139,6 @@
     var rootNode = this._dataGrid.rootNode();
     var children = rootNode.children;
 
-    event.consume(true);
-
     var keyFound = false;
     for (var i = 0; i < children.length; ++i) {
       var childNode = children[i];
@@ -209,6 +203,9 @@
     return dataGrid;
   }
 
+  /**
+   * @param {!Common.Event} event
+   */
   _deleteButtonClicked(event) {
     if (!this._dataGrid || !this._dataGrid.selectedNode)
       return;
@@ -216,6 +213,9 @@
     this._deleteCallback(this._dataGrid.selectedNode);
   }
 
+  /**
+   * @param {!Common.Event} event
+   */
   _refreshButtonClicked(event) {
     this._update();
   }
diff --git a/third_party/WebKit/Source/devtools/front_end/resources/DatabaseTableView.js b/third_party/WebKit/Source/devtools/front_end/resources/DatabaseTableView.js
index 6b98450e..ce6f2629 100644
--- a/third_party/WebKit/Source/devtools/front_end/resources/DatabaseTableView.js
+++ b/third_party/WebKit/Source/devtools/front_end/resources/DatabaseTableView.js
@@ -38,7 +38,7 @@
     this._visibleColumnsSetting = Common.settings.createSetting('databaseTableViewVisibleColumns', {});
 
     this.refreshButton = new UI.ToolbarButton(Common.UIString('Refresh'), 'largeicon-refresh');
-    this.refreshButton.addEventListener('click', this._refreshButtonClicked, this);
+    this.refreshButton.addEventListener(UI.ToolbarButton.Events.Click, this._refreshButtonClicked, this);
     this._visibleColumnsInput = new UI.ToolbarInput(Common.UIString('Visible columns'), 1);
     this._visibleColumnsInput.addEventListener(UI.ToolbarInput.Event.TextChanged, this._onVisibleColumnsChanged, this);
   }
@@ -134,6 +134,9 @@
     this.element.appendChild(errorMsgElement);
   }
 
+  /**
+   * @param {!Common.Event} event
+   */
   _refreshButtonClicked(event) {
     this.update();
   }
diff --git a/third_party/WebKit/Source/devtools/front_end/resources/IndexedDBViews.js b/third_party/WebKit/Source/devtools/front_end/resources/IndexedDBViews.js
index 0b4a589..b68d654 100644
--- a/third_party/WebKit/Source/devtools/front_end/resources/IndexedDBViews.js
+++ b/third_party/WebKit/Source/devtools/front_end/resources/IndexedDBViews.js
@@ -99,10 +99,10 @@
     this._createEditorToolbar();
 
     this._refreshButton = new UI.ToolbarButton(Common.UIString('Refresh'), 'largeicon-refresh');
-    this._refreshButton.addEventListener('click', this._refreshButtonClicked, this);
+    this._refreshButton.addEventListener(UI.ToolbarButton.Events.Click, this._refreshButtonClicked, this);
 
     this._clearButton = new UI.ToolbarButton(Common.UIString('Clear object store'), 'largeicon-clear');
-    this._clearButton.addEventListener('click', this._clearButtonClicked, this);
+    this._clearButton.addEventListener(UI.ToolbarButton.Events.Click, this._clearButtonClicked, this);
 
     this._pageSize = 50;
     this._skipCount = 0;
@@ -179,12 +179,12 @@
     var editorToolbar = new UI.Toolbar('data-view-toolbar', this.element);
 
     this._pageBackButton = new UI.ToolbarButton(Common.UIString('Show previous page'), 'largeicon-play-back');
-    this._pageBackButton.addEventListener('click', this._pageBackButtonClicked, this);
+    this._pageBackButton.addEventListener(UI.ToolbarButton.Events.Click, this._pageBackButtonClicked, this);
     editorToolbar.appendToolbarItem(this._pageBackButton);
 
     this._pageForwardButton = new UI.ToolbarButton(Common.UIString('Show next page'), 'largeicon-play');
     this._pageForwardButton.setEnabled(false);
-    this._pageForwardButton.addEventListener('click', this._pageForwardButtonClicked, this);
+    this._pageForwardButton.addEventListener(UI.ToolbarButton.Events.Click, this._pageForwardButtonClicked, this);
     editorToolbar.appendToolbarItem(this._pageForwardButton);
 
     this._keyInputElement = editorToolbar.element.createChild('input', 'key-input');
@@ -195,12 +195,18 @@
     this._keyInputElement.addEventListener('keydown', this._keyInputChanged.bind(this), false);
   }
 
-  _pageBackButtonClicked() {
+  /**
+   * @param {!Common.Event} event
+   */
+  _pageBackButtonClicked(event) {
     this._skipCount = Math.max(0, this._skipCount - this._pageSize);
     this._updateData(false);
   }
 
-  _pageForwardButtonClicked() {
+  /**
+   * @param {!Common.Event} event
+   */
+  _pageForwardButtonClicked(event) {
     this._skipCount = this._skipCount + this._pageSize;
     this._updateData(false);
   }
@@ -295,10 +301,16 @@
     }
   }
 
+  /**
+   * @param {!Common.Event} event
+   */
   _refreshButtonClicked(event) {
     this._updateData(true);
   }
 
+  /**
+   * @param {!Common.Event} event
+   */
   _clearButtonClicked(event) {
     /**
      * @this {Resources.IDBDataView}
diff --git a/third_party/WebKit/Source/devtools/front_end/resources/ServiceWorkerCacheViews.js b/third_party/WebKit/Source/devtools/front_end/resources/ServiceWorkerCacheViews.js
index d688bee..40124cf 100644
--- a/third_party/WebKit/Source/devtools/front_end/resources/ServiceWorkerCacheViews.js
+++ b/third_party/WebKit/Source/devtools/front_end/resources/ServiceWorkerCacheViews.js
@@ -21,7 +21,7 @@
     this._createEditorToolbar();
 
     this._refreshButton = new UI.ToolbarButton(Common.UIString('Refresh'), 'largeicon-refresh');
-    this._refreshButton.addEventListener('click', this._refreshButtonClicked, this);
+    this._refreshButton.addEventListener(UI.ToolbarButton.Events.Click, this._refreshButtonClicked, this);
 
     this._pageSize = 50;
     this._skipCount = 0;
@@ -45,21 +45,27 @@
     var editorToolbar = new UI.Toolbar('data-view-toolbar', this.element);
 
     this._pageBackButton = new UI.ToolbarButton(Common.UIString('Show previous page'), 'largeicon-play-back');
-    this._pageBackButton.addEventListener('click', this._pageBackButtonClicked, this);
+    this._pageBackButton.addEventListener(UI.ToolbarButton.Events.Click, this._pageBackButtonClicked, this);
     editorToolbar.appendToolbarItem(this._pageBackButton);
 
     this._pageForwardButton = new UI.ToolbarButton(Common.UIString('Show next page'), 'largeicon-play');
     this._pageForwardButton.setEnabled(false);
-    this._pageForwardButton.addEventListener('click', this._pageForwardButtonClicked, this);
+    this._pageForwardButton.addEventListener(UI.ToolbarButton.Events.Click, this._pageForwardButtonClicked, this);
     editorToolbar.appendToolbarItem(this._pageForwardButton);
   }
 
-  _pageBackButtonClicked() {
+  /**
+   * @param {!Common.Event} event
+   */
+  _pageBackButtonClicked(event) {
     this._skipCount = Math.max(0, this._skipCount - this._pageSize);
     this._updateData(false);
   }
 
-  _pageForwardButtonClicked() {
+  /**
+   * @param {!Common.Event} event
+   */
+  _pageForwardButtonClicked(event) {
     this._skipCount = this._skipCount + this._pageSize;
     this._updateData(false);
   }
@@ -128,6 +134,9 @@
     this._model.loadCacheData(this._cache, skipCount, pageSize, this._updateDataCallback.bind(this, skipCount));
   }
 
+  /**
+   * @param {!Common.Event} event
+   */
   _refreshButtonClicked(event) {
     this._updateData(true);
   }
diff --git a/third_party/WebKit/Source/devtools/front_end/resources/ServiceWorkersView.js b/third_party/WebKit/Source/devtools/front_end/resources/ServiceWorkersView.js
index c7ca8771..bbd952e1 100644
--- a/third_party/WebKit/Source/devtools/front_end/resources/ServiceWorkersView.js
+++ b/third_party/WebKit/Source/devtools/front_end/resources/ServiceWorkersView.js
@@ -154,18 +154,18 @@
     this._toolbar = section.createToolbar();
     this._toolbar.renderAsLinks();
     this._updateButton = new UI.ToolbarButton(Common.UIString('Update'), undefined, Common.UIString('Update'));
-    this._updateButton.addEventListener('click', this._updateButtonClicked.bind(this));
+    this._updateButton.addEventListener(UI.ToolbarButton.Events.Click, this._updateButtonClicked, this);
     this._toolbar.appendToolbarItem(this._updateButton);
     this._pushButton = new UI.ToolbarButton(Common.UIString('Emulate push event'), undefined, Common.UIString('Push'));
-    this._pushButton.addEventListener('click', this._pushButtonClicked.bind(this));
+    this._pushButton.addEventListener(UI.ToolbarButton.Events.Click, this._pushButtonClicked, this);
     this._toolbar.appendToolbarItem(this._pushButton);
     this._syncButton =
         new UI.ToolbarButton(Common.UIString('Emulate background sync event'), undefined, Common.UIString('Sync'));
-    this._syncButton.addEventListener('click', this._syncButtonClicked.bind(this));
+    this._syncButton.addEventListener(UI.ToolbarButton.Events.Click, this._syncButtonClicked, this);
     this._toolbar.appendToolbarItem(this._syncButton);
     this._deleteButton =
         new UI.ToolbarButton(Common.UIString('Unregister service worker'), undefined, Common.UIString('Unregister'));
-    this._deleteButton.addEventListener('click', this._unregisterButtonClicked.bind(this));
+    this._deleteButton.addEventListener(UI.ToolbarButton.Events.Click, this._unregisterButtonClicked, this);
     this._toolbar.appendToolbarItem(this._deleteButton);
 
     // Preserve the order.
@@ -318,20 +318,32 @@
     message.appendChild(createLabel('#' + error.versionId + ': ' + error.errorMessage, 'smallicon-error'));
   }
 
-  _unregisterButtonClicked() {
+  /**
+   * @param {!Common.Event} event
+   */
+  _unregisterButtonClicked(event) {
     this._manager.deleteRegistration(this._registration.id);
   }
 
-  _updateButtonClicked() {
+  /**
+   * @param {!Common.Event} event
+   */
+  _updateButtonClicked(event) {
     this._manager.updateRegistration(this._registration.id);
   }
 
-  _pushButtonClicked() {
+  /**
+   * @param {!Common.Event} event
+   */
+  _pushButtonClicked(event) {
     var data = 'Test push message from DevTools.';
     this._manager.deliverPushMessage(this._registration.id, data);
   }
 
-  _syncButtonClicked() {
+  /**
+   * @param {!Common.Event} event
+   */
+  _syncButtonClicked(event) {
     var tag = 'test-tag-from-devtools';
     var lastChance = true;
     this._manager.dispatchSyncEvent(this._registration.id, tag, lastChance);
diff --git a/third_party/WebKit/Source/devtools/front_end/screencast/ScreencastApp.js b/third_party/WebKit/Source/devtools/front_end/screencast/ScreencastApp.js
index 25f1ac0..6946291 100644
--- a/third_party/WebKit/Source/devtools/front_end/screencast/ScreencastApp.js
+++ b/third_party/WebKit/Source/devtools/front_end/screencast/ScreencastApp.js
@@ -11,7 +11,7 @@
     this._enabledSetting = Common.settings.createSetting('screencastEnabled', true);
     this._toggleButton = new UI.ToolbarToggle(Common.UIString('Toggle screencast'), 'largeicon-phone');
     this._toggleButton.setToggled(this._enabledSetting.get());
-    this._toggleButton.addEventListener('click', this._toggleButtonClicked, this);
+    this._toggleButton.addEventListener(UI.ToolbarButton.Events.Click, this._toggleButtonClicked, this);
     SDK.targetManager.observeTargets(this);
   }
 
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/DebuggerModel.js b/third_party/WebKit/Source/devtools/front_end/sdk/DebuggerModel.js
index 60fcf43..4c0c485 100644
--- a/third_party/WebKit/Source/devtools/front_end/sdk/DebuggerModel.js
+++ b/third_party/WebKit/Source/devtools/front_end/sdk/DebuggerModel.js
@@ -411,8 +411,8 @@
     this._isPausing = false;
     this._debuggerPausedDetails = debuggerPausedDetails;
     if (this._debuggerPausedDetails) {
-      if (Runtime.experiments.isEnabled('emptySourceMapAutoStepping')) {
-        if (this.dispatchEventToListeners(SDK.DebuggerModel.Events.BeforeDebuggerPaused, this._debuggerPausedDetails))
+      if (Runtime.experiments.isEnabled('emptySourceMapAutoStepping') && this._beforePausedCallback) {
+        if (!this._beforePausedCallback.call(null, this._debuggerPausedDetails))
           return false;
       }
       this.dispatchEventToListeners(SDK.DebuggerModel.Events.DebuggerPaused, this._debuggerPausedDetails);
@@ -425,6 +425,13 @@
   }
 
   /**
+   * @param {?function(!SDK.DebuggerPausedDetails):boolean} callback
+   */
+  setBeforePausedCallback(callback) {
+    this._beforePausedCallback = callback;
+  }
+
+  /**
    * @param {!Array.<!Protocol.Debugger.CallFrame>} callFrames
    * @param {string} reason
    * @param {!Object|undefined} auxData
@@ -807,7 +814,6 @@
 SDK.DebuggerModel.Events = {
   DebuggerWasEnabled: Symbol('DebuggerWasEnabled'),
   DebuggerWasDisabled: Symbol('DebuggerWasDisabled'),
-  BeforeDebuggerPaused: Symbol('BeforeDebuggerPaused'),
   DebuggerPaused: Symbol('DebuggerPaused'),
   DebuggerResumed: Symbol('DebuggerResumed'),
   ParsedScriptSource: Symbol('ParsedScriptSource'),
diff --git a/third_party/WebKit/Source/devtools/front_end/settings/SettingsScreen.js b/third_party/WebKit/Source/devtools/front_end/settings/SettingsScreen.js
index 85c68583..37d4a3b 100644
--- a/third_party/WebKit/Source/devtools/front_end/settings/SettingsScreen.js
+++ b/third_party/WebKit/Source/devtools/front_end/settings/SettingsScreen.js
@@ -368,7 +368,7 @@
 
     var toolbar = new UI.Toolbar('');
     var button = new UI.ToolbarButton(Common.UIString('Remove'), 'largeicon-delete');
-    button.addEventListener('click', this._removeFileSystemClicked.bind(this, fileSystem));
+    button.addEventListener(UI.ToolbarButton.Events.Click, this._removeFileSystemClicked.bind(this, fileSystem));
     toolbar.appendToolbarItem(button);
     header.appendChild(toolbar.element);
 
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/InplaceFormatterEditorAction.js b/third_party/WebKit/Source/devtools/front_end/sources/InplaceFormatterEditorAction.js
index 7e8a6aa85..036a6fc8e 100644
--- a/third_party/WebKit/Source/devtools/front_end/sources/InplaceFormatterEditorAction.js
+++ b/third_party/WebKit/Source/devtools/front_end/sources/InplaceFormatterEditorAction.js
@@ -44,7 +44,7 @@
     this._sourcesView.addEventListener(Sources.SourcesView.Events.EditorClosed, this._editorClosed.bind(this));
 
     this._button = new UI.ToolbarButton(Common.UIString('Format'), 'largeicon-pretty-print');
-    this._button.addEventListener('click', this._formatSourceInPlace, this);
+    this._button.addEventListener(UI.ToolbarButton.Events.Click, this._formatSourceInPlace, this);
     this._updateButton(sourcesView.currentUISourceCode());
 
     return this._button;
@@ -64,7 +64,10 @@
     return uiSourceCode.contentType().isStyleSheet();
   }
 
-  _formatSourceInPlace() {
+  /**
+   * @param {!Common.Event} event
+   */
+  _formatSourceInPlace(event) {
     var uiSourceCode = this._sourcesView.currentUISourceCode();
     if (!this._isFormattable(uiSourceCode))
       return;
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/NavigatorView.js b/third_party/WebKit/Source/devtools/front_end/sources/NavigatorView.js
index 3180034..3b62f4c 100644
--- a/third_party/WebKit/Source/devtools/front_end/sources/NavigatorView.js
+++ b/third_party/WebKit/Source/devtools/front_end/sources/NavigatorView.js
@@ -950,22 +950,9 @@
     this.listItemElement.draggable = true;
     this.listItemElement.addEventListener('click', this._onclick.bind(this), false);
     this.listItemElement.addEventListener('contextmenu', this._handleContextMenuEvent.bind(this), false);
-    this.listItemElement.addEventListener('mousedown', this._onmousedown.bind(this), false);
     this.listItemElement.addEventListener('dragstart', this._ondragstart.bind(this), false);
   }
 
-  _onmousedown(event) {
-    if (event.which === 1)  // Warm-up data for drag'n'drop
-      this._uiSourceCode.requestContent().then(callback.bind(this));
-    /**
-     * @param {?string} content
-     * @this {Sources.NavigatorSourceTreeElement}
-     */
-    function callback(content) {
-      this._warmedUpContent = content;
-    }
-  }
-
   _shouldRenameOnMouseDown() {
     if (!this._uiSourceCode.canRename())
       return false;
@@ -992,10 +979,12 @@
     }
   }
 
+  /**
+   * @param {!DragEvent} event
+   */
   _ondragstart(event) {
-    event.dataTransfer.setData('text/plain', this._warmedUpContent);
+    event.dataTransfer.setData('text/plain', this._uiSourceCode.url());
     event.dataTransfer.effectAllowed = 'copy';
-    return true;
   }
 
   /**
@@ -1268,16 +1257,15 @@
         (this._uiSourceCode.isDirty() || Persistence.persistence.hasUnsavedCommittedChanges(this._uiSourceCode)))
       titleText = '*' + titleText;
 
+    this._treeElement.title = titleText;
+
     var binding = Persistence.persistence.binding(this._uiSourceCode);
     if (binding && Runtime.experiments.isEnabled('persistence2')) {
-      var titleElement = createElement('span');
-      titleElement.textContent = titleText;
-      var icon = UI.Icon.create('smallicon-checkmark', 'mapped-file-checkmark');
+      var icon = UI.Icon.create('smallicon-green-checkmark');
       icon.title = Persistence.PersistenceUtils.tooltipForUISourceCode(this._uiSourceCode);
-      titleElement.appendChild(icon);
-      this._treeElement.title = titleElement;
+      this._treeElement.setTrailingIcons([icon]);
     } else {
-      this._treeElement.title = titleText;
+      this._treeElement.setTrailingIcons([]);
     }
 
     var tooltip = this._uiSourceCode.url();
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/ObjectEventListenersSidebarPane.js b/third_party/WebKit/Source/devtools/front_end/sources/ObjectEventListenersSidebarPane.js
index db31f97..e1ba2fc 100644
--- a/third_party/WebKit/Source/devtools/front_end/sources/ObjectEventListenersSidebarPane.js
+++ b/third_party/WebKit/Source/devtools/front_end/sources/ObjectEventListenersSidebarPane.js
@@ -11,7 +11,7 @@
     this.element.classList.add('event-listeners-sidebar-pane');
 
     this._refreshButton = new UI.ToolbarButton(Common.UIString('Refresh'), 'largeicon-refresh');
-    this._refreshButton.addEventListener('click', this._refreshClick.bind(this));
+    this._refreshButton.addEventListener(UI.ToolbarButton.Events.Click, this._refreshClick, this);
     this._refreshButton.setEnabled(false);
 
     this._eventListenersView = new Components.EventListenersView(this.element, this.update.bind(this));
@@ -91,7 +91,7 @@
    * @param {!Common.Event} event
    */
   _refreshClick(event) {
-    event.consume();
+    event.data.consume();
     this.update();
   }
 };
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/ScriptFormatterEditorAction.js b/third_party/WebKit/Source/devtools/front_end/sources/ScriptFormatterEditorAction.js
index 1576286..402627f 100644
--- a/third_party/WebKit/Source/devtools/front_end/sources/ScriptFormatterEditorAction.js
+++ b/third_party/WebKit/Source/devtools/front_end/sources/ScriptFormatterEditorAction.js
@@ -194,7 +194,7 @@
     this._sourcesView.addEventListener(Sources.SourcesView.Events.EditorClosed, this._editorClosed.bind(this));
 
     this._button = new UI.ToolbarButton(Common.UIString('Pretty print'), 'largeicon-pretty-print');
-    this._button.addEventListener('click', this._toggleFormatScriptSource, this);
+    this._button.addEventListener(UI.ToolbarButton.Events.Click, this._toggleFormatScriptSource, this);
     this._updateButton(sourcesView.currentUISourceCode());
 
     return this._button;
@@ -216,7 +216,10 @@
     return uiSourceCode.contentType().hasScripts();
   }
 
-  _toggleFormatScriptSource() {
+  /**
+   * @param {!Common.Event} event
+   */
+  _toggleFormatScriptSource(event) {
     var uiSourceCode = this._sourcesView.currentUISourceCode();
     if (this._isFormatableScript(uiSourceCode))
       this._formatUISourceCodeScript(uiSourceCode);
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/SourcesNavigator.js b/third_party/WebKit/Source/devtools/front_end/sources/SourcesNavigator.js
index 0b8dbf6..d8611db 100644
--- a/third_party/WebKit/Source/devtools/front_end/sources/SourcesNavigator.js
+++ b/third_party/WebKit/Source/devtools/front_end/sources/SourcesNavigator.js
@@ -146,7 +146,8 @@
     var toolbar = new UI.Toolbar('navigator-toolbar');
     var title = Common.UIString('Add folder to workspace');
     var addButton = new UI.ToolbarButton(title, 'largeicon-add', title);
-    addButton.addEventListener('click', () => Workspace.isolatedFileSystemManager.addFileSystem());
+    addButton.addEventListener(
+        UI.ToolbarButton.Events.Click, () => Workspace.isolatedFileSystemManager.addFileSystem());
     toolbar.appendToolbarItem(addButton);
     this.element.insertBefore(toolbar.element, this.element.firstChild);
   }
@@ -197,7 +198,7 @@
     super();
     var toolbar = new UI.Toolbar('navigator-toolbar');
     var newButton = new UI.ToolbarButton('', 'largeicon-add', Common.UIString('New Snippet'));
-    newButton.addEventListener('click', this._handleCreateSnippet.bind(this));
+    newButton.addEventListener(UI.ToolbarButton.Events.Click, this._handleCreateSnippet.bind(this));
     toolbar.appendToolbarItem(newButton);
     this.element.insertBefore(toolbar.element, this.element.firstChild);
   }
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/SourcesPanel.js b/third_party/WebKit/Source/devtools/front_end/sources/SourcesPanel.js
index 9e93907c..fc305dd 100644
--- a/third_party/WebKit/Source/devtools/front_end/sources/SourcesPanel.js
+++ b/third_party/WebKit/Source/devtools/front_end/sources/SourcesPanel.js
@@ -595,16 +595,15 @@
   }
 
   /**
-   * @return {boolean}
+   * @param {!Common.Event} event
    */
-  _longResume() {
+  _longResume(event) {
     var debuggerModel = this._prepareToResume();
     if (!debuggerModel)
-      return true;
+      return;
 
     debuggerModel.skipAllPausesUntilReloadOrTimeout(500);
     debuggerModel.resume();
-    return true;
   }
 
   /**
@@ -681,7 +680,7 @@
 
     var longResumeButton =
         new UI.ToolbarButton(Common.UIString('Resume with all pauses blocked for 500 ms'), 'largeicon-play');
-    longResumeButton.addEventListener('click', this._longResume.bind(this), this);
+    longResumeButton.addEventListener(UI.ToolbarButton.Events.Click, this._longResume, this);
     debugToolbar.appendToolbarItem(UI.Toolbar.createActionButton(this._togglePauseAction, [longResumeButton], []));
 
     debugToolbar.appendToolbarItem(UI.Toolbar.createActionButton(this._stepOverAction));
@@ -691,7 +690,7 @@
     debugToolbar.appendToolbarItem(UI.Toolbar.createActionButton(this._toggleBreakpointsActiveAction));
 
     this._pauseOnExceptionButton = new UI.ToolbarToggle('', 'largeicon-pause-on-exceptions');
-    this._pauseOnExceptionButton.addEventListener('click', this._togglePauseOnExceptions, this);
+    this._pauseOnExceptionButton.addEventListener(UI.ToolbarButton.Events.Click, this._togglePauseOnExceptions, this);
     debugToolbar.appendToolbarItem(this._pauseOnExceptionButton);
 
     debugToolbar.appendSeparator();
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/WatchExpressionsSidebarPane.js b/third_party/WebKit/Source/devtools/front_end/sources/WatchExpressionsSidebarPane.js
index 6385a2a..fd34603 100644
--- a/third_party/WebKit/Source/devtools/front_end/sources/WatchExpressionsSidebarPane.js
+++ b/third_party/WebKit/Source/devtools/front_end/sources/WatchExpressionsSidebarPane.js
@@ -43,9 +43,9 @@
     this._watchExpressionsSetting = Common.settings.createLocalSetting('watchExpressions', []);
 
     this._addButton = new UI.ToolbarButton(Common.UIString('Add expression'), 'largeicon-add');
-    this._addButton.addEventListener('click', this._addButtonClicked.bind(this));
+    this._addButton.addEventListener(UI.ToolbarButton.Events.Click, this._addButtonClicked.bind(this));
     this._refreshButton = new UI.ToolbarButton(Common.UIString('Refresh'), 'largeicon-refresh');
-    this._refreshButton.addEventListener('click', this._refreshButtonClicked.bind(this));
+    this._refreshButton.addEventListener(UI.ToolbarButton.Events.Click, this.update, this);
 
     this._bodyElement = this.element.createChild('div', 'vbox watch-expressions');
     this._bodyElement.addEventListener('contextmenu', this._contextMenu.bind(this), false);
@@ -82,25 +82,12 @@
     this._watchExpressionsSetting.set(toSave);
   }
 
-  /**
-   * @param {!Common.Event=} event
-   */
-  _addButtonClicked(event) {
-    if (event)
-      event.consume(true);
+  _addButtonClicked() {
     UI.viewManager.showView('sources.watch');
     this._createWatchExpression(null).startEditing();
   }
 
   /**
-   * @param {!Common.Event} event
-   */
-  _refreshButtonClicked(event) {
-    event.consume();
-    this.update();
-  }
-
-  /**
    * @override
    * @return {!Promise.<?>}
    */
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/XHRBreakpointsSidebarPane.js b/third_party/WebKit/Source/devtools/front_end/sources/XHRBreakpointsSidebarPane.js
index 69b130b..d21e644 100644
--- a/third_party/WebKit/Source/devtools/front_end/sources/XHRBreakpointsSidebarPane.js
+++ b/third_party/WebKit/Source/devtools/front_end/sources/XHRBreakpointsSidebarPane.js
@@ -16,7 +16,7 @@
     this._breakpointElements = new Map();
 
     this._addButton = new UI.ToolbarButton(Common.UIString('Add breakpoint'), 'largeicon-add');
-    this._addButton.addEventListener('click', this._addButtonClicked.bind(this));
+    this._addButton.addEventListener(UI.ToolbarButton.Events.Click, this._addButtonClicked.bind(this));
 
     this.emptyElement.addEventListener('contextmenu', this._emptyElementContextMenu.bind(this), true);
     SDK.targetManager.observeTargets(this, SDK.Target.Capability.Browser);
@@ -52,10 +52,7 @@
     contextMenu.show();
   }
 
-  _addButtonClicked(event) {
-    if (event)
-      event.consume();
-
+  _addButtonClicked() {
     UI.viewManager.showView('sources.xhrBreakpoints');
 
     var inputElementContainer = createElementWithClass('p', 'breakpoint-condition');
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/navigatorTree.css b/third_party/WebKit/Source/devtools/front_end/sources/navigatorTree.css
index b4418f4..e7a45e3b 100644
--- a/third_party/WebKit/Source/devtools/front_end/sources/navigatorTree.css
+++ b/third_party/WebKit/Source/devtools/front_end/sources/navigatorTree.css
@@ -52,15 +52,6 @@
     opacity: 0.5;
 }
 
-.mapped-file-checkmark {
-    background: #009802;
-    margin-left: 3px;
-}
-
-:focus .navigator-file-tree-item.selected .mapped-file-checkmark {
-    background: white !important;
-}
-
 :focus .navigator-file-tree-item.selected .icon {
     background: white !important;
 }
diff --git a/third_party/WebKit/Source/devtools/front_end/text_editor/CodeMirrorTextEditor.js b/third_party/WebKit/Source/devtools/front_end/text_editor/CodeMirrorTextEditor.js
index acd1700..0310ab6 100644
--- a/third_party/WebKit/Source/devtools/front_end/text_editor/CodeMirrorTextEditor.js
+++ b/third_party/WebKit/Source/devtools/front_end/text_editor/CodeMirrorTextEditor.js
@@ -172,6 +172,8 @@
 
     this._needsRefresh = true;
 
+    this._readOnly = false;
+
     this._mimeType = '';
     if (options.mimeType)
       this.setMimeType(options.mimeType);
@@ -711,6 +713,10 @@
    * @param {boolean} readOnly
    */
   setReadOnly(readOnly) {
+    if (this._readOnly === readOnly)
+      return;
+    this.clearPositionHighlight();
+    this._readOnly = readOnly;
     this.element.classList.toggle('CodeMirror-readonly', readOnly);
     this._codeMirror.setOption('readOnly', readOnly);
   }
@@ -903,8 +909,10 @@
       return;
     this.scrollLineIntoView(lineNumber);
     if (shouldHighlight) {
-      this._codeMirror.addLineClass(this._highlightedLine, null, 'cm-highlight');
-      this._clearHighlightTimeout = setTimeout(this.clearPositionHighlight.bind(this), 2000);
+      this._codeMirror.addLineClass(
+          this._highlightedLine, null, this._readOnly ? 'cm-readonly-highlight' : 'cm-highlight');
+      if (!this._readOnly)
+        this._clearHighlightTimeout = setTimeout(this.clearPositionHighlight.bind(this), 2000);
     }
     this.setSelection(Common.TextRange.createFromLocation(lineNumber, columnNumber));
   }
@@ -914,8 +922,10 @@
       clearTimeout(this._clearHighlightTimeout);
     delete this._clearHighlightTimeout;
 
-    if (this._highlightedLine)
-      this._codeMirror.removeLineClass(this._highlightedLine, null, 'cm-highlight');
+    if (this._highlightedLine) {
+      this._codeMirror.removeLineClass(
+          this._highlightedLine, null, this._readOnly ? 'cm-readonly-highlight' : 'cm-highlight');
+    }
     delete this._highlightedLine;
   }
 
diff --git a/third_party/WebKit/Source/devtools/front_end/text_editor/cmdevtools.css b/third_party/WebKit/Source/devtools/front_end/text_editor/cmdevtools.css
index 969daea..c143868 100644
--- a/third_party/WebKit/Source/devtools/front_end/text_editor/cmdevtools.css
+++ b/third_party/WebKit/Source/devtools/front_end/text_editor/cmdevtools.css
@@ -70,6 +70,14 @@
     to { background-color: transparent; }
 }
 
+.cm-readonly-highlight {
+    background-color: rgb(255, 255, 120);
+}
+
+.-theme-with-dark-background .cm-readonly-highlight {
+    background-color: hsla(133, 100%, 30%, 0.5);
+}
+
 .cm-highlight.cm-execution-line {
     -webkit-animation: fadeout-execution-line 1s 0s;
 }
@@ -378,11 +386,11 @@
     top: -9px;
 }
 
-.CodeMirror .text-editor-line-with-warning:not(.cm-execution-line) {
+.CodeMirror .text-editor-line-with-warning:not(.cm-execution-line):not(.cm-readonly-highlight) {
     background-color: rgba(241, 230, 0, 0.1);
 }
 
-.CodeMirror .text-editor-line-with-error:not(.cm-execution-line) {
+.CodeMirror .text-editor-line-with-error:not(.cm-execution-line):not(.cm-readonly-highlight) {
     background-color: rgba(255, 0, 0, 0.05);
 }
 
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineLandingPage.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineLandingPage.js
new file mode 100644
index 0000000..559a97c
--- /dev/null
+++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineLandingPage.js
@@ -0,0 +1,172 @@
+// 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.
+
+Timeline.TimelineLandingPage = class extends UI.VBox {
+  constructor() {
+    super(true);
+    this.registerRequiredCSS('timeline/timelineLandingPage.css');
+    this.contentElement.classList.add('timeline-landing-page', 'fill');
+    const perspectives = Timeline.TimelinePanel.Perspectives;
+    const config = Timeline.TimelineLandingPage.RecordingConfig;
+    this._tabbedPane = new UI.TabbedPane();
+    this._tabbedPane.setTabSlider(true);
+    this._tabbedPane.renderWithNoHeaderBackground();
+
+    var tab = new Timeline.TimelineLandingPage.PerspectiveTabWidget();
+    tab.setDescription(Common.UIString(
+        'Page Load mode allows you to analyze how fast the page is loaded and becomes responsive.\n' +
+        'In this mode the page is automatically reloaded right after the recording has started. ' +
+        'During recording it collects information about network requests, screen state updates, ' +
+        'and CPU threads acivity along with JavaScript stacks. ' +
+        'Recording is stopped automatically shortly after the page processes load event.'));
+    tab.setAction(recordAndReload);
+    tab.appendOption(config.network, false, true);
+    tab.appendOption(config.screenshots, true, true);
+    this._tabbedPane.appendTab(perspectives.Load, Common.UIString('Page Load'), tab);
+
+    tab = new Timeline.TimelineLandingPage.PerspectiveTabWidget();
+    tab.setDescription(Common.UIString('Record page responsiveness.'));
+    tab.setAction(record);
+    tab.appendOption(config.network, false, true);
+    tab.appendOption(config.screenshots, true, false);
+    this._tabbedPane.appendTab(perspectives.Responsiveness, Common.UIString('Responsiveness'), tab);
+
+    tab = new Timeline.TimelineLandingPage.PerspectiveTabWidget();
+    tab.setDescription(Common.UIString(
+        'This mode is useful when you want to focus on JavaScript performance. ' +
+        'All the options besides sampling CPU profiler are turned off to minimize measurement errors.'));
+    tab.setAction(record);
+    this._tabbedPane.appendTab(perspectives.JavaScript, Common.UIString('JavaScript'), tab);
+
+    tab = new Timeline.TimelineLandingPage.PerspectiveTabWidget();
+    tab.setDescription(Common.UIString('Advanced mode that allows you to customize recording options.'));
+    tab.setAction(record);
+    tab.appendOption(config.network, true, true);
+    tab.appendOption(config.javascript, true, true);
+    tab.appendOption(config.screenshots, true, true);
+    tab.appendOption(config.memory, true, false);
+    tab.appendOption(config.paints, true, false);
+    this._tabbedPane.appendTab(perspectives.Custom, Common.UIString('Custom'), tab);
+
+    this._tabbedPane.addEventListener(UI.TabbedPane.Events.TabSelected, this._tabSelected, this);
+    this._tabbedPane.show(this.contentElement);
+    this._perspectiveSetting =
+        Common.settings.createSetting('timelinePerspective', Timeline.TimelinePanel.Perspectives.Load);
+    this._perspectiveSetting.addChangeListener(this._perspectiveChanged, this);
+
+    function record() {
+      UI.actionRegistry.action('timeline.toggle-recording').execute();
+    }
+
+    function recordAndReload() {
+      SDK.targetManager.reloadPage();
+    }
+  }
+
+  /**
+   * @param {!Common.Event} event
+   */
+  _tabSelected(event) {
+    if (this._perspectiveSetting.get() !== event.data.tabId)
+      this._perspectiveSetting.set(event.data.tabId);
+  }
+
+  _perspectiveChanged() {
+    this._tabbedPane.selectTab(this._perspectiveSetting.get());
+    const tabWidget = /** @type {!Timeline.TimelineLandingPage.PerspectiveTabWidget} */ (this._tabbedPane.visibleView);
+    tabWidget.activate();
+  }
+};
+
+/** @typedef {!{id: string, title: string, description: string, setting: string}} */
+Timeline.TimelineLandingPage.RecordingOption;
+
+/** @type {!Object<string, !Timeline.TimelineLandingPage.RecordingOption>} */
+Timeline.TimelineLandingPage.RecordingConfig = {
+  network: {
+    id: 'network',
+    title: Common.UIString('Network'),
+    description: Common.UIString('Capture network requests information.'),
+    setting: 'timelineCaptureNetwork'
+  },
+  javascript: {
+    id: 'javascript',
+    title: Common.UIString('JavaScript'),
+    description: Common.UIString('Use sampling CPU profiler to collect JavaScript stacks.'),
+    setting: 'timelineEnableJSSampling'
+  },
+  screenshots: {
+    id: 'screenshots',
+    title: Common.UIString('Screenshots'),
+    description:
+        Common.UIString('Collect page screenshots, so you can observe how the page was evolving during recording.'),
+    setting: 'timelineCaptureFilmStrip'
+  },
+  paints: {
+    id: 'paints',
+    title: Common.UIString('Paints'),
+    description: Common.UIString(
+        'Capture graphics layer positions and rasterization draw calls (moderate performance overhead).'),
+    setting: 'timelineCaptureLayersAndPictures'
+  },
+  memory: {
+    id: 'memory',
+    title: Common.UIString('Memory'),
+    description: Common.UIString('Capture memory statistics on every timeline event.'),
+    setting: 'timelineCaptureMemory'
+  }
+};
+
+Timeline.TimelineLandingPage.PerspectiveTabWidget = class extends UI.VBox {
+  constructor() {
+    super(false);
+    this.contentElement.classList.add('timeline-perspective-body');
+    this._enabledOptions = new Set([Timeline.TimelineLandingPage.RecordingConfig.javascript.id]);
+    this._descriptionDiv = this.contentElement.createChild('div', 'timeline-perspective-description');
+    this._actionButton = createTextButton(Common.UIString('Start'));
+    this._actionButtonDiv = this.contentElement.createChild('div');
+    this._actionButtonDiv.appendChild(this._actionButton);
+  }
+
+  /**
+   * @param {string} text
+   */
+  setDescription(text) {
+    this._descriptionDiv.textContent = text;
+  }
+
+  /**
+   * @param {function()} action
+   */
+  setAction(action) {
+    this._actionButton.addEventListener('click', action);
+  }
+
+  /**
+   * @param {!Timeline.TimelineLandingPage.RecordingOption} option
+   * @param {boolean} visible
+   * @param {boolean} enabled
+   */
+  appendOption(option, visible, enabled) {
+    if (enabled)
+      this._enabledOptions.add(option.id);
+    if (!visible)
+      return;
+    const div = createElementWithClass('div', 'recording-setting');
+    const value = this._enabledOptions.has(option.id);
+    const setting = Common.settings.createSetting(option.setting, value);
+    div.appendChild(UI.SettingsUI.createSettingCheckbox(option.title, setting, true));
+    if (option.description)
+      div.createChild('div', 'recording-setting-description').textContent = option.description;
+    this.contentElement.insertBefore(div, this._actionButtonDiv);
+  }
+
+  activate() {
+    for (const id in Timeline.TimelineLandingPage.RecordingConfig) {
+      const config = Timeline.TimelineLandingPage.RecordingConfig[id];
+      const setting = Common.settings.createSetting(config.setting, false);
+      setting.set(this._enabledOptions.has(id));
+    }
+  }
+};
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePanel.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePanel.js
index 3b0192f..ff8fd7cd 100644
--- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePanel.js
+++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePanel.js
@@ -83,16 +83,16 @@
 
     this._panelToolbar = new UI.Toolbar('', this.element);
 
-    var timelinePane = new UI.VBox();
-    timelinePane.show(this.element);
-    var topPaneElement = timelinePane.element.createChild('div', 'hbox');
+    this._timelinePane = new UI.VBox();
+    this._timelinePane.show(this.element);
+    var topPaneElement = this._timelinePane.element.createChild('div', 'hbox');
     topPaneElement.id = 'timeline-overview-panel';
 
     // Create top overview component.
     this._overviewPane = new UI.TimelineOverviewPane('timeline');
     this._overviewPane.addEventListener(UI.TimelineOverviewPane.Events.WindowChanged, this._onWindowChanged.bind(this));
     this._overviewPane.show(topPaneElement);
-    this._statusPaneContainer = timelinePane.element.createChild('div', 'status-pane-container fill');
+    this._statusPaneContainer = this._timelinePane.element.createChild('div', 'status-pane-container fill');
 
     this._createFileSelector();
 
@@ -122,7 +122,7 @@
     this._captureMemorySetting.addChangeListener(this._onModeChanged, this);
     this._captureFilmStripSetting.addChangeListener(this._onModeChanged, this);
 
-    this._detailsSplitWidget.show(timelinePane.element);
+    this._detailsSplitWidget.show(this._timelinePane.element);
     this._detailsSplitWidget.hideSidebar();
     SDK.targetManager.addEventListener(SDK.TargetManager.Events.SuspendStateChanged, this._onSuspendStateChanged, this);
     this._showRecordingHelpMessage();
@@ -282,7 +282,7 @@
     if (Runtime.experiments.isEnabled('timelineRecordingPerspectives') &&
         perspectiveSetting.get() === Timeline.TimelinePanel.Perspectives.Load) {
       this._reloadButton = new UI.ToolbarButton(Common.UIString('Record & Reload'), 'largeicon-refresh');
-      this._reloadButton.addEventListener('click', () => SDK.targetManager.reloadPage());
+      this._reloadButton.addEventListener(UI.ToolbarButton.Events.Click, () => SDK.targetManager.reloadPage());
       this._panelToolbar.appendToolbarItem(this._reloadButton);
     } else {
       this._panelToolbar.appendToolbarItem(UI.Toolbar.createActionButton(this._toggleRecordAction));
@@ -290,7 +290,7 @@
 
     // Clear
     var clearButton = new UI.ToolbarButton(Common.UIString('Clear recording'), 'largeicon-clear');
-    clearButton.addEventListener('click', this._clear, this);
+    clearButton.addEventListener(UI.ToolbarButton.Events.Click, this._clear, this);
     this._panelToolbar.appendToolbarItem(clearButton);
 
     this._panelToolbar.appendSeparator();
@@ -410,7 +410,7 @@
      * @param {string} name
      * @param {number} value
      */
-    function addGroupingOption(name, value) {
+    function addOption(name, value) {
       var option = cpuThrottlingCombobox.createOption(name, '', String(value));
       cpuThrottlingCombobox.addOption(option);
       if (hasSelection || (value && value !== currentRate))
@@ -418,13 +418,9 @@
       cpuThrottlingCombobox.select(option);
       hasSelection = true;
     }
-    var predefinedRates = new Map([
-      [1, Common.UIString('No CPU throttling')], [2, Common.UIString('2\xD7 slowdown')],
-      [5, Common.UIString('5\xD7 slowdown')], [10, Common.UIString('10\xD7 slowdown')],
-      [20, Common.UIString('20\xD7 slowdown')]
-    ]);
-    for (var rate of predefinedRates)
-      addGroupingOption(rate[1], rate[0]);
+    addOption(Common.UIString('No CPU throttling'), 1);
+    for (const rate of [2, 5, 10, 20])
+      addOption(Common.UIString('%d\xD7 slowdown', rate), rate);
   }
 
   _prepareToLoadTimeline() {
@@ -633,32 +629,34 @@
   }
 
   _clear() {
+    this._showRecordingHelpMessage();
+    this._detailsSplitWidget.hideSidebar();
+    this._reset();
+  }
+
+  _reset() {
     if (Runtime.experiments.isEnabled('timelineRuleUsageRecording') && this._markUnusedCSS.get())
       Components.CoverageProfile.instance().reset();
 
     Components.LineLevelProfile.instance().reset();
     this._tracingModel.reset();
     this._model.reset();
-    this._showRecordingHelpMessage();
 
     this.requestWindowTimes(0, Infinity);
     delete this._selection;
     this._frameModel.reset();
     this._filmStripModel.reset(this._tracingModel);
     this._overviewPane.reset();
-    for (var i = 0; i < this._currentViews.length; ++i)
-      this._currentViews[i].reset();
-    for (var i = 0; i < this._overviewControls.length; ++i)
-      this._overviewControls[i].reset();
+    this._currentViews.forEach(view => view.reset());
+    this._overviewControls.forEach(overview => overview.reset());
     this.select(null);
-    this._detailsSplitWidget.hideSidebar();
   }
 
   /**
    * @override
    */
   recordingStarted() {
-    this._clear();
+    this._reset();
     this._setState(Timeline.TimelinePanel.State.Recording);
     this._showRecordingStarted();
     this._statusPane.updateStatus(Common.UIString('Recording\u2026'));
@@ -676,6 +674,11 @@
   }
 
   _showRecordingHelpMessage() {
+    if (Runtime.experiments.isEnabled('timelineLandingPage')) {
+      this._showLandingPage();
+      return;
+    }
+
     /**
      * @param {string} tagName
      * @param {string} contents
@@ -710,11 +713,31 @@
   }
 
   _hideRecordingHelpMessage() {
+    if (Runtime.experiments.isEnabled('timelineLandingPage')) {
+      this._hideLandingPage();
+      return;
+    }
     if (this._helpMessageElement)
       this._helpMessageElement.remove();
     delete this._helpMessageElement;
   }
 
+  _showLandingPage() {
+    if (this._landingPage)
+      return;
+    this._detailsSplitWidget.detach();
+    this._landingPage = new Timeline.TimelineLandingPage();
+    this._landingPage.show(this._timelinePane.element);
+  }
+
+  _hideLandingPage() {
+    if (!this._landingPage)
+      return;
+    this._landingPage.detach();
+    this._landingPage = null;
+    this._detailsSplitWidget.show(this._timelinePane.element);
+  }
+
   /**
    * @override
    */
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/module.json b/third_party/WebKit/Source/devtools/front_end/timeline/module.json
index 4e31b04..205c09a 100644
--- a/third_party/WebKit/Source/devtools/front_end/timeline/module.json
+++ b/third_party/WebKit/Source/devtools/front_end/timeline/module.json
@@ -131,6 +131,7 @@
         "TimelineFlameChart.js",
         "TimelineNetworkFlameChart.js",
         "TimelineTreeView.js",
+        "TimelineLandingPage.js",
         "TimelineUIUtils.js",
         "TimelineLayersView.js",
         "TimelinePaintProfilerView.js",
@@ -139,6 +140,7 @@
     "resources": [
         "invalidationsTree.css",
         "timelineFlamechartPopover.css",
+        "timelineLandingPage.css",
         "timelinePanel.css",
         "timelinePaintProfiler.css",
         "timelineStatusDialog.css"
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/timelineLandingPage.css b/third_party/WebKit/Source/devtools/front_end/timeline/timelineLandingPage.css
new file mode 100644
index 0000000..d6a652f1
--- /dev/null
+++ b/third_party/WebKit/Source/devtools/front_end/timeline/timelineLandingPage.css
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2016 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+.timeline-landing-page {
+    align-self: center;
+    max-width: 500px;
+    font-size: 13px;
+}
+
+.timeline-landing-page .tabbed-pane {
+    padding: 10px 0 0 0;
+}
+
+.timeline-landing-page .timeline-perspective-body {
+    align-items: stretch;
+    line-height: 1.5;
+    padding: 12px;
+    white-space: pre-line;
+    width: 100%;
+    font-size: 12px;
+}
+
+.timeline-landing-page .timeline-perspective-body > div {
+    margin-bottom: 12px;
+    flex-shrink: 0;
+}
+
+.timeline-landing-page button {
+    min-width: 90px;
+    min-height: 26px;
+    margin: 10px 0 0 0;
+}
+
+.timeline-landing-page .recording-setting {
+    display: flex;
+    align-items: flex-start;
+    margin-bottom: 2px !important;
+}
+
+.timeline-landing-page .recording-setting label {
+    flex: 0 0 100px;
+}
+
+.timeline-landing-page .recording-setting-description {
+    color: #999;
+}
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/FilterBar.js b/third_party/WebKit/Source/devtools/front_end/ui/FilterBar.js
index 34afd71e..75225cf 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui/FilterBar.js
+++ b/third_party/WebKit/Source/devtools/front_end/ui/FilterBar.js
@@ -44,7 +44,7 @@
     this.element.classList.add('filter-bar');
 
     this._filterButton = new UI.ToolbarToggle(Common.UIString('Filter'), 'largeicon-filter');
-    this._filterButton.addEventListener('click', this._handleFilterButtonClick, this);
+    this._filterButton.addEventListener(UI.ToolbarButton.Events.Click, this._handleFilterButtonClick, this);
 
     this._filters = [];
 
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/InspectorView.js b/third_party/WebKit/Source/devtools/front_end/ui/InspectorView.js
index 95178e7d..5e83c12 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui/InspectorView.js
+++ b/third_party/WebKit/Source/devtools/front_end/ui/InspectorView.js
@@ -51,7 +51,7 @@
     this._drawerTabbedPane = this._drawerTabbedLocation.tabbedPane();
     this._drawerTabbedPane.setMinimumSize(0, 27);
     var closeDrawerButton = new UI.ToolbarButton(Common.UIString('Close drawer'), 'largeicon-delete');
-    closeDrawerButton.addEventListener('click', this._closeDrawer.bind(this));
+    closeDrawerButton.addEventListener(UI.ToolbarButton.Events.Click, this._closeDrawer, this);
     this._drawerTabbedPane.rightToolbar().appendToolbarItem(closeDrawerButton);
     this._drawerSplitWidget.installResizer(this._drawerTabbedPane.headerElement());
     this._drawerSplitWidget.setSidebarWidget(this._drawerTabbedPane);
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/SearchableView.js b/third_party/WebKit/Source/devtools/front_end/ui/SearchableView.js
index d7f95e81..9edae2f 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui/SearchableView.js
+++ b/third_party/WebKit/Source/devtools/front_end/ui/SearchableView.js
@@ -54,14 +54,14 @@
     if (this._searchProvider.supportsCaseSensitiveSearch()) {
       this._caseSensitiveButton = new UI.ToolbarToggle(Common.UIString('Case sensitive'), '');
       this._caseSensitiveButton.setText('Aa');
-      this._caseSensitiveButton.addEventListener('click', this._toggleCaseSensitiveSearch, this);
+      this._caseSensitiveButton.addEventListener(UI.ToolbarButton.Events.Click, this._toggleCaseSensitiveSearch, this);
       toolbar.appendToolbarItem(this._caseSensitiveButton);
     }
 
     if (this._searchProvider.supportsRegexSearch()) {
       this._regexButton = new UI.ToolbarToggle(Common.UIString('Regex'), '');
       this._regexButton.setText('.*');
-      this._regexButton.addEventListener('click', this._toggleRegexSearch, this);
+      this._regexButton.addEventListener(UI.ToolbarButton.Events.Click, this._toggleRegexSearch, this);
       toolbar.appendToolbarItem(this._regexButton);
     }
 
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/SplitWidget.js b/third_party/WebKit/Source/devtools/front_end/ui/SplitWidget.js
index ea73d19..72d4fe4 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui/SplitWidget.js
+++ b/third_party/WebKit/Source/devtools/front_end/ui/SplitWidget.js
@@ -832,7 +832,7 @@
   createShowHideSidebarButton(title) {
     this._showHideSidebarButtonTitle = Common.UIString(title);
     this._showHideSidebarButton = new UI.ToolbarButton('', '');
-    this._showHideSidebarButton.addEventListener('click', buttonClicked.bind(this));
+    this._showHideSidebarButton.addEventListener(UI.ToolbarButton.Events.Click, buttonClicked, this);
     this._updateShowHideSidebarButton();
 
     /**
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/TabbedPane.js b/third_party/WebKit/Source/devtools/front_end/ui/TabbedPane.js
index 3616263..d9ad72f 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui/TabbedPane.js
+++ b/third_party/WebKit/Source/devtools/front_end/ui/TabbedPane.js
@@ -455,6 +455,7 @@
   setTabSlider(enable) {
     this._sliderEnabled = enable;
     this._tabSlider.classList.toggle('enabled', enable);
+    this._headerElement.classList.add('tabbed-pane-no-tab-borders');
   }
 
   /**
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/Toolbar.js b/third_party/WebKit/Source/devtools/front_end/ui/Toolbar.js
index 29a80f9..62958369 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui/Toolbar.js
+++ b/third_party/WebKit/Source/devtools/front_end/ui/Toolbar.js
@@ -57,7 +57,7 @@
   static createActionButton(action, toggledOptions, untoggledOptions) {
     var button = new UI.ToolbarToggle(action.title(), action.icon(), action.toggledIcon());
     button.setToggleWithRedColor(action.toggleWithRedColor());
-    button.addEventListener('click', action.execute, action);
+    button.addEventListener(UI.ToolbarButton.Events.Click, action.execute, action);
     action.addEventListener(UI.Action.Events.Enabled, enabledChanged);
     action.addEventListener(UI.Action.Events.Toggled, toggled);
     /** @type {?UI.LongClickController} */
@@ -107,7 +107,7 @@
     function showOptions() {
       var buttons = longClickButtons.slice();
       var mainButtonClone = new UI.ToolbarToggle(action.title(), action.icon(), action.toggledIcon());
-      mainButtonClone.addEventListener('click', clicked);
+      mainButtonClone.addEventListener(UI.ToolbarButton.Events.Click, clicked);
 
       /**
        * @param {!Common.Event} event
@@ -511,25 +511,30 @@
    * @param {!Event} event
    */
   _clicked(event) {
-    var defaultPrevented = this.dispatchEventToListeners('click', event);
-    event.consume(defaultPrevented);
+    this.dispatchEventToListeners(UI.ToolbarButton.Events.Click, event);
   }
 
   /**
    * @param {!Event} event
    */
   _mouseDown(event) {
-    this.dispatchEventToListeners('mousedown', event);
+    this.dispatchEventToListeners(UI.ToolbarButton.Events.MouseDown, event);
   }
 
   /**
    * @param {!Event} event
    */
   _mouseUp(event) {
-    this.dispatchEventToListeners('mouseup', event);
+    this.dispatchEventToListeners(UI.ToolbarButton.Events.MouseUp, event);
   }
 };
 
+UI.ToolbarButton.Events = {
+  Click: Symbol('Click'),
+  MouseDown: Symbol('MouseDown'),
+  MouseUp: Symbol('MouseUp')
+};
+
 /**
  * @unrestricted
  */
@@ -569,7 +574,7 @@
 };
 
 UI.ToolbarInput.Event = {
-  TextChanged: 'TextChanged'
+  TextChanged: Symbol('TextChanged')
 };
 
 /**
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/tabbedPane.css b/third_party/WebKit/Source/devtools/front_end/ui/tabbedPane.css
index 2d72edb..ee8aacf 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui/tabbedPane.css
+++ b/third_party/WebKit/Source/devtools/front_end/ui/tabbedPane.css
@@ -269,6 +269,15 @@
     background-color: transparent;
 }
 
+.tabbed-pane-no-tab-borders .tabbed-pane-header-tab {
+    border: none;
+    padding: 2px 10px;
+}
+
+.tabbed-pane-no-tab-borders .tabbed-pane-header-contents {
+    margin-left: 0;
+}
+
 .tabbed-pane-left-toolbar {
     margin-right: -4px;
     flex: none;
diff --git a/third_party/WebKit/Source/devtools/front_end/ui_lazy/OverviewGrid.js b/third_party/WebKit/Source/devtools/front_end/ui_lazy/OverviewGrid.js
index 90c5f20..856470c 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui_lazy/OverviewGrid.js
+++ b/third_party/WebKit/Source/devtools/front_end/ui_lazy/OverviewGrid.js
@@ -110,6 +110,13 @@
   }
 
   /**
+   * @param {?function(!Event):boolean} clickHandler
+   */
+  setClickHandler(clickHandler) {
+    this._window.setClickHandler(clickHandler);
+  }
+
+  /**
    * @param {number} zoomFactor
    * @param {number} referencePoint
    */
@@ -185,6 +192,13 @@
   }
 
   /**
+   * @param {?function(!Event):boolean} clickHandler
+   */
+  setClickHandler(clickHandler) {
+    this._clickHandler = clickHandler;
+  }
+
+  /**
    * @param {!Event} event
    */
   _resizerElementStartDragging(event) {
@@ -240,7 +254,7 @@
     delete this._overviewWindowSelector;
     var clickThreshold = 3;
     if (window.end - window.start < clickThreshold) {
-      if (this.dispatchEventToListeners(UI.OverviewGrid.Events.Click, event))
+      if (this._clickHandler && this._clickHandler.call(null, event))
         return;
       var middle = window.end;
       window.start = Math.max(0, middle - UI.OverviewGrid.MinSelectableSize / 2);
@@ -405,8 +419,7 @@
 
 /** @enum {symbol} */
 UI.OverviewGrid.Events = {
-  WindowChanged: Symbol('WindowChanged'),
-  Click: Symbol('Click')
+  WindowChanged: Symbol('WindowChanged')
 };
 
 /**
diff --git a/third_party/WebKit/Source/devtools/front_end/ui_lazy/TimelineOverviewPane.js b/third_party/WebKit/Source/devtools/front_end/ui_lazy/TimelineOverviewPane.js
index 9daeb84..3992575 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui_lazy/TimelineOverviewPane.js
+++ b/third_party/WebKit/Source/devtools/front_end/ui_lazy/TimelineOverviewPane.js
@@ -49,7 +49,7 @@
 
     this._overviewGrid.setResizeEnabled(false);
     this._overviewGrid.addEventListener(UI.OverviewGrid.Events.WindowChanged, this._onWindowChanged, this);
-    this._overviewGrid.addEventListener(UI.OverviewGrid.Events.Click, this._onClick, this);
+    this._overviewGrid.setClickHandler(this._onClick.bind(this));
     this._overviewControls = [];
     this._markers = new Map();
 
@@ -264,16 +264,15 @@
   }
 
   /**
-   * @param {!Common.Event} event
+   * @param {!Event} event
+   * @return {boolean}
    */
   _onClick(event) {
-    var domEvent = /** @type {!Event} */ (event.data);
     for (var overviewControl of this._overviewControls) {
-      if (overviewControl.onClick(domEvent)) {
-        event.preventDefault();
-        return;
-      }
+      if (overviewControl.onClick(event))
+        return true;
     }
+    return false;
   }
 
   /**
diff --git a/third_party/WebKit/Source/modules/bluetooth/BluetoothRemoteGATTCharacteristic.cpp b/third_party/WebKit/Source/modules/bluetooth/BluetoothRemoteGATTCharacteristic.cpp
index 0d4f5a8d..f679ecb 100644
--- a/third_party/WebKit/Source/modules/bluetooth/BluetoothRemoteGATTCharacteristic.cpp
+++ b/third_party/WebKit/Source/modules/bluetooth/BluetoothRemoteGATTCharacteristic.cpp
@@ -368,14 +368,6 @@
 
 ScriptPromise BluetoothRemoteGATTCharacteristic::stopNotifications(
     ScriptState* scriptState) {
-#if OS(MACOSX)
-  // TODO(jlebel): Remove when stopNotifications is implemented.
-  return ScriptPromise::rejectWithDOMException(
-      scriptState, DOMException::create(NotSupportedError,
-                                        "stopNotifications is not implemented "
-                                        "yet. See https://goo.gl/J6ASzs"));
-#endif  // OS(MACOSX)
-
   if (!gatt()->connected()) {
     return ScriptPromise::rejectWithDOMException(
         scriptState,
diff --git a/third_party/WebKit/Source/modules/budget/BudgetService.cpp b/third_party/WebKit/Source/modules/budget/BudgetService.cpp
index afd12a2..fda4afeb 100644
--- a/third_party/WebKit/Source/modules/budget/BudgetService.cpp
+++ b/third_party/WebKit/Source/modules/budget/BudgetService.cpp
@@ -65,10 +65,7 @@
         scriptState, DOMException::create(SecurityError, errorMessage));
 
   mojom::blink::BudgetOperationType type = stringToOperationType(operation);
-  if (type == mojom::blink::BudgetOperationType::INVALID_OPERATION)
-    return ScriptPromise::rejectWithDOMException(
-        scriptState, DOMException::create(NotSupportedError,
-                                          "Invalid operation type specified"));
+  DCHECK_NE(type, mojom::blink::BudgetOperationType::INVALID_OPERATION);
 
   ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
   ScriptPromise promise = resolver->promise();
@@ -129,10 +126,7 @@
   DCHECK(m_service);
 
   mojom::blink::BudgetOperationType type = stringToOperationType(operation);
-  if (type == mojom::blink::BudgetOperationType::INVALID_OPERATION)
-    return ScriptPromise::rejectWithDOMException(
-        scriptState, DOMException::create(NotSupportedError,
-                                          "Invalid operation type specified"));
+  DCHECK_NE(type, mojom::blink::BudgetOperationType::INVALID_OPERATION);
 
   String errorMessage;
   if (!scriptState->getExecutionContext()->isSecureContext(errorMessage))
diff --git a/third_party/WebKit/Source/modules/csspaint/PaintWorkletTest.cpp b/third_party/WebKit/Source/modules/csspaint/PaintWorkletTest.cpp
index 56498780..4c8d400 100644
--- a/third_party/WebKit/Source/modules/csspaint/PaintWorkletTest.cpp
+++ b/third_party/WebKit/Source/modules/csspaint/PaintWorkletTest.cpp
@@ -22,7 +22,7 @@
   PaintWorkletTest() : m_page(DummyPageHolder::create()) {}
 
   PaintWorklet* paintWorklet() {
-    return WindowPaintWorklet::from(*m_page->frame().localDOMWindow())
+    return WindowPaintWorklet::from(*m_page->frame().domWindow())
         .paintWorklet();
   }
 
diff --git a/third_party/WebKit/Source/modules/device_orientation/DeviceMotionController.cpp b/third_party/WebKit/Source/modules/device_orientation/DeviceMotionController.cpp
index f204460..52d6e60 100644
--- a/third_party/WebKit/Source/modules/device_orientation/DeviceMotionController.cpp
+++ b/third_party/WebKit/Source/modules/device_orientation/DeviceMotionController.cpp
@@ -43,8 +43,7 @@
     return;
 
   if (document().frame()) {
-    String errorMessage;
-    if (document().isSecureContext(errorMessage)) {
+    if (document().isSecureContext()) {
       UseCounter::count(document().frame(),
                         UseCounter::DeviceMotionSecureOrigin);
     } else {
diff --git a/third_party/WebKit/Source/modules/device_orientation/DeviceOrientationAbsoluteController.cpp b/third_party/WebKit/Source/modules/device_orientation/DeviceOrientationAbsoluteController.cpp
index 4683ffa..7703574 100644
--- a/third_party/WebKit/Source/modules/device_orientation/DeviceOrientationAbsoluteController.cpp
+++ b/third_party/WebKit/Source/modules/device_orientation/DeviceOrientationAbsoluteController.cpp
@@ -42,8 +42,7 @@
     return;
 
   if (document().frame()) {
-    String errorMessage;
-    if (document().isSecureContext(errorMessage)) {
+    if (document().isSecureContext()) {
       UseCounter::count(document().frame(),
                         UseCounter::DeviceOrientationAbsoluteSecureOrigin);
     } else {
diff --git a/third_party/WebKit/Source/modules/device_orientation/DeviceOrientationController.cpp b/third_party/WebKit/Source/modules/device_orientation/DeviceOrientationController.cpp
index 7d39dab..0390ae3 100644
--- a/third_party/WebKit/Source/modules/device_orientation/DeviceOrientationController.cpp
+++ b/third_party/WebKit/Source/modules/device_orientation/DeviceOrientationController.cpp
@@ -52,8 +52,7 @@
     return;
 
   if (document().frame()) {
-    String errorMessage;
-    if (document().isSecureContext(errorMessage)) {
+    if (document().isSecureContext()) {
       UseCounter::count(document().frame(),
                         UseCounter::DeviceOrientationSecureOrigin);
     } else {
diff --git a/third_party/WebKit/Source/modules/encryptedmedia/NavigatorRequestMediaKeySystemAccess.cpp b/third_party/WebKit/Source/modules/encryptedmedia/NavigatorRequestMediaKeySystemAccess.cpp
index 7ba57ec..76c9f5d 100644
--- a/third_party/WebKit/Source/modules/encryptedmedia/NavigatorRequestMediaKeySystemAccess.cpp
+++ b/third_party/WebKit/Source/modules/encryptedmedia/NavigatorRequestMediaKeySystemAccess.cpp
@@ -355,8 +355,7 @@
   // sites, we simply keep track of sites that aren't secure and output a
   // deprecation message.
   ExecutionContext* executionContext = scriptState->getExecutionContext();
-  String errorMessage;
-  if (executionContext->isSecureContext(errorMessage)) {
+  if (executionContext->isSecureContext()) {
     UseCounter::count(executionContext, UseCounter::EncryptedMediaSecureOrigin);
   } else {
     Deprecation::countDeprecation(executionContext,
diff --git a/third_party/WebKit/Source/modules/gamepad/NavigatorGamepad.cpp b/third_party/WebKit/Source/modules/gamepad/NavigatorGamepad.cpp
index f99ab0b..546499b 100644
--- a/third_party/WebKit/Source/modules/gamepad/NavigatorGamepad.cpp
+++ b/third_party/WebKit/Source/modules/gamepad/NavigatorGamepad.cpp
@@ -174,7 +174,7 @@
           this,
           &NavigatorGamepad::dispatchOneEvent)) {
   if (frame)
-    frame->localDOMWindow()->registerEventListenerObserver(this);
+    frame->domWindow()->registerEventListenerObserver(this);
 }
 
 NavigatorGamepad::~NavigatorGamepad() {}
diff --git a/third_party/WebKit/Source/modules/notifications/Notification.cpp b/third_party/WebKit/Source/modules/notifications/Notification.cpp
index f2fa76b..ff8630b4 100644
--- a/third_party/WebKit/Source/modules/notifications/Notification.cpp
+++ b/third_party/WebKit/Source/modules/notifications/Notification.cpp
@@ -91,8 +91,7 @@
     return nullptr;
   }
 
-  String insecureOriginMessage;
-  if (context->isSecureContext(insecureOriginMessage)) {
+  if (context->isSecureContext()) {
     UseCounter::count(context, UseCounter::NotificationSecureOrigin);
     if (context->isDocument())
       UseCounter::countCrossOriginIframe(
diff --git a/third_party/WebKit/Source/modules/permissions/Permissions.cpp b/third_party/WebKit/Source/modules/permissions/Permissions.cpp
index 873b4452..0050013 100644
--- a/third_party/WebKit/Source/modules/permissions/Permissions.cpp
+++ b/third_party/WebKit/Source/modules/permissions/Permissions.cpp
@@ -156,7 +156,7 @@
   service->RequestPermission(
       std::move(descriptor),
       scriptState->getExecutionContext()->getSecurityOrigin(),
-      UserGestureIndicator::processingUserGesture(),
+      UserGestureIndicator::processingUserGestureThreadSafe(),
       convertToBaseCallback(WTF::bind(
           &Permissions::taskComplete, wrapPersistent(this),
           wrapPersistent(resolver), WTF::passed(std::move(descriptorCopy)))));
@@ -247,7 +247,7 @@
   service->RequestPermissions(
       std::move(internalPermissions),
       scriptState->getExecutionContext()->getSecurityOrigin(),
-      UserGestureIndicator::processingUserGesture(),
+      UserGestureIndicator::processingUserGestureThreadSafe(),
       convertToBaseCallback(
           WTF::bind(&Permissions::batchTaskComplete, wrapPersistent(this),
                     wrapPersistent(resolver),
diff --git a/third_party/WebKit/Source/modules/storage/StorageArea.cpp b/third_party/WebKit/Source/modules/storage/StorageArea.cpp
index 9e3bb551..3271d940 100644
--- a/third_party/WebKit/Source/modules/storage/StorageArea.cpp
+++ b/third_party/WebKit/Source/modules/storage/StorageArea.cpp
@@ -174,14 +174,14 @@
       if (!frame->isLocalFrame())
         continue;
       LocalFrame* localFrame = toLocalFrame(frame);
-      LocalDOMWindow* localWindow = localFrame->localDOMWindow();
+      LocalDOMWindow* localWindow = localFrame->domWindow();
       Storage* storage =
           DOMWindowStorage::from(*localWindow).optionalLocalStorage();
       if (storage &&
           localFrame->document()->getSecurityOrigin()->canAccess(
               securityOrigin) &&
           !isEventSource(storage, sourceAreaInstance))
-        localFrame->localDOMWindow()->enqueueWindowEvent(
+        localFrame->domWindow()->enqueueWindowEvent(
             StorageEvent::create(EventTypeNames::storage, key, oldValue,
                                  newValue, pageURL, storage));
     }
@@ -225,14 +225,14 @@
     if (!frame->isLocalFrame())
       continue;
     LocalFrame* localFrame = toLocalFrame(frame);
-    LocalDOMWindow* localWindow = localFrame->localDOMWindow();
+    LocalDOMWindow* localWindow = localFrame->domWindow();
     Storage* storage =
         DOMWindowStorage::from(*localWindow).optionalSessionStorage();
     if (storage &&
         localFrame->document()->getSecurityOrigin()->canAccess(
             securityOrigin) &&
         !isEventSource(storage, sourceAreaInstance))
-      localFrame->localDOMWindow()->enqueueWindowEvent(StorageEvent::create(
+      localFrame->domWindow()->enqueueWindowEvent(StorageEvent::create(
           EventTypeNames::storage, key, oldValue, newValue, pageURL, storage));
   }
   if (InspectorDOMStorageAgent* agent =
diff --git a/third_party/WebKit/Source/modules/vibration/NavigatorVibration.cpp b/third_party/WebKit/Source/modules/vibration/NavigatorVibration.cpp
index a932c52..95e5b353 100644
--- a/third_party/WebKit/Source/modules/vibration/NavigatorVibration.cpp
+++ b/third_party/WebKit/Source/modules/vibration/NavigatorVibration.cpp
@@ -82,11 +82,11 @@
   // runtime flag.
   if (!isFeatureEnabledInFrame(blink::kVibrateFeature, frame)) {
     if (RuntimeEnabledFeatures::featurePolicyEnabled()) {
-      frame->localDOMWindow()->printErrorMessage(
+      frame->domWindow()->printErrorMessage(
           "Navigator.vibrate() is not enabled in feature policy for this "
           "frame.");
     } else {
-      frame->localDOMWindow()->printErrorMessage(
+      frame->domWindow()->printErrorMessage(
           "A call of navigator.vibrate will be no-op inside cross-origin "
           "iframes: https://www.chromestatus.com/feature/5682658461876224.");
     }
diff --git a/third_party/WebKit/Source/modules/vr/NavigatorVR.cpp b/third_party/WebKit/Source/modules/vr/NavigatorVR.cpp
index 68a6c6b..1dfdcf8a 100644
--- a/third_party/WebKit/Source/modules/vr/NavigatorVR.cpp
+++ b/third_party/WebKit/Source/modules/vr/NavigatorVR.cpp
@@ -61,8 +61,7 @@
 
   UseCounter::count(*document, UseCounter::VRGetDisplays);
   ExecutionContext* executionContext = scriptState->getExecutionContext();
-  String errorMessage;
-  if (!executionContext->isSecureContext(errorMessage))
+  if (!executionContext->isSecureContext())
     UseCounter::count(*document, UseCounter::VRGetDisplaysInsecureOrigin);
 
   Platform::current()->recordRapporURL("VR.WebVR.GetDisplays", document->url());
@@ -97,7 +96,7 @@
 
 NavigatorVR::NavigatorVR(LocalFrame* frame)
     : DOMWindowProperty(frame), PageVisibilityObserver(frame->page()) {
-  frame->localDOMWindow()->registerEventListenerObserver(this);
+  frame->domWindow()->registerEventListenerObserver(this);
 }
 
 NavigatorVR::~NavigatorVR() {}
@@ -107,17 +106,19 @@
 }
 
 void NavigatorVR::enqueueVREvent(VRDisplayEvent* event) {
-  if (frame() && frame()->localDOMWindow()) {
-    frame()->localDOMWindow()->enqueueWindowEvent(event);
+  // TODO(dcheng): Why does this need to check both frame and domWindow?
+  if (frame() && frame()->domWindow()) {
+    frame()->domWindow()->enqueueWindowEvent(event);
   }
 }
 
 void NavigatorVR::dispatchVRGestureEvent(VRDisplayEvent* event) {
-  if (frame() && frame()->localDOMWindow()) {
+  // TODO(dcheng): Why does this need to check both frame and domWindow?
+  if (frame() && frame()->domWindow()) {
     UserGestureIndicator gestureIndicator(
         DocumentUserGestureToken::create(frame()->document()));
-    event->setTarget(frame()->localDOMWindow());
-    frame()->localDOMWindow()->dispatchEvent(event);
+    event->setTarget(frame()->domWindow());
+    frame()->domWindow()->dispatchEvent(event);
   }
 }
 
diff --git a/third_party/WebKit/Source/modules/vr/VRDisplay.cpp b/third_party/WebKit/Source/modules/vr/VRDisplay.cpp
index debe0fb..f4ed320c 100644
--- a/third_party/WebKit/Source/modules/vr/VRDisplay.cpp
+++ b/third_party/WebKit/Source/modules/vr/VRDisplay.cpp
@@ -283,8 +283,7 @@
                                         const HeapVector<VRLayer>& layers) {
   ExecutionContext* executionContext = scriptState->getExecutionContext();
   UseCounter::count(executionContext, UseCounter::VRRequestPresent);
-  String errorMessage;
-  if (!executionContext->isSecureContext(errorMessage)) {
+  if (!executionContext->isSecureContext()) {
     UseCounter::count(executionContext,
                       UseCounter::VRRequestPresentInsecureOrigin);
   }
diff --git a/third_party/WebKit/Source/platform/BUILD.gn b/third_party/WebKit/Source/platform/BUILD.gn
index d43ec77..0a49563d 100644
--- a/third_party/WebKit/Source/platform/BUILD.gn
+++ b/third_party/WebKit/Source/platform/BUILD.gn
@@ -1606,6 +1606,7 @@
     "testing/MessageLoopForMojo.h",
     "testing/PaintPrinters.cpp",
     "testing/PaintPrinters.h",
+    "testing/PaintPropertyTestHelpers.h",
     "testing/PictureMatchers.cpp",
     "testing/PictureMatchers.h",
     "testing/PlatformTestPrinters.cpp",
diff --git a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in
index 33b67cc..127f6dc 100644
--- a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in
+++ b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in
@@ -276,5 +276,5 @@
 LazyParseCSS status=experimental
 ParseHTMLOnMainThread status=test
 SendBeaconThrowForBlobWithNonSimpleType status=experimental
-PerformanceNavigationTiming2 status=test
+PerformanceNavigationTiming2 status=experimental
 BackgroundVideoTrackOptimization status=stable
diff --git a/third_party/WebKit/Source/platform/UserGestureIndicator.cpp b/third_party/WebKit/Source/platform/UserGestureIndicator.cpp
index 84433950..6311458 100644
--- a/third_party/WebKit/Source/platform/UserGestureIndicator.cpp
+++ b/third_party/WebKit/Source/platform/UserGestureIndicator.cpp
@@ -42,7 +42,7 @@
       m_timestamp(WTF::currentTime()),
       m_timeoutPolicy(Default),
       m_usageCallback(nullptr) {
-  if (status == NewGesture || !UserGestureIndicator::currentToken())
+  if (status == NewGesture || !UserGestureIndicator::currentTokenThreadSafe())
     m_consumableGestures++;
 }
 
@@ -151,18 +151,18 @@
 }
 
 bool UserGestureIndicator::processingUserGesture() {
-  if (auto* token = currentToken()) {
-    ASSERT(isMainThread());
+  if (auto* token = currentToken())
     return token->hasGestures();
-  }
-
   return false;
 }
 
+bool UserGestureIndicator::processingUserGestureThreadSafe() {
+  return isMainThread() && processingUserGesture();
+}
+
 // static
 bool UserGestureIndicator::consumeUserGesture() {
   if (auto* token = currentToken()) {
-    ASSERT(isMainThread());
     if (token->consumeGesture()) {
       token->userGestureUtilized();
       return true;
@@ -171,11 +171,17 @@
   return false;
 }
 
-// static
+bool UserGestureIndicator::consumeUserGestureThreadSafe() {
+  return isMainThread() && consumeUserGesture();
+}
+
 UserGestureToken* UserGestureIndicator::currentToken() {
-  if (!isMainThread() || !s_rootToken)
-    return nullptr;
+  DCHECK(isMainThread());
   return s_rootToken;
 }
 
+UserGestureToken* UserGestureIndicator::currentTokenThreadSafe() {
+  return isMainThread() ? currentToken() : nullptr;
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/platform/UserGestureIndicator.h b/third_party/WebKit/Source/platform/UserGestureIndicator.h
index 5cab2e0..4e4cebe2 100644
--- a/third_party/WebKit/Source/platform/UserGestureIndicator.h
+++ b/third_party/WebKit/Source/platform/UserGestureIndicator.h
@@ -94,11 +94,17 @@
   WTF_MAKE_NONCOPYABLE(UserGestureIndicator);
 
  public:
+  // Note: All *ThreadSafe methods are safe to call from any thread. Their
+  // non-suffixed counterparts *must* be called on the main thread. Consider
+  // always using the non-suffixed one unless the code really
+  // needs to be thread-safe
+
   // Returns whether a user gesture is currently in progress.
   // Does not invoke the UserGestureUtilizedCallback.  Consider calling
   // utilizeUserGesture instead if you know for sure that the return value
   // will have an effect.
   static bool processingUserGesture();
+  static bool processingUserGestureThreadSafe();
 
   // Indicates that a user gesture (if any) is being used, without preventing it
   // from being used again.  Returns whether a user gesture is currently in
@@ -111,8 +117,10 @@
   // operations like creating a new process.
   // Like utilizeUserGesture, may invoke/clear any UserGestureUtilizedCallback.
   static bool consumeUserGesture();
+  static bool consumeUserGestureThreadSafe();
 
   static UserGestureToken* currentToken();
+  static UserGestureToken* currentTokenThreadSafe();
 
   explicit UserGestureIndicator(PassRefPtr<UserGestureToken>);
   ~UserGestureIndicator();
diff --git a/third_party/WebKit/Source/platform/WebTaskRunner.h b/third_party/WebKit/Source/platform/WebTaskRunner.h
index b6cf972f..073e1ee 100644
--- a/third_party/WebKit/Source/platform/WebTaskRunner.h
+++ b/third_party/WebKit/Source/platform/WebTaskRunner.h
@@ -60,22 +60,6 @@
  public:
   virtual ~WebTaskRunner() {}
 
-  class BLINK_PLATFORM_EXPORT Task {
-   public:
-    virtual ~Task() {}
-    virtual void run() = 0;
-  };
-
-  // Schedule a task to be run on the the associated WebThread.
-  // Takes ownership of |Task|. Can be called from any thread.
-  virtual void postTask(const WebTraceLocation&, Task*) = 0;
-
-  // Schedule a task to be run after |delayMs| on the the associated WebThread.
-  // Takes ownership of |Task|. Can be called from any thread.
-  virtual void postDelayedTask(const WebTraceLocation&,
-                               Task*,
-                               double delayMs) = 0;
-
   // Schedule a task to be run after |delayMs| on the the associated WebThread.
   // Can be called from any thread.
   virtual void postDelayedTask(const WebTraceLocation&,
diff --git a/third_party/WebKit/Source/platform/graphics/CompositingReasons.cpp b/third_party/WebKit/Source/platform/graphics/CompositingReasons.cpp
index b053de8..fdc3d2a 100644
--- a/third_party/WebKit/Source/platform/graphics/CompositingReasons.cpp
+++ b/third_party/WebKit/Source/platform/graphics/CompositingReasons.cpp
@@ -127,6 +127,10 @@
      "Secondary layer, to contain the mask contents"},
     {CompositingReasonLayerForClippingMask, "layerForClippingMask",
      "Secondary layer, for clipping mask"},
+    {CompositingReasonLayerForAncestorClippingMask,
+     "layerForAncestorClippingMask",
+     "Secondary layer, applies a clipping mask due to a sibling in the "
+     "composited layer tree"},
     {CompositingReasonLayerForScrollingBlockSelection,
      "layerForScrollingBlockSelection",
      "Secondary layer, to house block selection gaps for composited scrolling "
diff --git a/third_party/WebKit/Source/platform/graphics/CompositingReasons.h b/third_party/WebKit/Source/platform/graphics/CompositingReasons.h
index e0d8667..aff8adc 100644
--- a/third_party/WebKit/Source/platform/graphics/CompositingReasons.h
+++ b/third_party/WebKit/Source/platform/graphics/CompositingReasons.h
@@ -84,16 +84,18 @@
 const uint64_t CompositingReasonLayerForBackground = UINT64_C(1) << 44;
 const uint64_t CompositingReasonLayerForMask = UINT64_C(1) << 45;
 const uint64_t CompositingReasonLayerForClippingMask = UINT64_C(1) << 46;
+const uint64_t CompositingReasonLayerForAncestorClippingMask = UINT64_C(1)
+                                                               << 47;
 const uint64_t CompositingReasonLayerForScrollingBlockSelection = UINT64_C(1)
-                                                                  << 47;
+                                                                  << 48;
 // Composited layer painted on top of all other layers as decoration
-const uint64_t CompositingReasonLayerForDecoration = UINT64_C(1) << 48;
+const uint64_t CompositingReasonLayerForDecoration = UINT64_C(1) << 49;
 
 // Composited elements with inline transforms trigger assumed overlap so that
 // we can update their transforms quickly.
-const uint64_t CompositingReasonInlineTransform = UINT64_C(1) << 49;
+const uint64_t CompositingReasonInlineTransform = UINT64_C(1) << 50;
 
-const uint64_t CompositingReasonCompositorProxy = UINT64_C(1) << 50;
+const uint64_t CompositingReasonCompositorProxy = UINT64_C(1) << 51;
 
 // Various combinations of compositing reasons are defined here also, for more
 // intutive and faster bitwise logic.
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp b/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp
index d2a9211..7816da4 100644
--- a/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp
+++ b/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp
@@ -738,6 +738,8 @@
       paintingPhasesJSON->pushString("GraphicsLayerPaintMask");
     if (m_paintingPhase & GraphicsLayerPaintChildClippingMask)
       paintingPhasesJSON->pushString("GraphicsLayerPaintChildClippingMask");
+    if (m_paintingPhase & GraphicsLayerPaintAncestorClippingMask)
+      paintingPhasesJSON->pushString("GraphicsLayerPaintAncestorClippingMask");
     if (m_paintingPhase & GraphicsLayerPaintOverflowContents)
       paintingPhasesJSON->pushString("GraphicsLayerPaintOverflowContents");
     if (m_paintingPhase & GraphicsLayerPaintCompositedScroll)
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsLayerClient.h b/third_party/WebKit/Source/platform/graphics/GraphicsLayerClient.h
index d5c81e5..c121f14 100644
--- a/third_party/WebKit/Source/platform/graphics/GraphicsLayerClient.h
+++ b/third_party/WebKit/Source/platform/graphics/GraphicsLayerClient.h
@@ -43,7 +43,8 @@
   GraphicsLayerPaintOverflowContents = (1 << 3),
   GraphicsLayerPaintCompositedScroll = (1 << 4),
   GraphicsLayerPaintChildClippingMask = (1 << 5),
-  GraphicsLayerPaintDecoration = (1 << 6),
+  GraphicsLayerPaintAncestorClippingMask = (1 << 6),
+  GraphicsLayerPaintDecoration = (1 << 7),
   GraphicsLayerPaintAllWithOverflowClip =
       (GraphicsLayerPaintBackground | GraphicsLayerPaintForeground |
        GraphicsLayerPaintMask |
diff --git a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositorTest.cpp b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositorTest.cpp
index 9d23fbb..65f83f6 100644
--- a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositorTest.cpp
+++ b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositorTest.cpp
@@ -19,6 +19,7 @@
 #include "platform/graphics/paint/EffectPaintPropertyNode.h"
 #include "platform/graphics/paint/PaintArtifact.h"
 #include "platform/graphics/paint/ScrollPaintPropertyNode.h"
+#include "platform/testing/PaintPropertyTestHelpers.h"
 #include "platform/testing/PictureMatchers.h"
 #include "platform/testing/TestPaintArtifact.h"
 #include "platform/testing/WebLayerTreeViewImplForTesting.h"
@@ -29,6 +30,7 @@
 namespace blink {
 namespace {
 
+using ::blink::testing::createOpacityOnlyEffect;
 using ::testing::Pointee;
 
 PaintChunkProperties defaultPaintChunkProperties() {
@@ -569,15 +571,12 @@
 }
 
 TEST_F(PaintArtifactCompositorTestWithPropertyTrees, EffectTreeConversion) {
-  RefPtr<EffectPaintPropertyNode> effect1 = EffectPaintPropertyNode::create(
-      EffectPaintPropertyNode::root(), TransformPaintPropertyNode::root(),
-      ClipPaintPropertyNode::root(), CompositorFilterOperations(), 0.5);
-  RefPtr<EffectPaintPropertyNode> effect2 = EffectPaintPropertyNode::create(
-      effect1, TransformPaintPropertyNode::root(),
-      ClipPaintPropertyNode::root(), CompositorFilterOperations(), 0.3);
-  RefPtr<EffectPaintPropertyNode> effect3 = EffectPaintPropertyNode::create(
-      EffectPaintPropertyNode::root(), TransformPaintPropertyNode::root(),
-      ClipPaintPropertyNode::root(), CompositorFilterOperations(), 0.2);
+  RefPtr<EffectPaintPropertyNode> effect1 =
+      createOpacityOnlyEffect(EffectPaintPropertyNode::root(), 0.5);
+  RefPtr<EffectPaintPropertyNode> effect2 =
+      createOpacityOnlyEffect(effect1, 0.3);
+  RefPtr<EffectPaintPropertyNode> effect3 =
+      createOpacityOnlyEffect(EffectPaintPropertyNode::root(), 0.2);
 
   TestPaintArtifact artifact;
   artifact
@@ -661,9 +660,8 @@
 }
 
 TEST_F(PaintArtifactCompositorTestWithPropertyTrees, NestedScrollNodes) {
-  RefPtr<EffectPaintPropertyNode> effect = EffectPaintPropertyNode::create(
-      EffectPaintPropertyNode::root(), TransformPaintPropertyNode::root(),
-      ClipPaintPropertyNode::root(), CompositorFilterOperations(), 0.5);
+  RefPtr<EffectPaintPropertyNode> effect =
+      createOpacityOnlyEffect(EffectPaintPropertyNode::root(), 0.5);
 
   RefPtr<TransformPaintPropertyNode> scrollTranslationA =
       TransformPaintPropertyNode::create(
diff --git a/third_party/WebKit/Source/platform/graphics/paint/GeometryMapperTest.cpp b/third_party/WebKit/Source/platform/graphics/paint/GeometryMapperTest.cpp
index 3f7d0e5..e9533d8 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/GeometryMapperTest.cpp
+++ b/third_party/WebKit/Source/platform/graphics/paint/GeometryMapperTest.cpp
@@ -10,22 +10,19 @@
 #include "platform/graphics/paint/EffectPaintPropertyNode.h"
 #include "platform/graphics/paint/ScrollPaintPropertyNode.h"
 #include "platform/graphics/paint/TransformPaintPropertyNode.h"
+#include "platform/testing/PaintPropertyTestHelpers.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace blink {
 
 class GeometryMapperTest : public ::testing::Test {
  public:
-  RefPtr<TransformPaintPropertyNode> rootTransformNode;
-  RefPtr<ClipPaintPropertyNode> rootClipNode;
-  RefPtr<EffectPaintPropertyNode> rootEffectNode;
-  RefPtr<ScrollPaintPropertyNode> rootScrollNode;
-
   std::unique_ptr<GeometryMapper> geometryMapper;
 
   PropertyTreeState rootPropertyTreeState() {
-    PropertyTreeState state(rootTransformNode.get(), rootClipNode.get(),
-                            rootEffectNode.get(), rootScrollNode.get());
+    PropertyTreeState state(
+        TransformPaintPropertyNode::root(), ClipPaintPropertyNode::root(),
+        EffectPaintPropertyNode::root(), ScrollPaintPropertyNode::root());
     return state;
   }
 
@@ -42,16 +39,6 @@
 
  private:
   void SetUp() override {
-    rootTransformNode = TransformPaintPropertyNode::create(
-        nullptr, TransformationMatrix(), FloatPoint3D());
-    rootClipNode = ClipPaintPropertyNode::create(
-        nullptr, rootTransformNode,
-        FloatRoundedRect(LayoutRect::infiniteIntRect()));
-    rootEffectNode = EffectPaintPropertyNode::create(
-        nullptr, rootTransformNode, rootClipNode, CompositorFilterOperations(),
-        1.0);
-    rootScrollNode = ScrollPaintPropertyNode::create(
-        nullptr, rootTransformNode, IntSize(), IntSize(), false, false, 0);
     geometryMapper = WTF::makeUnique<GeometryMapper>();
   }
 
@@ -116,9 +103,10 @@
 TEST_F(GeometryMapperTest, Root) {
   FloatRect input(0, 0, 100, 100);
 
-  CHECK_MAPPINGS(input, input, input, rootTransformNode->matrix(),
-                 rootClipNode->clipRect().rect(), rootPropertyTreeState(),
-                 rootPropertyTreeState());
+  CHECK_MAPPINGS(input, input, input,
+                 TransformPaintPropertyNode::root()->matrix(),
+                 ClipPaintPropertyNode::root()->clipRect().rect(),
+                 rootPropertyTreeState(), rootPropertyTreeState());
 }
 
 TEST_F(GeometryMapperTest, IdentityTransform) {
@@ -132,7 +120,7 @@
   FloatRect input(0, 0, 100, 100);
 
   CHECK_MAPPINGS(input, input, input, transform->matrix(),
-                 rootClipNode->clipRect().rect(), localState,
+                 ClipPaintPropertyNode::root()->clipRect().rect(), localState,
                  rootPropertyTreeState());
 }
 
@@ -149,7 +137,7 @@
   FloatRect output = transformMatrix.mapRect(input);
 
   CHECK_MAPPINGS(input, output, output, transform->matrix(),
-                 rootClipNode->clipRect().rect(), localState,
+                 ClipPaintPropertyNode::root()->clipRect().rect(), localState,
                  rootPropertyTreeState());
 
   bool success = false;
@@ -174,7 +162,7 @@
   FloatRect output = transformMatrix.mapRect(input);
 
   CHECK_MAPPINGS(input, output, output, transformMatrix,
-                 rootClipNode->clipRect().rect(), localState,
+                 ClipPaintPropertyNode::root()->clipRect().rect(), localState,
                  rootPropertyTreeState());
 }
 
@@ -194,7 +182,7 @@
   FloatRect output = transformMatrix.mapRect(input);
 
   CHECK_MAPPINGS(input, output, output, transformMatrix,
-                 rootClipNode->clipRect().rect(), localState,
+                 ClipPaintPropertyNode::root()->clipRect().rect(), localState,
                  rootPropertyTreeState());
 }
 
@@ -218,8 +206,9 @@
   TransformationMatrix final = rotateTransform * scaleTransform;
   FloatRect output = final.mapRect(input);
 
-  CHECK_MAPPINGS(input, output, output, final, rootClipNode->clipRect().rect(),
-                 localState, rootPropertyTreeState());
+  CHECK_MAPPINGS(input, output, output, final,
+                 ClipPaintPropertyNode::root()->clipRect().rect(), localState,
+                 rootPropertyTreeState());
 
   // Check the cached matrix for the intermediate transform.
   EXPECT_EQ(rotateTransform,
@@ -249,8 +238,9 @@
   TransformationMatrix final = scaleTransform * translateTransform;
   FloatRect output = final.mapRect(input);
 
-  CHECK_MAPPINGS(input, output, output, final, rootClipNode->clipRect().rect(),
-                 localState, rootPropertyTreeState());
+  CHECK_MAPPINGS(input, output, output, final,
+                 ClipPaintPropertyNode::root()->clipRect().rect(), localState,
+                 rootPropertyTreeState());
 
   // Check the cached matrix for the intermediate transform.
   EXPECT_EQ(scaleTransform,
@@ -281,13 +271,14 @@
   FloatRect output = scaleTransform.mapRect(input);
 
   CHECK_MAPPINGS(input, output, output, scaleTransform,
-                 rootClipNode->clipRect().rect(), localState,
+                 ClipPaintPropertyNode::root()->clipRect().rect(), localState,
                  intermediateState);
 }
 
 TEST_F(GeometryMapperTest, SimpleClip) {
   RefPtr<ClipPaintPropertyNode> clip = ClipPaintPropertyNode::create(
-      rootClipNode, rootTransformNode, FloatRoundedRect(10, 10, 50, 50));
+      ClipPaintPropertyNode::root(), TransformPaintPropertyNode::root(),
+      FloatRoundedRect(10, 10, 50, 50));
 
   PropertyTreeState localState = rootPropertyTreeState();
   localState.setClip(clip.get());
@@ -295,13 +286,14 @@
   FloatRect input(0, 0, 100, 100);
   FloatRect output(10, 10, 50, 50);
 
-  CHECK_MAPPINGS(
-      input,                        // Input
-      output,                       // Visual rect
-      input,                        // Transformed rect (not clipped).
-      rootTransformNode->matrix(),  // Transform matrix to ancestor space
-      clip->clipRect().rect(),      // Clip rect in ancestor space
-      localState, rootPropertyTreeState());
+  CHECK_MAPPINGS(input,   // Input
+                 output,  // Visual rect
+                 input,   // Transformed rect (not clipped).
+                 TransformPaintPropertyNode::root()
+                     ->matrix(),           // Transform matrix to ancestor space
+                 clip->clipRect().rect(),  // Clip rect in ancestor space
+                 localState,
+                 rootPropertyTreeState());
 }
 
 TEST_F(GeometryMapperTest, ClipBeforeTransform) {
@@ -312,7 +304,8 @@
                                          rotateTransform, FloatPoint3D());
 
   RefPtr<ClipPaintPropertyNode> clip = ClipPaintPropertyNode::create(
-      rootClipNode, transform.get(), FloatRoundedRect(10, 10, 50, 50));
+      ClipPaintPropertyNode::root(), transform.get(),
+      FloatRoundedRect(10, 10, 50, 50));
 
   PropertyTreeState localState = rootPropertyTreeState();
   localState.setClip(clip.get());
@@ -341,9 +334,9 @@
       TransformPaintPropertyNode::create(rootPropertyTreeState().transform(),
                                          rotateTransform, FloatPoint3D());
 
-  RefPtr<ClipPaintPropertyNode> clip =
-      ClipPaintPropertyNode::create(rootClipNode, rootTransformNode.get(),
-                                    FloatRoundedRect(10, 10, 200, 200));
+  RefPtr<ClipPaintPropertyNode> clip = ClipPaintPropertyNode::create(
+      ClipPaintPropertyNode::root(), TransformPaintPropertyNode::root(),
+      FloatRoundedRect(10, 10, 200, 200));
 
   PropertyTreeState localState = rootPropertyTreeState();
   localState.setClip(clip.get());
@@ -364,9 +357,9 @@
 }
 
 TEST_F(GeometryMapperTest, TwoClipsWithTransformBetween) {
-  RefPtr<ClipPaintPropertyNode> clip1 =
-      ClipPaintPropertyNode::create(rootClipNode, rootTransformNode.get(),
-                                    FloatRoundedRect(10, 10, 200, 200));
+  RefPtr<ClipPaintPropertyNode> clip1 = ClipPaintPropertyNode::create(
+      ClipPaintPropertyNode::root(), TransformPaintPropertyNode::root(),
+      FloatRoundedRect(10, 10, 200, 200));
 
   TransformationMatrix rotateTransform;
   rotateTransform.rotate(45);
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintChunkerTest.cpp b/third_party/WebKit/Source/platform/graphics/paint/PaintChunkerTest.cpp
index 3704015..d1fd8e48 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/PaintChunkerTest.cpp
+++ b/third_party/WebKit/Source/platform/graphics/paint/PaintChunkerTest.cpp
@@ -5,24 +5,18 @@
 #include "platform/graphics/paint/PaintChunker.h"
 
 #include "platform/RuntimeEnabledFeatures.h"
+#include "platform/testing/PaintPropertyTestHelpers.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-using testing::ElementsAre;
+using ::blink::testing::createOpacityOnlyEffect;
+using ::blink::testing::defaultPaintChunkProperties;
+using ::testing::ElementsAre;
 
 namespace blink {
 namespace {
 
-PaintChunkProperties rootPaintChunkProperties() {
-  PaintChunkProperties rootProperties;
-  rootProperties.transform = TransformPaintPropertyNode::root();
-  rootProperties.clip = ClipPaintPropertyNode::root();
-  rootProperties.effect = EffectPaintPropertyNode::root();
-  rootProperties.scroll = ScrollPaintPropertyNode::root();
-  return rootProperties;
-}
-
-class PaintChunkerTest : public testing::Test {
+class PaintChunkerTest : public ::testing::Test {
  protected:
   void SetUp() override {
     RuntimeEnabledFeatures::setSlimmingPaintV2Enabled(true);
@@ -73,34 +67,34 @@
 TEST_F(PaintChunkerTest, SingleNonEmptyRange) {
   PaintChunker chunker;
   chunker.updateCurrentPaintChunkProperties(nullptr,
-                                            rootPaintChunkProperties());
+                                            defaultPaintChunkProperties());
   chunker.incrementDisplayItemIndex(NormalTestDisplayItem(m_client));
   chunker.incrementDisplayItemIndex(NormalTestDisplayItem(m_client));
   Vector<PaintChunk> chunks = chunker.releasePaintChunks();
 
   EXPECT_THAT(chunks, ElementsAre(PaintChunk(0, 2, nullptr,
-                                             rootPaintChunkProperties())));
+                                             defaultPaintChunkProperties())));
 }
 
 TEST_F(PaintChunkerTest, SamePropertiesTwiceCombineIntoOneChunk) {
   PaintChunker chunker;
   chunker.updateCurrentPaintChunkProperties(nullptr,
-                                            rootPaintChunkProperties());
+                                            defaultPaintChunkProperties());
   chunker.incrementDisplayItemIndex(NormalTestDisplayItem(m_client));
   chunker.incrementDisplayItemIndex(NormalTestDisplayItem(m_client));
   chunker.updateCurrentPaintChunkProperties(nullptr,
-                                            rootPaintChunkProperties());
+                                            defaultPaintChunkProperties());
   chunker.incrementDisplayItemIndex(NormalTestDisplayItem(m_client));
   Vector<PaintChunk> chunks = chunker.releasePaintChunks();
 
   EXPECT_THAT(chunks, ElementsAre(PaintChunk(0, 3, nullptr,
-                                             rootPaintChunkProperties())));
+                                             defaultPaintChunkProperties())));
 }
 
 TEST_F(PaintChunkerTest, CanRewindDisplayItemIndex) {
   PaintChunker chunker;
   chunker.updateCurrentPaintChunkProperties(nullptr,
-                                            rootPaintChunkProperties());
+                                            defaultPaintChunkProperties());
   chunker.incrementDisplayItemIndex(NormalTestDisplayItem(m_client));
   chunker.incrementDisplayItemIndex(NormalTestDisplayItem(m_client));
   chunker.decrementDisplayItemIndex();
@@ -108,24 +102,24 @@
   Vector<PaintChunk> chunks = chunker.releasePaintChunks();
 
   EXPECT_THAT(chunks, ElementsAre(PaintChunk(0, 2, nullptr,
-                                             rootPaintChunkProperties())));
+                                             defaultPaintChunkProperties())));
 }
 
 TEST_F(PaintChunkerTest, BuildMultipleChunksWithSinglePropertyChanging) {
   PaintChunker chunker;
   chunker.updateCurrentPaintChunkProperties(nullptr,
-                                            rootPaintChunkProperties());
+                                            defaultPaintChunkProperties());
   chunker.incrementDisplayItemIndex(NormalTestDisplayItem(m_client));
   chunker.incrementDisplayItemIndex(NormalTestDisplayItem(m_client));
 
-  PaintChunkProperties simpleTransform = rootPaintChunkProperties();
+  PaintChunkProperties simpleTransform = defaultPaintChunkProperties();
   simpleTransform.transform = TransformPaintPropertyNode::create(
       nullptr, TransformationMatrix(0, 1, 2, 3, 4, 5), FloatPoint3D(9, 8, 7));
 
   chunker.updateCurrentPaintChunkProperties(nullptr, simpleTransform);
   chunker.incrementDisplayItemIndex(NormalTestDisplayItem(m_client));
 
-  PaintChunkProperties anotherTransform = rootPaintChunkProperties();
+  PaintChunkProperties anotherTransform = defaultPaintChunkProperties();
   anotherTransform.transform = TransformPaintPropertyNode::create(
       nullptr, TransformationMatrix(0, 1, 2, 3, 4, 5), FloatPoint3D(9, 8, 7));
   chunker.updateCurrentPaintChunkProperties(nullptr, anotherTransform);
@@ -133,45 +127,42 @@
 
   Vector<PaintChunk> chunks = chunker.releasePaintChunks();
 
-  EXPECT_THAT(chunks,
-              ElementsAre(PaintChunk(0, 2, nullptr, rootPaintChunkProperties()),
-                          PaintChunk(2, 3, nullptr, simpleTransform),
-                          PaintChunk(3, 4, nullptr, anotherTransform)));
+  EXPECT_THAT(chunks, ElementsAre(PaintChunk(0, 2, nullptr,
+                                             defaultPaintChunkProperties()),
+                                  PaintChunk(2, 3, nullptr, simpleTransform),
+                                  PaintChunk(3, 4, nullptr, anotherTransform)));
 }
 
 TEST_F(PaintChunkerTest, BuildMultipleChunksWithDifferentPropertyChanges) {
   PaintChunker chunker;
   chunker.updateCurrentPaintChunkProperties(nullptr,
-                                            rootPaintChunkProperties());
+                                            defaultPaintChunkProperties());
   chunker.incrementDisplayItemIndex(NormalTestDisplayItem(m_client));
 
-  PaintChunkProperties simpleTransform = rootPaintChunkProperties();
+  PaintChunkProperties simpleTransform = defaultPaintChunkProperties();
   simpleTransform.transform = TransformPaintPropertyNode::create(
       nullptr, TransformationMatrix(0, 0, 0, 0, 0, 0), FloatPoint3D(9, 8, 7));
   chunker.updateCurrentPaintChunkProperties(nullptr, simpleTransform);
   chunker.incrementDisplayItemIndex(NormalTestDisplayItem(m_client));
   chunker.incrementDisplayItemIndex(NormalTestDisplayItem(m_client));
 
-  PaintChunkProperties simpleTransformAndEffect = rootPaintChunkProperties();
+  PaintChunkProperties simpleTransformAndEffect = defaultPaintChunkProperties();
   simpleTransformAndEffect.transform = simpleTransform.transform;
-  simpleTransformAndEffect.effect = EffectPaintPropertyNode::create(
-      EffectPaintPropertyNode::root(), TransformPaintPropertyNode::root(),
-      ClipPaintPropertyNode::root(), CompositorFilterOperations(), 0.5f);
+  simpleTransformAndEffect.effect =
+      createOpacityOnlyEffect(EffectPaintPropertyNode::root(), 0.5f);
   chunker.updateCurrentPaintChunkProperties(nullptr, simpleTransformAndEffect);
   chunker.incrementDisplayItemIndex(NormalTestDisplayItem(m_client));
   chunker.incrementDisplayItemIndex(NormalTestDisplayItem(m_client));
 
   PaintChunkProperties simpleTransformAndEffectWithUpdatedTransform =
-      rootPaintChunkProperties();
+      defaultPaintChunkProperties();
   simpleTransformAndEffectWithUpdatedTransform.transform =
       TransformPaintPropertyNode::create(nullptr,
                                          TransformationMatrix(1, 1, 0, 0, 0, 0),
                                          FloatPoint3D(9, 8, 7));
   simpleTransformAndEffectWithUpdatedTransform.effect =
-      EffectPaintPropertyNode::create(
-          EffectPaintPropertyNode::root(), TransformPaintPropertyNode::root(),
-          ClipPaintPropertyNode::root(), CompositorFilterOperations(),
-          simpleTransformAndEffect.effect->opacity());
+      createOpacityOnlyEffect(EffectPaintPropertyNode::root(),
+                              simpleTransformAndEffect.effect->opacity());
   chunker.updateCurrentPaintChunkProperties(
       nullptr, simpleTransformAndEffectWithUpdatedTransform);
   chunker.incrementDisplayItemIndex(NormalTestDisplayItem(m_client));
@@ -187,7 +178,7 @@
 
   EXPECT_THAT(
       chunks,
-      ElementsAre(PaintChunk(0, 1, nullptr, rootPaintChunkProperties()),
+      ElementsAre(PaintChunk(0, 1, nullptr, defaultPaintChunkProperties()),
                   PaintChunk(1, 3, nullptr, simpleTransform),
                   PaintChunk(3, 5, nullptr, simpleTransformAndEffect),
                   PaintChunk(5, 7, nullptr,
@@ -202,10 +193,10 @@
   // </root xform>
   PaintChunker chunker;
   chunker.updateCurrentPaintChunkProperties(nullptr,
-                                            rootPaintChunkProperties());
+                                            defaultPaintChunkProperties());
   chunker.incrementDisplayItemIndex(NormalTestDisplayItem(m_client));
 
-  PaintChunkProperties simpleTransform = rootPaintChunkProperties();
+  PaintChunkProperties simpleTransform = defaultPaintChunkProperties();
   simpleTransform.transform = TransformPaintPropertyNode::create(
       nullptr, TransformationMatrix(0, 1, 2, 3, 4, 5), FloatPoint3D(9, 8, 7));
   chunker.updateCurrentPaintChunkProperties(nullptr, simpleTransform);
@@ -213,31 +204,31 @@
   chunker.incrementDisplayItemIndex(NormalTestDisplayItem(m_client));
 
   chunker.updateCurrentPaintChunkProperties(nullptr,
-                                            rootPaintChunkProperties());
+                                            defaultPaintChunkProperties());
   chunker.incrementDisplayItemIndex(NormalTestDisplayItem(m_client));
 
   Vector<PaintChunk> chunks = chunker.releasePaintChunks();
 
   EXPECT_THAT(
       chunks,
-      ElementsAre(PaintChunk(0, 1, nullptr, rootPaintChunkProperties()),
+      ElementsAre(PaintChunk(0, 1, nullptr, defaultPaintChunkProperties()),
                   PaintChunk(1, 3, nullptr, simpleTransform),
-                  PaintChunk(3, 4, nullptr, rootPaintChunkProperties())));
+                  PaintChunk(3, 4, nullptr, defaultPaintChunkProperties())));
 }
 
 TEST_F(PaintChunkerTest, ChangingPropertiesWithoutItems) {
   // Test that properties can change without display items being generated.
   PaintChunker chunker;
   chunker.updateCurrentPaintChunkProperties(nullptr,
-                                            rootPaintChunkProperties());
+                                            defaultPaintChunkProperties());
   chunker.incrementDisplayItemIndex(NormalTestDisplayItem(m_client));
 
-  PaintChunkProperties firstTransform = rootPaintChunkProperties();
+  PaintChunkProperties firstTransform = defaultPaintChunkProperties();
   firstTransform.transform = TransformPaintPropertyNode::create(
       nullptr, TransformationMatrix(0, 1, 2, 3, 4, 5), FloatPoint3D(9, 8, 7));
   chunker.updateCurrentPaintChunkProperties(nullptr, firstTransform);
 
-  PaintChunkProperties secondTransform = rootPaintChunkProperties();
+  PaintChunkProperties secondTransform = defaultPaintChunkProperties();
   secondTransform.transform = TransformPaintPropertyNode::create(
       nullptr, TransformationMatrix(9, 8, 7, 6, 5, 4), FloatPoint3D(3, 2, 1));
   chunker.updateCurrentPaintChunkProperties(nullptr, secondTransform);
@@ -245,9 +236,9 @@
   chunker.incrementDisplayItemIndex(NormalTestDisplayItem(m_client));
   Vector<PaintChunk> chunks = chunker.releasePaintChunks();
 
-  EXPECT_THAT(chunks,
-              ElementsAre(PaintChunk(0, 1, nullptr, rootPaintChunkProperties()),
-                          PaintChunk(1, 2, nullptr, secondTransform)));
+  EXPECT_THAT(chunks, ElementsAre(PaintChunk(0, 1, nullptr,
+                                             defaultPaintChunkProperties()),
+                                  PaintChunk(1, 2, nullptr, secondTransform)));
 }
 
 TEST_F(PaintChunkerTest, CreatesSeparateChunksWhenRequested) {
@@ -262,7 +253,7 @@
   TestDisplayItemRequiringSeparateChunk i6(m_client);
 
   chunker.updateCurrentPaintChunkProperties(nullptr,
-                                            rootPaintChunkProperties());
+                                            defaultPaintChunkProperties());
   chunker.incrementDisplayItemIndex(NormalTestDisplayItem(m_client));
   chunker.incrementDisplayItemIndex(i1);
   chunker.incrementDisplayItemIndex(i2);
@@ -282,13 +273,14 @@
   DisplayItem::Id id3 = i3.getId();
   DisplayItem::Id id6 = i6.getId();
   Vector<PaintChunk> chunks = chunker.releasePaintChunks();
-  EXPECT_THAT(chunks,
-              ElementsAre(PaintChunk(0, 1, nullptr, rootPaintChunkProperties()),
-                          PaintChunk(1, 2, &id1, rootPaintChunkProperties()),
-                          PaintChunk(2, 3, &id2, rootPaintChunkProperties()),
-                          PaintChunk(3, 4, &id3, rootPaintChunkProperties()),
-                          PaintChunk(4, 6, nullptr, rootPaintChunkProperties()),
-                          PaintChunk(6, 7, &id6, rootPaintChunkProperties())));
+  EXPECT_THAT(
+      chunks,
+      ElementsAre(PaintChunk(0, 1, nullptr, defaultPaintChunkProperties()),
+                  PaintChunk(1, 2, &id1, defaultPaintChunkProperties()),
+                  PaintChunk(2, 3, &id2, defaultPaintChunkProperties()),
+                  PaintChunk(3, 4, &id3, defaultPaintChunkProperties()),
+                  PaintChunk(4, 6, nullptr, defaultPaintChunkProperties()),
+                  PaintChunk(6, 7, &id6, defaultPaintChunkProperties())));
 }
 
 TEST_F(PaintChunkerTest, ChunkIds) {
@@ -299,11 +291,11 @@
   DisplayItem::Id id2 = i2.getId();
 
   chunker.updateCurrentPaintChunkProperties(nullptr,
-                                            rootPaintChunkProperties());
+                                            defaultPaintChunkProperties());
   chunker.incrementDisplayItemIndex(NormalTestDisplayItem(m_client));
   chunker.incrementDisplayItemIndex(NormalTestDisplayItem(m_client));
 
-  PaintChunkProperties simpleTransform = rootPaintChunkProperties();
+  PaintChunkProperties simpleTransform = defaultPaintChunkProperties();
   simpleTransform.transform = TransformPaintPropertyNode::create(
       nullptr, TransformationMatrix(0, 1, 2, 3, 4, 5), FloatPoint3D(9, 8, 7));
   chunker.updateCurrentPaintChunkProperties(&id1, simpleTransform);
@@ -314,17 +306,17 @@
   chunker.incrementDisplayItemIndex(NormalTestDisplayItem(m_client));
 
   chunker.updateCurrentPaintChunkProperties(nullptr,
-                                            rootPaintChunkProperties());
+                                            defaultPaintChunkProperties());
   chunker.incrementDisplayItemIndex(NormalTestDisplayItem(m_client));
 
   Vector<PaintChunk> chunks = chunker.releasePaintChunks();
   EXPECT_THAT(
       chunks,
-      ElementsAre(PaintChunk(0, 2, nullptr, rootPaintChunkProperties()),
+      ElementsAre(PaintChunk(0, 2, nullptr, defaultPaintChunkProperties()),
                   PaintChunk(2, 4, &id1, simpleTransform),
                   PaintChunk(4, 5, &id2, simpleTransform),
                   PaintChunk(5, 6, nullptr, simpleTransform),
-                  PaintChunk(6, 7, nullptr, rootPaintChunkProperties())));
+                  PaintChunk(6, 7, nullptr, defaultPaintChunkProperties())));
 }
 
 TEST_F(PaintChunkerTest, ChunkIdsSkippingCache) {
@@ -336,11 +328,11 @@
   i2.setSkippedCache();
 
   chunker.updateCurrentPaintChunkProperties(nullptr,
-                                            rootPaintChunkProperties());
+                                            defaultPaintChunkProperties());
   chunker.incrementDisplayItemIndex(NormalTestDisplayItem(m_client));
   chunker.incrementDisplayItemIndex(NormalTestDisplayItem(m_client));
 
-  PaintChunkProperties simpleTransform = rootPaintChunkProperties();
+  PaintChunkProperties simpleTransform = defaultPaintChunkProperties();
   simpleTransform.transform = TransformPaintPropertyNode::create(
       nullptr, TransformationMatrix(0, 1, 2, 3, 4, 5), FloatPoint3D(9, 8, 7));
   chunker.updateCurrentPaintChunkProperties(&id1, simpleTransform);
@@ -351,17 +343,17 @@
   chunker.incrementDisplayItemIndex(NormalTestDisplayItem(m_client));
 
   chunker.updateCurrentPaintChunkProperties(nullptr,
-                                            rootPaintChunkProperties());
+                                            defaultPaintChunkProperties());
   chunker.incrementDisplayItemIndex(NormalTestDisplayItem(m_client));
 
   Vector<PaintChunk> chunks = chunker.releasePaintChunks();
   EXPECT_THAT(
       chunks,
-      ElementsAre(PaintChunk(0, 2, nullptr, rootPaintChunkProperties()),
+      ElementsAre(PaintChunk(0, 2, nullptr, defaultPaintChunkProperties()),
                   PaintChunk(2, 4, nullptr, simpleTransform),
                   PaintChunk(4, 5, nullptr, simpleTransform),
                   PaintChunk(5, 6, nullptr, simpleTransform),
-                  PaintChunk(6, 7, nullptr, rootPaintChunkProperties())));
+                  PaintChunk(6, 7, nullptr, defaultPaintChunkProperties())));
 }
 
 }  // namespace
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintControllerTest.cpp b/third_party/WebKit/Source/platform/graphics/paint/PaintControllerTest.cpp
index 870d850..90b33c04 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/PaintControllerTest.cpp
+++ b/third_party/WebKit/Source/platform/graphics/paint/PaintControllerTest.cpp
@@ -14,15 +14,18 @@
 #include "platform/graphics/paint/DrawingRecorder.h"
 #include "platform/graphics/paint/SubsequenceRecorder.h"
 #include "platform/testing/FakeDisplayItemClient.h"
+#include "platform/testing/PaintPropertyTestHelpers.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include <memory>
 
+using blink::testing::createOpacityOnlyEffect;
+using blink::testing::defaultPaintChunkProperties;
 using testing::UnorderedElementsAre;
 
 namespace blink {
 
-class PaintControllerTestBase : public testing::Test {
+class PaintControllerTestBase : public ::testing::Test {
  public:
   PaintControllerTestBase() : m_paintController(PaintController::create()) {}
 
@@ -54,15 +57,6 @@
   RuntimeEnabledFeatures::Backup m_featuresBackup;
 };
 
-PaintChunkProperties rootPaintChunkProperties() {
-  PaintChunkProperties rootProperties;
-  rootProperties.transform = TransformPaintPropertyNode::root();
-  rootProperties.clip = ClipPaintPropertyNode::root();
-  rootProperties.effect = EffectPaintPropertyNode::root();
-  rootProperties.scroll = ScrollPaintPropertyNode::root();
-  return rootProperties;
-}
-
 const DisplayItem::Type foregroundDrawingType =
     static_cast<DisplayItem::Type>(DisplayItem::kDrawingPaintPhaseFirst + 4);
 const DisplayItem::Type backgroundDrawingType =
@@ -136,7 +130,7 @@
 // enabled and disabled.
 class PaintControllerTest
     : public PaintControllerTestBase,
-      public testing::WithParamInterface<TestConfigurations> {
+      public ::testing::WithParamInterface<TestConfigurations> {
  public:
   PaintControllerTest()
       : m_rootPaintPropertyClient("root"),
@@ -177,7 +171,7 @@
   FakeDisplayItemClient client("client", LayoutRect(100, 100, 200, 200));
   if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
     getPaintController().updateCurrentPaintChunkProperties(
-        &m_rootPaintChunkId, rootPaintChunkProperties());
+        &m_rootPaintChunkId, defaultPaintChunkProperties());
   }
 
   drawClippedRect(context, client, clipType, backgroundDrawingType,
@@ -203,7 +197,7 @@
   GraphicsContext context(getPaintController());
   if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
     getPaintController().updateCurrentPaintChunkProperties(
-        &m_rootPaintChunkId, rootPaintChunkProperties());
+        &m_rootPaintChunkId, defaultPaintChunkProperties());
   }
 
   drawRect(context, first, backgroundDrawingType,
@@ -228,7 +222,7 @@
                 UnorderedElementsAre(FloatRect(LayoutRect::infiniteIntRect())));
 
     getPaintController().updateCurrentPaintChunkProperties(
-        &m_rootPaintChunkId, rootPaintChunkProperties());
+        &m_rootPaintChunkId, defaultPaintChunkProperties());
   }
 
   drawRect(context, first, backgroundDrawingType,
@@ -265,7 +259,7 @@
   GraphicsContext context(getPaintController());
   if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
     getPaintController().updateCurrentPaintChunkProperties(
-        &m_rootPaintChunkId, rootPaintChunkProperties());
+        &m_rootPaintChunkId, defaultPaintChunkProperties());
   }
 
   drawRect(context, first, backgroundDrawingType,
@@ -292,7 +286,7 @@
 
   if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
     getPaintController().updateCurrentPaintChunkProperties(
-        &m_rootPaintChunkId, rootPaintChunkProperties());
+        &m_rootPaintChunkId, defaultPaintChunkProperties());
   }
   drawRect(context, second, backgroundDrawingType,
            FloatRect(100, 100, 50, 200));
@@ -339,7 +333,7 @@
   GraphicsContext context(getPaintController());
   if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
     getPaintController().updateCurrentPaintChunkProperties(
-        &m_rootPaintChunkId, rootPaintChunkProperties());
+        &m_rootPaintChunkId, defaultPaintChunkProperties());
   }
 
   drawRect(context, first, backgroundDrawingType,
@@ -366,7 +360,7 @@
 
   if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
     getPaintController().updateCurrentPaintChunkProperties(
-        &m_rootPaintChunkId, rootPaintChunkProperties());
+        &m_rootPaintChunkId, defaultPaintChunkProperties());
   }
 
   first.setDisplayItemsUncached();
@@ -418,7 +412,7 @@
   GraphicsContext context(getPaintController());
   if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
     getPaintController().updateCurrentPaintChunkProperties(
-        &m_rootPaintChunkId, rootPaintChunkProperties());
+        &m_rootPaintChunkId, defaultPaintChunkProperties());
   }
 
   drawRect(context, first, backgroundDrawingType,
@@ -433,7 +427,7 @@
 
   if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
     getPaintController().updateCurrentPaintChunkProperties(
-        &m_rootPaintChunkId, rootPaintChunkProperties());
+        &m_rootPaintChunkId, defaultPaintChunkProperties());
   }
 
   drawRect(context, first, backgroundDrawingType,
@@ -472,7 +466,7 @@
   GraphicsContext context(getPaintController());
   if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
     getPaintController().updateCurrentPaintChunkProperties(
-        &m_rootPaintChunkId, rootPaintChunkProperties());
+        &m_rootPaintChunkId, defaultPaintChunkProperties());
   }
 
   drawRect(context, first, backgroundDrawingType,
@@ -497,7 +491,7 @@
 
   if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
     getPaintController().updateCurrentPaintChunkProperties(
-        &m_rootPaintChunkId, rootPaintChunkProperties());
+        &m_rootPaintChunkId, defaultPaintChunkProperties());
   }
 
   second.setDisplayItemsUncached();
@@ -544,7 +538,7 @@
   GraphicsContext context(getPaintController());
   if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
     getPaintController().updateCurrentPaintChunkProperties(
-        &m_rootPaintChunkId, rootPaintChunkProperties());
+        &m_rootPaintChunkId, defaultPaintChunkProperties());
   }
 
   drawRect(context, second, backgroundDrawingType, FloatRect(200, 200, 50, 50));
@@ -557,7 +551,7 @@
 
   if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
     getPaintController().updateCurrentPaintChunkProperties(
-        &m_rootPaintChunkId, rootPaintChunkProperties());
+        &m_rootPaintChunkId, defaultPaintChunkProperties());
   }
 
   first.setDisplayItemsUncached();
@@ -590,7 +584,7 @@
                     FloatRect(150, 150, 100, 100)));  // New bounds of |second|.
 
     getPaintController().updateCurrentPaintChunkProperties(
-        &m_rootPaintChunkId, rootPaintChunkProperties());
+        &m_rootPaintChunkId, defaultPaintChunkProperties());
   }
 
   drawRect(context, second, backgroundDrawingType,
@@ -626,7 +620,7 @@
   GraphicsContext context(getPaintController());
   if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
     getPaintController().updateCurrentPaintChunkProperties(
-        &m_rootPaintChunkId, rootPaintChunkProperties());
+        &m_rootPaintChunkId, defaultPaintChunkProperties());
   }
 
   drawRect(context, first, backgroundDrawingType,
@@ -641,7 +635,7 @@
 
   if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
     getPaintController().updateCurrentPaintChunkProperties(
-        &m_rootPaintChunkId, rootPaintChunkProperties());
+        &m_rootPaintChunkId, defaultPaintChunkProperties());
   }
 
   first.setDisplayItemsUncached();
@@ -672,7 +666,7 @@
                               50)));  // |second| newly appeared in the chunk.
 
     getPaintController().updateCurrentPaintChunkProperties(
-        &m_rootPaintChunkId, rootPaintChunkProperties());
+        &m_rootPaintChunkId, defaultPaintChunkProperties());
   }
 
   first.setDisplayItemsUncached();
@@ -708,7 +702,7 @@
   {
     if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
       PaintChunk::Id id(first, clipType);
-      PaintChunkProperties properties = rootPaintChunkProperties();
+      PaintChunkProperties properties = defaultPaintChunkProperties();
       properties.clip = ClipPaintPropertyNode::create(
           nullptr, nullptr, FloatRoundedRect(1, 1, 2, 2));
       getPaintController().updateCurrentPaintChunkProperties(&id, properties);
@@ -730,7 +724,7 @@
 
   if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
     getPaintController().updateCurrentPaintChunkProperties(
-        &m_rootPaintChunkId, rootPaintChunkProperties());
+        &m_rootPaintChunkId, defaultPaintChunkProperties());
   }
 
   first.setDisplayItemsUncached();
@@ -759,7 +753,7 @@
                     LayoutRect::infiniteIntRect())));  // This is a new chunk.
 
     getPaintController().updateCurrentPaintChunkProperties(
-        &m_rootPaintChunkId, rootPaintChunkProperties());
+        &m_rootPaintChunkId, defaultPaintChunkProperties());
   }
 
   second.setDisplayItemsUncached();
@@ -768,7 +762,7 @@
   {
     if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
       PaintChunk::Id id(second, clipType);
-      PaintChunkProperties properties = rootPaintChunkProperties();
+      PaintChunkProperties properties = defaultPaintChunkProperties();
       properties.clip = ClipPaintPropertyNode::create(
           nullptr, nullptr, FloatRoundedRect(1, 1, 2, 2));
       getPaintController().updateCurrentPaintChunkProperties(&id, properties);
@@ -804,7 +798,7 @@
   GraphicsContext context(getPaintController());
   if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
     getPaintController().updateCurrentPaintChunkProperties(
-        &m_rootPaintChunkId, rootPaintChunkProperties());
+        &m_rootPaintChunkId, defaultPaintChunkProperties());
   }
 
   drawRect(context, first, backgroundDrawingType,
@@ -833,7 +827,7 @@
 
   if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
     getPaintController().updateCurrentPaintChunkProperties(
-        &m_rootPaintChunkId, rootPaintChunkProperties());
+        &m_rootPaintChunkId, defaultPaintChunkProperties());
   }
   drawRect(context, first, backgroundDrawingType,
            FloatRect(100, 100, 150, 150));
@@ -871,7 +865,7 @@
   GraphicsContext context(getPaintController());
   if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
     getPaintController().updateCurrentPaintChunkProperties(
-        &m_rootPaintChunkId, rootPaintChunkProperties());
+        &m_rootPaintChunkId, defaultPaintChunkProperties());
   }
 
   drawRect(context, container1, backgroundDrawingType,
@@ -904,7 +898,7 @@
 
   if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
     getPaintController().updateCurrentPaintChunkProperties(
-        &m_rootPaintChunkId, rootPaintChunkProperties());
+        &m_rootPaintChunkId, defaultPaintChunkProperties());
   }
 
   // Simulate the situation when |container1| gets a z-index that is greater
@@ -959,7 +953,7 @@
   GraphicsContext context(getPaintController());
   if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
     getPaintController().updateCurrentPaintChunkProperties(
-        &m_rootPaintChunkId, rootPaintChunkProperties());
+        &m_rootPaintChunkId, defaultPaintChunkProperties());
   }
 
   drawRect(context, container1, backgroundDrawingType,
@@ -992,7 +986,7 @@
 
   if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
     getPaintController().updateCurrentPaintChunkProperties(
-        &m_rootPaintChunkId, rootPaintChunkProperties());
+        &m_rootPaintChunkId, defaultPaintChunkProperties());
   }
 
   // Simulate the situation when |container1| gets a z-index that is greater
@@ -1049,15 +1043,14 @@
   FakeDisplayItemClient content2("content2", LayoutRect(100, 200, 50, 200));
   GraphicsContext context(getPaintController());
 
-  PaintChunkProperties container1Properties = rootPaintChunkProperties();
-  PaintChunkProperties container2Properties = rootPaintChunkProperties();
+  PaintChunkProperties container1Properties = defaultPaintChunkProperties();
+  PaintChunkProperties container2Properties = defaultPaintChunkProperties();
 
   {
     if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
       PaintChunk::Id id(container1, backgroundDrawingType);
-      container1Properties.effect = EffectPaintPropertyNode::create(
-          EffectPaintPropertyNode::root(), TransformPaintPropertyNode::root(),
-          ClipPaintPropertyNode::root(), CompositorFilterOperations(), 0.5);
+      container1Properties.effect =
+          createOpacityOnlyEffect(EffectPaintPropertyNode::root(), 0.5);
       getPaintController().updateCurrentPaintChunkProperties(
           &id, container1Properties);
     }
@@ -1074,9 +1067,8 @@
   {
     if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
       PaintChunk::Id id(container2, backgroundDrawingType);
-      container2Properties.effect = EffectPaintPropertyNode::create(
-          EffectPaintPropertyNode::root(), TransformPaintPropertyNode::root(),
-          ClipPaintPropertyNode::root(), CompositorFilterOperations(), 0.5);
+      container2Properties.effect =
+          createOpacityOnlyEffect(EffectPaintPropertyNode::root(), 0.5);
       getPaintController().updateCurrentPaintChunkProperties(
           &id, container2Properties);
     }
@@ -1221,15 +1213,14 @@
   FakeDisplayItemClient content2("content2", LayoutRect(100, 200, 50, 200));
   GraphicsContext context(getPaintController());
 
-  PaintChunkProperties container1Properties = rootPaintChunkProperties();
-  PaintChunkProperties container2Properties = rootPaintChunkProperties();
+  PaintChunkProperties container1Properties = defaultPaintChunkProperties();
+  PaintChunkProperties container2Properties = defaultPaintChunkProperties();
 
   {
     if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
       PaintChunk::Id id(container1, backgroundDrawingType);
-      container1Properties.effect = EffectPaintPropertyNode::create(
-          EffectPaintPropertyNode::root(), TransformPaintPropertyNode::root(),
-          ClipPaintPropertyNode::root(), CompositorFilterOperations(), 0.5);
+      container1Properties.effect =
+          createOpacityOnlyEffect(EffectPaintPropertyNode::root(), 0.5);
       getPaintController().updateCurrentPaintChunkProperties(
           &id, container1Properties);
     }
@@ -1241,9 +1232,8 @@
   {
     if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
       PaintChunk::Id id(container2, backgroundDrawingType);
-      container2Properties.effect = EffectPaintPropertyNode::create(
-          EffectPaintPropertyNode::root(), TransformPaintPropertyNode::root(),
-          ClipPaintPropertyNode::root(), CompositorFilterOperations(), 0.5);
+      container2Properties.effect =
+          createOpacityOnlyEffect(EffectPaintPropertyNode::root(), 0.5);
       getPaintController().updateCurrentPaintChunkProperties(
           &id, container2Properties);
     }
@@ -1335,7 +1325,7 @@
 
   if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
     getPaintController().updateCurrentPaintChunkProperties(
-        &m_rootPaintChunkId, rootPaintChunkProperties());
+        &m_rootPaintChunkId, defaultPaintChunkProperties());
   }
   drawRect(context, client, type1, FloatRect(100, 100, 100, 100));
   drawRect(context, client, type2, FloatRect(100, 100, 50, 200));
@@ -1346,7 +1336,7 @@
 
   if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
     getPaintController().updateCurrentPaintChunkProperties(
-        &m_rootPaintChunkId, rootPaintChunkProperties());
+        &m_rootPaintChunkId, defaultPaintChunkProperties());
   }
   drawRect(context, client, type2, FloatRect(100, 100, 50, 200));
   drawRect(context, client, type3, FloatRect(100, 100, 50, 200));
@@ -1366,20 +1356,19 @@
   GraphicsContext context(getPaintController());
 
   PaintChunkProperties container1BackgroundProperties =
-      rootPaintChunkProperties();
-  PaintChunkProperties content1Properties = rootPaintChunkProperties();
+      defaultPaintChunkProperties();
+  PaintChunkProperties content1Properties = defaultPaintChunkProperties();
   PaintChunkProperties container1ForegroundProperties =
-      rootPaintChunkProperties();
+      defaultPaintChunkProperties();
   PaintChunkProperties container2BackgroundProperties =
-      rootPaintChunkProperties();
-  PaintChunkProperties content2Properties = rootPaintChunkProperties();
+      defaultPaintChunkProperties();
+  PaintChunkProperties content2Properties = defaultPaintChunkProperties();
 
   {
     if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
       PaintChunk::Id id(container1, backgroundDrawingType);
-      container1BackgroundProperties.effect = EffectPaintPropertyNode::create(
-          EffectPaintPropertyNode::root(), TransformPaintPropertyNode::root(),
-          ClipPaintPropertyNode::root(), CompositorFilterOperations(), 0.5);
+      container1BackgroundProperties.effect =
+          createOpacityOnlyEffect(EffectPaintPropertyNode::root(), 0.5);
       getPaintController().updateCurrentPaintChunkProperties(
           &id, container1BackgroundProperties);
     }
@@ -1389,9 +1378,8 @@
     {
       if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
         PaintChunk::Id id(content1, backgroundDrawingType);
-        content1Properties.effect = EffectPaintPropertyNode::create(
-            EffectPaintPropertyNode::root(), TransformPaintPropertyNode::root(),
-            ClipPaintPropertyNode::root(), CompositorFilterOperations(), 0.6);
+        content1Properties.effect =
+            createOpacityOnlyEffect(EffectPaintPropertyNode::root(), 0.6);
         getPaintController().updateCurrentPaintChunkProperties(
             &id, content1Properties);
       }
@@ -1403,9 +1391,8 @@
     }
     if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
       PaintChunk::Id id(container1, foregroundDrawingType);
-      container1ForegroundProperties.effect = EffectPaintPropertyNode::create(
-          EffectPaintPropertyNode::root(), TransformPaintPropertyNode::root(),
-          ClipPaintPropertyNode::root(), CompositorFilterOperations(), 0.5);
+      container1ForegroundProperties.effect =
+          createOpacityOnlyEffect(EffectPaintPropertyNode::root(), 0.5);
       getPaintController().updateCurrentPaintChunkProperties(
           &id, container1ForegroundProperties);
     }
@@ -1415,9 +1402,8 @@
   {
     if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
       PaintChunk::Id id(container2, backgroundDrawingType);
-      container2BackgroundProperties.effect = EffectPaintPropertyNode::create(
-          EffectPaintPropertyNode::root(), TransformPaintPropertyNode::root(),
-          ClipPaintPropertyNode::root(), CompositorFilterOperations(), 0.7);
+      container2BackgroundProperties.effect =
+          createOpacityOnlyEffect(EffectPaintPropertyNode::root(), 0.7);
       getPaintController().updateCurrentPaintChunkProperties(
           &id, container2BackgroundProperties);
     }
@@ -1427,9 +1413,8 @@
     {
       if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
         PaintChunk::Id id(content2, backgroundDrawingType);
-        content2Properties.effect = EffectPaintPropertyNode::create(
-            EffectPaintPropertyNode::root(), TransformPaintPropertyNode::root(),
-            ClipPaintPropertyNode::root(), CompositorFilterOperations(), 0.8);
+        content2Properties.effect =
+            createOpacityOnlyEffect(EffectPaintPropertyNode::root(), 0.8);
         getPaintController().updateCurrentPaintChunkProperties(
             &id, content2Properties);
       }
@@ -1596,7 +1581,7 @@
   GraphicsContext context(getPaintController());
   if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
     getPaintController().updateCurrentPaintChunkProperties(
-        &m_rootPaintChunkId, rootPaintChunkProperties());
+        &m_rootPaintChunkId, defaultPaintChunkProperties());
   }
 
   FloatRect rect1(100, 100, 50, 50);
@@ -1633,7 +1618,7 @@
                 UnorderedElementsAre(FloatRect(LayoutRect::infiniteIntRect())));
 
     getPaintController().updateCurrentPaintChunkProperties(
-        &m_rootPaintChunkId, rootPaintChunkProperties());
+        &m_rootPaintChunkId, defaultPaintChunkProperties());
   }
 
   // Draw again with nothing invalidated.
@@ -1675,7 +1660,7 @@
             FloatRect(100, 100, 100, 100)));  // New bounds of |content|.
 
     getPaintController().updateCurrentPaintChunkProperties(
-        &m_rootPaintChunkId, rootPaintChunkProperties());
+        &m_rootPaintChunkId, defaultPaintChunkProperties());
   }
 
   // Now the multicol becomes 3 columns and repaints.
@@ -1726,7 +1711,7 @@
 
   if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
     getPaintController().updateCurrentPaintChunkProperties(
-        &m_rootPaintChunkId, rootPaintChunkProperties());
+        &m_rootPaintChunkId, defaultPaintChunkProperties());
   }
   drawRect(context, content, backgroundDrawingType, rect1);
   getPaintController().beginSkippingCache();
@@ -1760,7 +1745,7 @@
 
   if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
     getPaintController().updateCurrentPaintChunkProperties(
-        &m_rootPaintChunkId, rootPaintChunkProperties());
+        &m_rootPaintChunkId, defaultPaintChunkProperties());
   }
   // Draw again with nothing invalidated.
   drawRect(context, content, backgroundDrawingType, rect1);
@@ -1851,7 +1836,7 @@
 
   if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
     getPaintController().updateCurrentPaintChunkProperties(
-        nullptr, rootPaintChunkProperties());
+        nullptr, defaultPaintChunkProperties());
   }
   GraphicsContext context(getPaintController());
   drawRect(context, client, backgroundDrawingType, FloatRect(0, 0, 100, 100));
diff --git a/third_party/WebKit/Source/platform/scheduler/child/web_task_runner_impl.cc b/third_party/WebKit/Source/platform/scheduler/child/web_task_runner_impl.cc
index f767e1a..5d8d6c445 100644
--- a/third_party/WebKit/Source/platform/scheduler/child/web_task_runner_impl.cc
+++ b/third_party/WebKit/Source/platform/scheduler/child/web_task_runner_impl.cc
@@ -19,24 +19,6 @@
 
 WebTaskRunnerImpl::~WebTaskRunnerImpl() {}
 
-void WebTaskRunnerImpl::postTask(const blink::WebTraceLocation& location,
-                                 blink::WebTaskRunner::Task* task) {
-  task_queue_->PostTask(location,
-                        base::Bind(&WebTaskRunnerImpl::runTask,
-                                   base::Passed(base::WrapUnique(task))));
-}
-
-void WebTaskRunnerImpl::postDelayedTask(const blink::WebTraceLocation& location,
-                                        blink::WebTaskRunner::Task* task,
-                                        double delayMs) {
-  DCHECK_GE(delayMs, 0.0) << location.function_name() << " "
-                          << location.file_name();
-  task_queue_->PostDelayedTask(location,
-                               base::Bind(&WebTaskRunnerImpl::runTask,
-                                          base::Passed(base::WrapUnique(task))),
-                               base::TimeDelta::FromMillisecondsD(delayMs));
-}
-
 void WebTaskRunnerImpl::postDelayedTask(const WebTraceLocation& location,
                                         const base::Closure& task,
                                         double delayMs) {
@@ -76,10 +58,5 @@
   return task_queue_.get();
 }
 
-void WebTaskRunnerImpl::runTask(
-    std::unique_ptr<blink::WebTaskRunner::Task> task) {
-  task->run();
-}
-
 }  // namespace scheduler
 }  // namespace blink
diff --git a/third_party/WebKit/Source/platform/scheduler/child/web_task_runner_impl.h b/third_party/WebKit/Source/platform/scheduler/child/web_task_runner_impl.h
index f8fa9c2..2eb7f11 100644
--- a/third_party/WebKit/Source/platform/scheduler/child/web_task_runner_impl.h
+++ b/third_party/WebKit/Source/platform/scheduler/child/web_task_runner_impl.h
@@ -24,11 +24,6 @@
   ~WebTaskRunnerImpl() override;
 
   // WebTaskRunner implementation:
-  void postTask(const WebTraceLocation& web_location,
-                WebTaskRunner::Task* task) override;
-  void postDelayedTask(const WebTraceLocation& web_location,
-                       WebTaskRunner::Task* task,
-                       double delayMs) override;
   void postDelayedTask(const WebTraceLocation&,
                        const base::Closure&,
                        double delayMs) override;
@@ -38,14 +33,6 @@
   std::unique_ptr<WebTaskRunner> clone() override;
   base::SingleThreadTaskRunner* toSingleThreadTaskRunner() override;
 
-  // WebTaskRunner::Task should be wrapped by base::Passed() when
-  // used with base::Bind(). See https://crbug.com/551356.
-  // runTask() is a helper to call WebTaskRunner::Task::run from
-  // std::unique_ptr<WebTaskRunner::Task>.
-  // runTask() is placed here because std::unique_ptr<> cannot be used from
-  // Blink.
-  static void runTask(std::unique_ptr<WebTaskRunner::Task>);
-
  private:
   base::TimeTicks Now() const;
 
diff --git a/third_party/WebKit/Source/platform/scheduler/child/webthread_impl_for_worker_scheduler_unittest.cc b/third_party/WebKit/Source/platform/scheduler/child/webthread_impl_for_worker_scheduler_unittest.cc
index 0c14654..dc50950b 100644
--- a/third_party/WebKit/Source/platform/scheduler/child/webthread_impl_for_worker_scheduler_unittest.cc
+++ b/third_party/WebKit/Source/platform/scheduler/child/webthread_impl_for_worker_scheduler_unittest.cc
@@ -22,17 +22,8 @@
 namespace scheduler {
 namespace {
 
-class NopTask : public blink::WebTaskRunner::Task {
+class MockTask {
  public:
-  ~NopTask() override {}
-
-  void run() override {}
-};
-
-class MockTask : public blink::WebTaskRunner::Task {
- public:
-  ~MockTask() override {}
-
   MOCK_METHOD0(run, void());
 };
 
@@ -57,17 +48,9 @@
   std::string* calls_;  // NOT OWNED
 };
 
-class TestTask : public blink::WebTaskRunner::Task {
- public:
-  explicit TestTask(std::string* calls) : calls_(calls) {}
-
-  ~TestTask() override {}
-
-  void run() override { calls_->append(" run"); }
-
- private:
-  std::string* calls_;  // NOT OWNED
-};
+void runTestTask(std::string* calls) {
+  calls->append(" run");
+}
 
 void addTaskObserver(WebThreadImplForWorkerScheduler* thread,
                      TestObserver* observer) {
@@ -123,33 +106,35 @@
 };
 
 TEST_F(WebThreadImplForWorkerSchedulerTest, TestDefaultTask) {
-  std::unique_ptr<MockTask> task(new MockTask());
+  MockTask task;
   base::WaitableEvent completion(
       base::WaitableEvent::ResetPolicy::AUTOMATIC,
       base::WaitableEvent::InitialState::NOT_SIGNALED);
 
-  EXPECT_CALL(*task, run());
-  ON_CALL(*task, run())
-      .WillByDefault(Invoke([&completion]() { completion.Signal(); }));
+  EXPECT_CALL(task, run());
+  ON_CALL(task, run()).WillByDefault(Invoke([&completion]() {
+    completion.Signal();
+  }));
 
-  thread_->getWebTaskRunner()->postTask(blink::WebTraceLocation(),
-                                        task.release());
+  thread_->getWebTaskRunner()->postTask(
+      BLINK_FROM_HERE, WTF::bind(&MockTask::run, WTF::unretained(&task)));
   completion.Wait();
 }
 
 TEST_F(WebThreadImplForWorkerSchedulerTest,
        TestTaskExecutedBeforeThreadDeletion) {
-  std::unique_ptr<MockTask> task(new MockTask());
+  MockTask task;
   base::WaitableEvent completion(
       base::WaitableEvent::ResetPolicy::AUTOMATIC,
       base::WaitableEvent::InitialState::NOT_SIGNALED);
 
-  EXPECT_CALL(*task, run());
-  ON_CALL(*task, run())
-      .WillByDefault(Invoke([&completion]() { completion.Signal(); }));
+  EXPECT_CALL(task, run());
+  ON_CALL(task, run()).WillByDefault(Invoke([&completion]() {
+    completion.Signal();
+  }));
 
-  thread_->getWebTaskRunner()->postTask(blink::WebTraceLocation(),
-                                        task.release());
+  thread_->getWebTaskRunner()->postTask(
+      BLINK_FROM_HERE, WTF::bind(&MockTask::run, WTF::unretained(&task)));
   thread_.reset();
 }
 
@@ -163,10 +148,10 @@
   ON_CALL(*task, run(_))
       .WillByDefault(Invoke([&completion](double) { completion.Signal(); }));
 
-  thread_->postIdleTask(blink::WebTraceLocation(), task.release());
+  thread_->postIdleTask(BLINK_FROM_HERE, task.release());
   // We need to post a wakeup task or idle work will never happen.
-  thread_->getWebTaskRunner()->postDelayedTask(blink::WebTraceLocation(),
-                                               new NopTask(), 50ll);
+  thread_->getWebTaskRunner()->postDelayedTask(BLINK_FROM_HERE,
+                                               WTF::bind([] {}), 50ll);
 
   completion.Wait();
 }
@@ -177,8 +162,8 @@
 
   RunOnWorkerThread(FROM_HERE,
                     base::Bind(&addTaskObserver, thread_.get(), &observer));
-  thread_->getWebTaskRunner()->postTask(blink::WebTraceLocation(),
-                                        new TestTask(&calls));
+  thread_->getWebTaskRunner()->postTask(
+      BLINK_FROM_HERE, WTF::bind(&runTestTask, WTF::unretained(&calls)));
   RunOnWorkerThread(FROM_HERE,
                     base::Bind(&removeTaskObserver, thread_.get(), &observer));
 
@@ -191,17 +176,18 @@
 }
 
 TEST_F(WebThreadImplForWorkerSchedulerTest, TestShutdown) {
-  std::unique_ptr<MockTask> task(new MockTask());
-  std::unique_ptr<MockTask> delayed_task(new MockTask());
+  MockTask task;
+  MockTask delayed_task;
 
-  EXPECT_CALL(*task, run()).Times(0);
-  EXPECT_CALL(*delayed_task, run()).Times(0);
+  EXPECT_CALL(task, run()).Times(0);
+  EXPECT_CALL(delayed_task, run()).Times(0);
 
   RunOnWorkerThread(FROM_HERE, base::Bind(&shutdownOnThread, thread_.get()));
-  thread_->getWebTaskRunner()->postTask(blink::WebTraceLocation(),
-                                        task.release());
-  thread_->getWebTaskRunner()->postDelayedTask(blink::WebTraceLocation(),
-                                               task.release(), 50ll);
+  thread_->getWebTaskRunner()->postTask(
+      BLINK_FROM_HERE, WTF::bind(&MockTask::run, WTF::unretained(&task)));
+  thread_->getWebTaskRunner()->postDelayedTask(
+      BLINK_FROM_HERE,
+      WTF::bind(&MockTask::run, WTF::unretained(&delayed_task)), 50ll);
   thread_.reset();
 }
 
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl_unittest.cc b/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl_unittest.cc
index 744c54eae..dcb5dab 100644
--- a/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl_unittest.cc
+++ b/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl_unittest.cc
@@ -57,23 +57,21 @@
 };
 
 namespace {
-class RepeatingTask : public blink::WebTaskRunner::Task {
- public:
-  RepeatingTask(blink::WebTaskRunner* web_task_runner, int* run_count)
-      : web_task_runner_(web_task_runner), run_count_(run_count) {}
 
-  ~RepeatingTask() override {}
+void runRepeatingTask(WebTaskRunner* task_runner, int* run_count);
 
-  void run() override {
-    (*run_count_)++;
-    web_task_runner_->postDelayedTask(
-        BLINK_FROM_HERE, new RepeatingTask(web_task_runner_, run_count_), 1.0);
-  }
+std::unique_ptr<WTF::Closure> makeRepeatingTask(
+    blink::WebTaskRunner* task_runner,
+    int* run_count) {
+  return WTF::bind(&runRepeatingTask, WTF::unretained(task_runner),
+                   WTF::unretained(run_count));
+}
 
- private:
-  blink::WebTaskRunner* web_task_runner_;  // NOT OWNED
-  int* run_count_;                         // NOT OWNED
-};
+void runRepeatingTask(WebTaskRunner* task_runner, int* run_count) {
+  ++*run_count;
+  task_runner->postDelayedTask(BLINK_FROM_HERE,
+                               makeRepeatingTask(task_runner, run_count), 1.0);
+}
 
 void IncrementCounter(int* counter) {
   ++*counter;
@@ -87,7 +85,7 @@
   int run_count = 0;
   web_frame_scheduler_->timerTaskRunner()->postDelayedTask(
       BLINK_FROM_HERE,
-      new RepeatingTask(web_frame_scheduler_->timerTaskRunner(), &run_count),
+      makeRepeatingTask(web_frame_scheduler_->timerTaskRunner(), &run_count),
       1.0);
 
   mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(1));
@@ -101,7 +99,7 @@
   int run_count = 0;
   web_frame_scheduler_->timerTaskRunner()->postDelayedTask(
       BLINK_FROM_HERE,
-      new RepeatingTask(web_frame_scheduler_->timerTaskRunner(), &run_count),
+      makeRepeatingTask(web_frame_scheduler_->timerTaskRunner(), &run_count),
       1.0);
 
   mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(1));
@@ -115,7 +113,7 @@
   int run_count = 0;
   web_frame_scheduler_->timerTaskRunner()->postDelayedTask(
       BLINK_FROM_HERE,
-      new RepeatingTask(web_frame_scheduler_->timerTaskRunner(), &run_count),
+      makeRepeatingTask(web_frame_scheduler_->timerTaskRunner(), &run_count),
       1.0);
 
   mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(1));
@@ -130,7 +128,7 @@
   int run_count = 0;
   web_frame_scheduler_->timerTaskRunner()->postDelayedTask(
       BLINK_FROM_HERE,
-      new RepeatingTask(web_frame_scheduler_->timerTaskRunner(), &run_count),
+      makeRepeatingTask(web_frame_scheduler_->timerTaskRunner(), &run_count),
       1.0);
 
   mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(1));
@@ -145,7 +143,7 @@
   int run_count = 0;
   web_frame_scheduler_->timerTaskRunner()->postDelayedTask(
       BLINK_FROM_HERE,
-      new RepeatingTask(web_frame_scheduler_->timerTaskRunner(), &run_count),
+      makeRepeatingTask(web_frame_scheduler_->timerTaskRunner(), &run_count),
       1.0);
 
   mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(1));
@@ -159,7 +157,7 @@
   int run_count = 0;
   web_frame_scheduler_->timerTaskRunner()->postDelayedTask(
       BLINK_FROM_HERE,
-      new RepeatingTask(web_frame_scheduler_->timerTaskRunner(), &run_count),
+      makeRepeatingTask(web_frame_scheduler_->timerTaskRunner(), &run_count),
       1.0);
 
   mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(1));
@@ -174,7 +172,7 @@
   int run_count = 0;
   web_frame_scheduler_->timerTaskRunner()->postDelayedTask(
       BLINK_FROM_HERE,
-      new RepeatingTask(web_frame_scheduler_->timerTaskRunner(), &run_count),
+      makeRepeatingTask(web_frame_scheduler_->timerTaskRunner(), &run_count),
       1.0);
 
   mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(1));
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler_impl_unittest.cc b/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler_impl_unittest.cc
index 287fe6e..0c94e408 100644
--- a/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler_impl_unittest.cc
+++ b/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler_impl_unittest.cc
@@ -79,23 +79,22 @@
 }
 
 namespace {
-class RepeatingTask : public blink::WebTaskRunner::Task {
- public:
-  RepeatingTask(blink::WebTaskRunner* web_task_runner, int* run_count)
-      : web_task_runner_(web_task_runner), run_count_(run_count) {}
 
-  ~RepeatingTask() override {}
+void runRepeatingTask(blink::WebTaskRunner* task_runner, int* run_count);
 
-  void run() override {
-    (*run_count_)++;
-    web_task_runner_->postDelayedTask(
-        BLINK_FROM_HERE, new RepeatingTask(web_task_runner_, run_count_), 1.0);
-  }
+std::unique_ptr<WTF::Closure> makeRepeatingTask(
+    blink::WebTaskRunner* task_runner,
+    int* run_count) {
+  return WTF::bind(&runRepeatingTask, WTF::unretained(task_runner),
+                   WTF::unretained(run_count));
+}
 
- private:
-  blink::WebTaskRunner* web_task_runner_;  // NOT OWNED
-  int* run_count_;                         // NOT OWNED
-};
+void runRepeatingTask(blink::WebTaskRunner* task_runner, int* run_count) {
+  ++*run_count;
+  task_runner->postDelayedTask(BLINK_FROM_HERE,
+                               makeRepeatingTask(task_runner, run_count), 1.0);
+}
+
 }  // namespace
 
 TEST_F(WebViewSchedulerImplTest, RepeatingTimer_PageInForeground) {
@@ -104,7 +103,7 @@
   int run_count = 0;
   web_frame_scheduler_->timerTaskRunner()->postDelayedTask(
       BLINK_FROM_HERE,
-      new RepeatingTask(web_frame_scheduler_->timerTaskRunner(), &run_count),
+      makeRepeatingTask(web_frame_scheduler_->timerTaskRunner(), &run_count),
       1.0);
 
   mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(1));
@@ -117,7 +116,7 @@
   int run_count = 0;
   web_frame_scheduler_->timerTaskRunner()->postDelayedTask(
       BLINK_FROM_HERE,
-      new RepeatingTask(web_frame_scheduler_->timerTaskRunner(), &run_count),
+      makeRepeatingTask(web_frame_scheduler_->timerTaskRunner(), &run_count),
       1.0);
 
   mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(1));
@@ -130,7 +129,7 @@
   int run_count = 0;
   web_frame_scheduler_->loadingTaskRunner()->postDelayedTask(
       BLINK_FROM_HERE,
-      new RepeatingTask(web_frame_scheduler_->loadingTaskRunner(), &run_count),
+      makeRepeatingTask(web_frame_scheduler_->loadingTaskRunner(), &run_count),
       1.0);
 
   mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(1));
@@ -150,11 +149,11 @@
   int run_count2 = 0;
   web_frame_scheduler_->timerTaskRunner()->postDelayedTask(
       BLINK_FROM_HERE,
-      new RepeatingTask(web_frame_scheduler_->timerTaskRunner(), &run_count1),
+      makeRepeatingTask(web_frame_scheduler_->timerTaskRunner(), &run_count1),
       1.0);
   web_frame_scheduler2->timerTaskRunner()->postDelayedTask(
       BLINK_FROM_HERE,
-      new RepeatingTask(web_frame_scheduler2->timerTaskRunner(), &run_count2),
+      makeRepeatingTask(web_frame_scheduler2->timerTaskRunner(), &run_count2),
       1.0);
 
   mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(1));
@@ -163,31 +162,26 @@
 }
 
 namespace {
-class VirtualTimeRecorderTask : public blink::WebTaskRunner::Task {
- public:
-  VirtualTimeRecorderTask(base::SimpleTestTickClock* clock,
-                          blink::WebTaskRunner* web_task_runner,
-                          std::vector<base::TimeTicks>* out_real_times,
-                          std::vector<size_t>* out_virtual_times_ms)
-      : clock_(clock),
-        web_task_runner_(web_task_runner),
-        out_real_times_(out_real_times),
-        out_virtual_times_ms_(out_virtual_times_ms) {}
 
-  ~VirtualTimeRecorderTask() override {}
+void runVirtualTimeRecorderTask(base::SimpleTestTickClock* clock,
+                                blink::WebTaskRunner* web_task_runner,
+                                std::vector<base::TimeTicks>* out_real_times,
+                                std::vector<size_t>* out_virtual_times_ms) {
+  out_real_times->push_back(clock->NowTicks());
+  out_virtual_times_ms->push_back(
+      web_task_runner->monotonicallyIncreasingVirtualTimeSeconds() * 1000.0);
+}
 
-  void run() override {
-    out_real_times_->push_back(clock_->NowTicks());
-    out_virtual_times_ms_->push_back(
-        web_task_runner_->monotonicallyIncreasingVirtualTimeSeconds() * 1000.0);
-  }
-
- private:
-  base::SimpleTestTickClock* clock_;              // NOT OWNED
-  blink::WebTaskRunner* web_task_runner_;         // NOT OWNED
-  std::vector<base::TimeTicks>* out_real_times_;  // NOT OWNED
-  std::vector<size_t>* out_virtual_times_ms_;     // NOT OWNED
-};
+std::unique_ptr<WTF::Closure> makeVirtualTimeRecorderTask(
+    base::SimpleTestTickClock* clock,
+    blink::WebTaskRunner* web_task_runner,
+    std::vector<base::TimeTicks>* out_real_times,
+    std::vector<size_t>* out_virtual_times_ms) {
+  return WTF::bind(&runVirtualTimeRecorderTask, WTF::unretained(clock),
+                   WTF::unretained(web_task_runner),
+                   WTF::unretained(out_real_times),
+                   WTF::unretained(out_virtual_times_ms));
+}
 }
 
 TEST_F(WebViewSchedulerImplTest, VirtualTime_TimerFastForwarding) {
@@ -203,21 +197,21 @@
 
   web_frame_scheduler_->timerTaskRunner()->postDelayedTask(
       BLINK_FROM_HERE,
-      new VirtualTimeRecorderTask(clock_.get(),
+      makeVirtualTimeRecorderTask(clock_.get(),
                                   web_frame_scheduler_->timerTaskRunner(),
                                   &real_times, &virtual_times_ms),
       2.0);
 
   web_frame_scheduler_->timerTaskRunner()->postDelayedTask(
       BLINK_FROM_HERE,
-      new VirtualTimeRecorderTask(clock_.get(),
+      makeVirtualTimeRecorderTask(clock_.get(),
                                   web_frame_scheduler_->timerTaskRunner(),
                                   &real_times, &virtual_times_ms),
       20.0);
 
   web_frame_scheduler_->timerTaskRunner()->postDelayedTask(
       BLINK_FROM_HERE,
-      new VirtualTimeRecorderTask(clock_.get(),
+      makeVirtualTimeRecorderTask(clock_.get(),
                                   web_frame_scheduler_->timerTaskRunner(),
                                   &real_times, &virtual_times_ms),
       200.0);
@@ -244,21 +238,21 @@
 
   web_frame_scheduler_->loadingTaskRunner()->postDelayedTask(
       BLINK_FROM_HERE,
-      new VirtualTimeRecorderTask(clock_.get(),
+      makeVirtualTimeRecorderTask(clock_.get(),
                                   web_frame_scheduler_->loadingTaskRunner(),
                                   &real_times, &virtual_times_ms),
       2.0);
 
   web_frame_scheduler_->loadingTaskRunner()->postDelayedTask(
       BLINK_FROM_HERE,
-      new VirtualTimeRecorderTask(clock_.get(),
+      makeVirtualTimeRecorderTask(clock_.get(),
                                   web_frame_scheduler_->loadingTaskRunner(),
                                   &real_times, &virtual_times_ms),
       20.0);
 
   web_frame_scheduler_->loadingTaskRunner()->postDelayedTask(
       BLINK_FROM_HERE,
-      new VirtualTimeRecorderTask(clock_.get(),
+      makeVirtualTimeRecorderTask(clock_.get(),
                                   web_frame_scheduler_->loadingTaskRunner(),
                                   &real_times, &virtual_times_ms),
       200.0);
@@ -281,7 +275,7 @@
   int run_count = 0;
   web_frame_scheduler_->timerTaskRunner()->postDelayedTask(
       BLINK_FROM_HERE,
-      new RepeatingTask(web_frame_scheduler_->timerTaskRunner(), &run_count),
+      makeRepeatingTask(web_frame_scheduler_->timerTaskRunner(), &run_count),
       1.0);
 
   mock_task_runner_->RunTasksWhile(mock_task_runner_->TaskRunCountBelow(2000));
@@ -294,42 +288,19 @@
 }
 
 namespace {
-class RunOrderTask : public blink::WebTaskRunner::Task {
- public:
-  RunOrderTask(int index, std::vector<int>* out_run_order)
-      : index_(index), out_run_order_(out_run_order) {}
 
-  ~RunOrderTask() override {}
+void runOrderTask(int index, std::vector<int>* out_run_order) {
+  out_run_order->push_back(index);
+}
 
-  void run() override { out_run_order_->push_back(index_); }
-
- private:
-  int index_;
-  std::vector<int>* out_run_order_;  // NOT OWNED
-};
-
-class DelayedRunOrderTask : public blink::WebTaskRunner::Task {
- public:
-  DelayedRunOrderTask(int index,
-                      blink::WebTaskRunner* task_runner,
-                      std::vector<int>* out_run_order)
-      : index_(index),
-        task_runner_(task_runner),
-        out_run_order_(out_run_order) {}
-
-  ~DelayedRunOrderTask() override {}
-
-  void run() override {
-    out_run_order_->push_back(index_);
-    task_runner_->postTask(BLINK_FROM_HERE,
-                           new RunOrderTask(index_ + 1, out_run_order_));
-  }
-
- private:
-  int index_;
-  blink::WebTaskRunner* task_runner_;  // NOT OWNED
-  std::vector<int>* out_run_order_;    // NOT OWNED
-};
+void delayedRunOrderTask(int index,
+                         blink::WebTaskRunner* task_runner,
+                         std::vector<int>* out_run_order) {
+  out_run_order->push_back(index);
+  task_runner->postTask(
+      BLINK_FROM_HERE,
+      WTF::bind(&runOrderTask, index + 1, WTF::unretained(out_run_order)));
+}
 }
 
 TEST_F(WebViewSchedulerImplTest, VirtualTime_NotAllowedToAdvance) {
@@ -339,18 +310,21 @@
   web_view_scheduler_->enableVirtualTime();
 
   web_frame_scheduler_->timerTaskRunner()->postTask(
-      BLINK_FROM_HERE, new RunOrderTask(0, &run_order));
+      BLINK_FROM_HERE,
+      WTF::bind(&runOrderTask, 0, WTF::unretained(&run_order)));
 
   web_frame_scheduler_->timerTaskRunner()->postDelayedTask(
       BLINK_FROM_HERE,
-      new DelayedRunOrderTask(1, web_frame_scheduler_->timerTaskRunner(),
-                              &run_order),
+      WTF::bind(&delayedRunOrderTask, 1,
+                WTF::unretained(web_frame_scheduler_->timerTaskRunner()),
+                WTF::unretained(&run_order)),
       2.0);
 
   web_frame_scheduler_->timerTaskRunner()->postDelayedTask(
       BLINK_FROM_HERE,
-      new DelayedRunOrderTask(3, web_frame_scheduler_->timerTaskRunner(),
-                              &run_order),
+      WTF::bind(&delayedRunOrderTask, 3,
+                WTF::unretained(web_frame_scheduler_->timerTaskRunner()),
+                WTF::unretained(&run_order)),
       4.0);
 
   mock_task_runner_->RunUntilIdle();
@@ -366,18 +340,21 @@
   web_view_scheduler_->enableVirtualTime();
 
   web_frame_scheduler_->timerTaskRunner()->postTask(
-      BLINK_FROM_HERE, new RunOrderTask(0, &run_order));
+      BLINK_FROM_HERE,
+      WTF::bind(&runOrderTask, 0, WTF::unretained(&run_order)));
 
   web_frame_scheduler_->timerTaskRunner()->postDelayedTask(
       BLINK_FROM_HERE,
-      new DelayedRunOrderTask(1, web_frame_scheduler_->timerTaskRunner(),
-                              &run_order),
+      WTF::bind(&delayedRunOrderTask, 1,
+                WTF::unretained(web_frame_scheduler_->timerTaskRunner()),
+                WTF::unretained(&run_order)),
       2.0);
 
   web_frame_scheduler_->timerTaskRunner()->postDelayedTask(
       BLINK_FROM_HERE,
-      new DelayedRunOrderTask(3, web_frame_scheduler_->timerTaskRunner(),
-                              &run_order),
+      WTF::bind(&delayedRunOrderTask, 3,
+                WTF::unretained(web_frame_scheduler_->timerTaskRunner()),
+                WTF::unretained(&run_order)),
       4.0);
 
   mock_task_runner_->RunUntilIdle();
@@ -401,7 +378,7 @@
   int run_count = 0;
   web_frame_scheduler_->timerTaskRunner()->postDelayedTask(
       BLINK_FROM_HERE,
-      new RepeatingTask(web_frame_scheduler_->timerTaskRunner(), &run_count),
+      makeRepeatingTask(web_frame_scheduler_->timerTaskRunner(), &run_count),
       1.0);
 
   mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(1));
@@ -418,7 +395,8 @@
       web_view_scheduler_->createWebFrameSchedulerImpl(nullptr);
 
   web_frame_scheduler->timerTaskRunner()->postDelayedTask(
-      BLINK_FROM_HERE, new RunOrderTask(1, &run_order), 0.1);
+      BLINK_FROM_HERE, WTF::bind(&runOrderTask, 1, WTF::unretained(&run_order)),
+      1);
 
   mock_task_runner_->RunUntilIdle();
   EXPECT_TRUE(run_order.empty());
@@ -430,72 +408,47 @@
 }
 
 namespace {
-class DeleteWebFrameSchedulerTask : public blink::WebTaskRunner::Task {
- public:
-  explicit DeleteWebFrameSchedulerTask(WebViewSchedulerImpl* web_view_scheduler)
-      : web_frame_scheduler_(
-            web_view_scheduler->createWebFrameSchedulerImpl(nullptr)) {}
 
-  ~DeleteWebFrameSchedulerTask() override {}
+template <typename T>
+std::unique_ptr<WTF::Closure> makeDeletionTask(T* obj) {
+  return WTF::bind([](T* obj) { delete obj; }, WTF::unretained(obj));
+}
 
-  void run() override { web_frame_scheduler_.reset(); }
-
-  WebFrameSchedulerImpl* web_frame_scheduler() const {
-    return web_frame_scheduler_.get();
-  }
-
- private:
-  std::unique_ptr<WebFrameSchedulerImpl> web_frame_scheduler_;
-};
-
-class DeleteWebViewSchedulerTask : public blink::WebTaskRunner::Task {
- public:
-  explicit DeleteWebViewSchedulerTask(WebViewSchedulerImpl* web_view_scheduler)
-      : web_view_scheduler_(web_view_scheduler) {}
-
-  ~DeleteWebViewSchedulerTask() override {}
-
-  void run() override { web_view_scheduler_.reset(); }
-
- private:
-  std::unique_ptr<WebViewSchedulerImpl> web_view_scheduler_;
-};
 }  // namespace
 
 TEST_F(WebViewSchedulerImplTest, DeleteWebFrameSchedulers_InTask) {
   for (int i = 0; i < 10; i++) {
-    DeleteWebFrameSchedulerTask* task =
-        new DeleteWebFrameSchedulerTask(web_view_scheduler_.get());
-    task->web_frame_scheduler()->timerTaskRunner()->postDelayedTask(
-        BLINK_FROM_HERE, task, 1.0);
+    WebFrameSchedulerImpl* web_frame_scheduler =
+        web_view_scheduler_->createWebFrameSchedulerImpl(nullptr).release();
+    web_frame_scheduler->timerTaskRunner()->postDelayedTask(
+        BLINK_FROM_HERE, makeDeletionTask(web_frame_scheduler), 1);
   }
   mock_task_runner_->RunUntilIdle();
 }
 
 TEST_F(WebViewSchedulerImplTest, DeleteWebViewScheduler_InTask) {
   web_frame_scheduler_->timerTaskRunner()->postTask(
-      BLINK_FROM_HERE,
-      new DeleteWebViewSchedulerTask(web_view_scheduler_.release()));
+      BLINK_FROM_HERE, makeDeletionTask(web_view_scheduler_.release()));
   mock_task_runner_->RunUntilIdle();
 }
 
 TEST_F(WebViewSchedulerImplTest, DeleteThrottledQueue_InTask) {
   web_view_scheduler_->setPageVisible(false);
 
-  DeleteWebFrameSchedulerTask* delete_frame_task =
-      new DeleteWebFrameSchedulerTask(web_view_scheduler_.get());
+  WebFrameSchedulerImpl* web_frame_scheduler =
+      web_view_scheduler_->createWebFrameSchedulerImpl(nullptr).release();
   blink::WebTaskRunner* timer_task_runner =
-      delete_frame_task->web_frame_scheduler()->timerTaskRunner();
+      web_frame_scheduler->timerTaskRunner();
 
   int run_count = 0;
   timer_task_runner->postDelayedTask(
-      BLINK_FROM_HERE, new RepeatingTask(timer_task_runner, &run_count), 1.0);
+      BLINK_FROM_HERE, makeRepeatingTask(timer_task_runner, &run_count), 1.0);
 
   // Note this will run at time t = 10s since we start at time t = 5000us, and
   // it will prevent further tasks from running (i.e. the RepeatingTask) by
   // deleting the WebFrameScheduler.
-  timer_task_runner->postDelayedTask(BLINK_FROM_HERE, delete_frame_task,
-                                     9990.0);
+  timer_task_runner->postDelayedTask(
+      BLINK_FROM_HERE, makeDeletionTask(web_frame_scheduler), 9990.0);
 
   mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(100));
   EXPECT_EQ(10, run_count);
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/webthread_impl_for_renderer_scheduler_unittest.cc b/third_party/WebKit/Source/platform/scheduler/renderer/webthread_impl_for_renderer_scheduler_unittest.cc
index 6fc53b0..f9111c7 100644
--- a/third_party/WebKit/Source/platform/scheduler/renderer/webthread_impl_for_renderer_scheduler_unittest.cc
+++ b/third_party/WebKit/Source/platform/scheduler/renderer/webthread_impl_for_renderer_scheduler_unittest.cc
@@ -26,7 +26,7 @@
 
 const int kWorkBatchSize = 2;
 
-class MockTask : public blink::WebTaskRunner::Task {
+class MockTask {
  public:
   MOCK_METHOD0(run, void());
 };
@@ -73,17 +73,17 @@
 TEST_F(WebThreadImplForRendererSchedulerTest, TestTaskObserver) {
   MockTaskObserver observer;
   thread_->addTaskObserver(&observer);
-  std::unique_ptr<MockTask> task(new MockTask());
+  MockTask task;
 
   {
     testing::InSequence sequence;
     EXPECT_CALL(observer, willProcessTask());
-    EXPECT_CALL(*task, run());
+    EXPECT_CALL(task, run());
     EXPECT_CALL(observer, didProcessTask());
   }
 
-  thread_->getWebTaskRunner()->postTask(blink::WebTraceLocation(),
-                                        task.release());
+  thread_->getWebTaskRunner()->postTask(
+      BLINK_FROM_HERE, WTF::bind(&MockTask::run, WTF::unretained(&task)));
   base::RunLoop().RunUntilIdle();
   thread_->removeTaskObserver(&observer);
 }
@@ -91,18 +91,18 @@
 TEST_F(WebThreadImplForRendererSchedulerTest, TestWorkBatchWithOneTask) {
   MockTaskObserver observer;
   thread_->addTaskObserver(&observer);
-  std::unique_ptr<MockTask> task(new MockTask());
+  MockTask task;
 
   SetWorkBatchSizeForTesting(kWorkBatchSize);
   {
     testing::InSequence sequence;
     EXPECT_CALL(observer, willProcessTask());
-    EXPECT_CALL(*task, run());
+    EXPECT_CALL(task, run());
     EXPECT_CALL(observer, didProcessTask());
   }
 
-  thread_->getWebTaskRunner()->postTask(blink::WebTraceLocation(),
-                                        task.release());
+  thread_->getWebTaskRunner()->postTask(
+      BLINK_FROM_HERE, WTF::bind(&MockTask::run, WTF::unretained(&task)));
   base::RunLoop().RunUntilIdle();
   thread_->removeTaskObserver(&observer);
 }
@@ -110,25 +110,25 @@
 TEST_F(WebThreadImplForRendererSchedulerTest, TestWorkBatchWithTwoTasks) {
   MockTaskObserver observer;
   thread_->addTaskObserver(&observer);
-  std::unique_ptr<MockTask> task1(new MockTask());
-  std::unique_ptr<MockTask> task2(new MockTask());
+  MockTask task1;
+  MockTask task2;
 
   SetWorkBatchSizeForTesting(kWorkBatchSize);
   {
     testing::InSequence sequence;
     EXPECT_CALL(observer, willProcessTask());
-    EXPECT_CALL(*task1, run());
+    EXPECT_CALL(task1, run());
     EXPECT_CALL(observer, didProcessTask());
 
     EXPECT_CALL(observer, willProcessTask());
-    EXPECT_CALL(*task2, run());
+    EXPECT_CALL(task2, run());
     EXPECT_CALL(observer, didProcessTask());
   }
 
-  thread_->getWebTaskRunner()->postTask(blink::WebTraceLocation(),
-                                        task1.release());
-  thread_->getWebTaskRunner()->postTask(blink::WebTraceLocation(),
-                                        task2.release());
+  thread_->getWebTaskRunner()->postTask(
+      BLINK_FROM_HERE, WTF::bind(&MockTask::run, WTF::unretained(&task1)));
+  thread_->getWebTaskRunner()->postTask(
+      BLINK_FROM_HERE, WTF::bind(&MockTask::run, WTF::unretained(&task2)));
   base::RunLoop().RunUntilIdle();
   thread_->removeTaskObserver(&observer);
 }
@@ -136,52 +136,43 @@
 TEST_F(WebThreadImplForRendererSchedulerTest, TestWorkBatchWithThreeTasks) {
   MockTaskObserver observer;
   thread_->addTaskObserver(&observer);
-  std::unique_ptr<MockTask> task1(new MockTask());
-  std::unique_ptr<MockTask> task2(new MockTask());
-  std::unique_ptr<MockTask> task3(new MockTask());
+  MockTask task1;
+  MockTask task2;
+  MockTask task3;
 
   SetWorkBatchSizeForTesting(kWorkBatchSize);
   {
     testing::InSequence sequence;
     EXPECT_CALL(observer, willProcessTask());
-    EXPECT_CALL(*task1, run());
+    EXPECT_CALL(task1, run());
     EXPECT_CALL(observer, didProcessTask());
 
     EXPECT_CALL(observer, willProcessTask());
-    EXPECT_CALL(*task2, run());
+    EXPECT_CALL(task2, run());
     EXPECT_CALL(observer, didProcessTask());
 
     EXPECT_CALL(observer, willProcessTask());
-    EXPECT_CALL(*task3, run());
+    EXPECT_CALL(task3, run());
     EXPECT_CALL(observer, didProcessTask());
   }
 
-  thread_->getWebTaskRunner()->postTask(blink::WebTraceLocation(),
-                                        task1.release());
-  thread_->getWebTaskRunner()->postTask(blink::WebTraceLocation(),
-                                        task2.release());
-  thread_->getWebTaskRunner()->postTask(blink::WebTraceLocation(),
-                                        task3.release());
+  thread_->getWebTaskRunner()->postTask(
+      BLINK_FROM_HERE, WTF::bind(&MockTask::run, WTF::unretained(&task1)));
+  thread_->getWebTaskRunner()->postTask(
+      BLINK_FROM_HERE, WTF::bind(&MockTask::run, WTF::unretained(&task2)));
+  thread_->getWebTaskRunner()->postTask(
+      BLINK_FROM_HERE, WTF::bind(&MockTask::run, WTF::unretained(&task3)));
   base::RunLoop().RunUntilIdle();
   thread_->removeTaskObserver(&observer);
 }
 
-class ExitRunLoopTask : public blink::WebTaskRunner::Task {
- public:
-  ExitRunLoopTask(base::RunLoop* run_loop) : run_loop_(run_loop) {}
-
-  void run() override { run_loop_->Quit(); }
-
- private:
-  base::RunLoop* run_loop_;
-};
-
 void EnterRunLoop(base::MessageLoop* message_loop, blink::WebThread* thread) {
   // Note: WebThreads do not support nested run loops, which is why we use a
   // run loop directly.
   base::RunLoop run_loop;
-  thread->getWebTaskRunner()->postTask(blink::WebTraceLocation(),
-                                       new ExitRunLoopTask(&run_loop));
+  thread->getWebTaskRunner()->postTask(
+      BLINK_FROM_HERE,
+      WTF::bind(&base::RunLoop::Quit, WTF::unretained(&run_loop)));
   message_loop->SetNestableTasksAllowed(true);
   run_loop.Run();
 }
diff --git a/third_party/WebKit/Source/platform/scheduler/test/fake_web_task_runner.cc b/third_party/WebKit/Source/platform/scheduler/test/fake_web_task_runner.cc
index 0d38666..304d1ade 100644
--- a/third_party/WebKit/Source/platform/scheduler/test/fake_web_task_runner.cc
+++ b/third_party/WebKit/Source/platform/scheduler/test/fake_web_task_runner.cc
@@ -68,17 +68,6 @@
   data_->time_ = new_time;
 }
 
-void FakeWebTaskRunner::postTask(const WebTraceLocation&, Task*) {
-  NOTREACHED();
-}
-
-void FakeWebTaskRunner::postDelayedTask(const WebTraceLocation&,
-                                        Task* task,
-                                        double) {
-  data_->task_queue_.push_back(
-      base::Bind(&WebTaskRunner::Task::run, base::Owned(task)));
-}
-
 void FakeWebTaskRunner::postDelayedTask(const WebTraceLocation&,
                                         const base::Closure& closure,
                                         double) {
diff --git a/third_party/WebKit/Source/platform/scheduler/test/fake_web_task_runner.h b/third_party/WebKit/Source/platform/scheduler/test/fake_web_task_runner.h
index 4a6c435..2753d2b2 100644
--- a/third_party/WebKit/Source/platform/scheduler/test/fake_web_task_runner.h
+++ b/third_party/WebKit/Source/platform/scheduler/test/fake_web_task_runner.h
@@ -25,8 +25,6 @@
   void setTime(double new_time);
 
   // WebTaskRunner implementation:
-  void postTask(const WebTraceLocation&, Task*) override;
-  void postDelayedTask(const WebTraceLocation&, Task*, double) override;
   void postDelayedTask(const WebTraceLocation&,
                        const base::Closure&,
                        double) override;
diff --git a/third_party/WebKit/Source/platform/testing/PaintPropertyTestHelpers.h b/third_party/WebKit/Source/platform/testing/PaintPropertyTestHelpers.h
new file mode 100644
index 0000000..8a74c39
--- /dev/null
+++ b/third_party/WebKit/Source/platform/testing/PaintPropertyTestHelpers.h
@@ -0,0 +1,36 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "platform/graphics/paint/ClipPaintPropertyNode.h"
+#include "platform/graphics/paint/EffectPaintPropertyNode.h"
+#include "platform/graphics/paint/PaintChunkProperties.h"
+#include "platform/graphics/paint/ScrollPaintPropertyNode.h"
+#include "platform/graphics/paint/TransformPaintPropertyNode.h"
+
+namespace blink {
+namespace testing {
+
+static inline PassRefPtr<EffectPaintPropertyNode> createOpacityOnlyEffect(
+    PassRefPtr<const EffectPaintPropertyNode> parent,
+    float opacity) {
+  RefPtr<TransformPaintPropertyNode> localTransformSpace =
+      const_cast<TransformPaintPropertyNode*>(parent->localTransformSpace());
+  RefPtr<ClipPaintPropertyNode> outputClip =
+      const_cast<ClipPaintPropertyNode*>(parent->outputClip());
+  return EffectPaintPropertyNode::create(
+      std::move(parent), std::move(localTransformSpace), std::move(outputClip),
+      CompositorFilterOperations(), opacity);
+}
+
+static inline PaintChunkProperties defaultPaintChunkProperties() {
+  PaintChunkProperties defaultProperties;
+  defaultProperties.transform = TransformPaintPropertyNode::root();
+  defaultProperties.clip = ClipPaintPropertyNode::root();
+  defaultProperties.effect = EffectPaintPropertyNode::root();
+  defaultProperties.scroll = ScrollPaintPropertyNode::root();
+  return defaultProperties;
+}
+
+}  // namespace testing
+}  // namespace blink
diff --git a/third_party/WebKit/Source/platform/testing/TestingPlatformSupport.h b/third_party/WebKit/Source/platform/testing/TestingPlatformSupport.h
index 938dbb4..0b9e0e9 100644
--- a/third_party/WebKit/Source/platform/testing/TestingPlatformSupport.h
+++ b/third_party/WebKit/Source/platform/testing/TestingPlatformSupport.h
@@ -108,9 +108,6 @@
   void resumeTimerQueue() override {}
   void addPendingNavigation(WebScheduler::NavigatingFrameType) override {}
   void removePendingNavigation(WebScheduler::NavigatingFrameType) override {}
-
- private:
-  WTF::Deque<std::unique_ptr<WebTaskRunner::Task>> m_tasks;
 };
 
 class TestingPlatformSupport : public Platform {
diff --git a/third_party/WebKit/Source/web/SharedWorkerRepositoryClientImpl.cpp b/third_party/WebKit/Source/web/SharedWorkerRepositoryClientImpl.cpp
index 13f4441..7ed68f5 100644
--- a/third_party/WebKit/Source/web/SharedWorkerRepositoryClientImpl.cpp
+++ b/third_party/WebKit/Source/web/SharedWorkerRepositoryClientImpl.cpp
@@ -144,9 +144,7 @@
   }
 
   WebWorkerCreationError creationError;
-  String unusedSecureContextError;
-  bool isSecureContext =
-      worker->getExecutionContext()->isSecureContext(unusedSecureContextError);
+  bool isSecureContext = worker->getExecutionContext()->isSecureContext();
   std::unique_ptr<WebSharedWorkerConnector> webWorkerConnector =
       WTF::wrapUnique(m_client->createSharedWorkerConnector(
           url, name, getId(document), header, headerType,
diff --git a/third_party/WebKit/Source/web/WebDocument.cpp b/third_party/WebKit/Source/web/WebDocument.cpp
index 78d64db8..26f088f 100644
--- a/third_party/WebKit/Source/web/WebDocument.cpp
+++ b/third_party/WebKit/Source/web/WebDocument.cpp
@@ -79,14 +79,9 @@
   return WebSecurityOrigin(constUnwrap<Document>()->getSecurityOrigin());
 }
 
-bool WebDocument::isSecureContext(WebString& errorMessage) const {
+bool WebDocument::isSecureContext() const {
   const Document* document = constUnwrap<Document>();
-  if (!document)
-    return false;
-  String message;
-  bool result = document->isSecureContext(message);
-  errorMessage = message;
-  return result;
+  return document && document->isSecureContext();
 }
 
 WebString WebDocument::encoding() const {
diff --git a/third_party/WebKit/Source/web/WebHistoryItem.cpp b/third_party/WebKit/Source/web/WebHistoryItem.cpp
index 70e5a20b..08fafab 100644
--- a/third_party/WebKit/Source/web/WebHistoryItem.cpp
+++ b/third_party/WebKit/Source/web/WebHistoryItem.cpp
@@ -113,8 +113,8 @@
   m_private->setPageScaleFactor(scale);
 }
 
-WebVector<WebString> WebHistoryItem::documentState() const {
-  return m_private->documentState();
+WebVector<WebString> WebHistoryItem::getDocumentState() const {
+  return m_private->getDocumentState();
 }
 
 void WebHistoryItem::setDocumentState(const WebVector<WebString>& state) {
diff --git a/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp b/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp
index d49378a..97bbe6a 100644
--- a/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp
+++ b/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp
@@ -941,7 +941,7 @@
 }
 
 unsigned WebLocalFrameImpl::unloadListenerCount() const {
-  return frame()->localDOMWindow()->pendingUnloadEventListeners();
+  return frame()->domWindow()->pendingUnloadEventListeners();
 }
 
 void WebLocalFrameImpl::replaceSelection(const WebString& text) {
@@ -2062,7 +2062,7 @@
 
   // Legacy window.orientation API
   if (RuntimeEnabledFeatures::orientationEventEnabled() && frame()->domWindow())
-    frame()->localDOMWindow()->sendOrientationChangeEvent();
+    frame()->domWindow()->sendOrientationChangeEvent();
 }
 
 void WebLocalFrameImpl::didCallAddSearchProvider() {
@@ -2179,7 +2179,7 @@
     const WebSecurityOrigin& intendedTargetOrigin,
     const WebDOMEvent& event) {
   DCHECK(!event.isNull());
-  frame()->localDOMWindow()->dispatchMessageEventWithOriginCheck(
+  frame()->domWindow()->dispatchMessageEventWithOriginCheck(
       intendedTargetOrigin.get(), event,
       SourceLocation::create(String(), 0, 0, nullptr));
 }
diff --git a/third_party/WebKit/Source/web/WebPagePopupImpl.cpp b/third_party/WebKit/Source/web/WebPagePopupImpl.cpp
index 86336bd70..f7554080 100644
--- a/third_party/WebKit/Source/web/WebPagePopupImpl.cpp
+++ b/third_party/WebKit/Source/web/WebPagePopupImpl.cpp
@@ -304,7 +304,7 @@
           m_popupClient->ownerElement().document().existingAXObjectCache())
     cache->childrenChanged(&m_popupClient->ownerElement());
 
-  DCHECK(frame->localDOMWindow());
+  DCHECK(frame->domWindow());
   PagePopupSupplement::install(*frame, *this, m_popupClient);
   DCHECK_EQ(m_popupClient->ownerElement().document().existingAXObjectCache(),
             frame->document()->existingAXObjectCache());
@@ -322,8 +322,7 @@
   if (!m_page)
     return;
   ScriptForbiddenScope::AllowUserAgentScript allowScript;
-  if (LocalDOMWindow* window =
-          toLocalFrame(m_page->mainFrame())->localDOMWindow())
+  if (LocalDOMWindow* window = toLocalFrame(m_page->mainFrame())->domWindow())
     window->dispatchEvent(MessageEvent::create(message));
 }
 
@@ -545,7 +544,7 @@
 }
 
 LocalDOMWindow* WebPagePopupImpl::window() {
-  return m_page->deprecatedLocalMainFrame()->localDOMWindow();
+  return m_page->deprecatedLocalMainFrame()->domWindow();
 }
 
 void WebPagePopupImpl::layoutAndPaintAsync(
diff --git a/third_party/WebKit/Source/web/WebUserGestureIndicator.cpp b/third_party/WebKit/Source/web/WebUserGestureIndicator.cpp
index e1eaf1b..9e206ee 100644
--- a/third_party/WebKit/Source/web/WebUserGestureIndicator.cpp
+++ b/third_party/WebKit/Source/web/WebUserGestureIndicator.cpp
@@ -40,8 +40,15 @@
   return UserGestureIndicator::processingUserGesture();
 }
 
+bool WebUserGestureIndicator::isProcessingUserGestureThreadSafe() {
+  return UserGestureIndicator::processingUserGestureThreadSafe();
+}
+
+// TODO(csharrison): consumeUserGesture() and currentUserGestureToken() use
+// the thread-safe API, which many callers probably do not need. Consider
+// updating them if they are in any sort of critical path or called often.
 bool WebUserGestureIndicator::consumeUserGesture() {
-  return UserGestureIndicator::consumeUserGesture();
+  return UserGestureIndicator::consumeUserGestureThreadSafe();
 }
 
 bool WebUserGestureIndicator::processedUserGestureSinceLoad(
@@ -51,7 +58,7 @@
 }
 
 WebUserGestureToken WebUserGestureIndicator::currentUserGestureToken() {
-  return WebUserGestureToken(UserGestureIndicator::currentToken());
+  return WebUserGestureToken(UserGestureIndicator::currentTokenThreadSafe());
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/web/tests/BrowserControlsTest.cpp b/third_party/WebKit/Source/web/tests/BrowserControlsTest.cpp
index 330ab6e1..d8099ba 100644
--- a/third_party/WebKit/Source/web/tests/BrowserControlsTest.cpp
+++ b/third_party/WebKit/Source/web/tests/BrowserControlsTest.cpp
@@ -169,7 +169,9 @@
   webView->handleInputEvent(
       generateEvent(WebInputEvent::GestureScrollUpdate, 0, -25.f));
   EXPECT_FLOAT_EQ(25.f, webView->browserControls().contentOffset());
-  EXPECT_SIZE_EQ(ScrollOffset(0, 0), frame()->view()->getScrollOffset());
+  EXPECT_SIZE_EQ(
+      ScrollOffset(0, 0),
+      frame()->view()->layoutViewportScrollableArea()->getScrollOffset());
 
   // Browser controls should consume 25px and become hidden. Excess scroll
   // should be
@@ -177,13 +179,17 @@
   webView->handleInputEvent(
       generateEvent(WebInputEvent::GestureScrollUpdate, 0, -40.f));
   EXPECT_FLOAT_EQ(0.f, webView->browserControls().contentOffset());
-  EXPECT_SIZE_EQ(ScrollOffset(0, 15), frame()->view()->getScrollOffset());
+  EXPECT_SIZE_EQ(
+      ScrollOffset(0, 15),
+      frame()->view()->layoutViewportScrollableArea()->getScrollOffset());
 
   // Only page should consume scroll
   webView->handleInputEvent(
       generateEvent(WebInputEvent::GestureScrollUpdate, 0, -20.f));
   EXPECT_FLOAT_EQ(0.f, webView->browserControls().contentOffset());
-  EXPECT_SIZE_EQ(ScrollOffset(0, 35), frame()->view()->getScrollOffset());
+  EXPECT_SIZE_EQ(
+      ScrollOffset(0, 35),
+      frame()->view()->layoutViewportScrollableArea()->getScrollOffset());
 }
 
 // Scrolling up should show browser controls.
@@ -199,12 +205,16 @@
   webView->handleInputEvent(
       generateEvent(WebInputEvent::GestureScrollUpdate, 0, 10.f));
   EXPECT_FLOAT_EQ(10.f, webView->browserControls().contentOffset());
-  EXPECT_SIZE_EQ(ScrollOffset(0, 0), frame()->view()->getScrollOffset());
+  EXPECT_SIZE_EQ(
+      ScrollOffset(0, 0),
+      frame()->view()->layoutViewportScrollableArea()->getScrollOffset());
 
   webView->handleInputEvent(
       generateEvent(WebInputEvent::GestureScrollUpdate, 0, 50.f));
   EXPECT_FLOAT_EQ(50.f, webView->browserControls().contentOffset());
-  EXPECT_SIZE_EQ(ScrollOffset(0, 0), frame()->view()->getScrollOffset());
+  EXPECT_SIZE_EQ(
+      ScrollOffset(0, 0),
+      frame()->view()->layoutViewportScrollableArea()->getScrollOffset());
 }
 
 // Scrolling up after previous scroll downs should cause browser controls to be
@@ -225,32 +235,42 @@
   webView->handleInputEvent(
       generateEvent(WebInputEvent::GestureScrollUpdate, 0, -150.f));
   EXPECT_FLOAT_EQ(0.f, webView->browserControls().contentOffset());
-  EXPECT_SIZE_EQ(ScrollOffset(0, 200), frame()->view()->getScrollOffset());
+  EXPECT_SIZE_EQ(
+      ScrollOffset(0, 200),
+      frame()->view()->layoutViewportScrollableArea()->getScrollOffset());
 
   // Scroll up and ensure the browser controls does not move until we recover
   // 100px previously scrolled.
   webView->handleInputEvent(
       generateEvent(WebInputEvent::GestureScrollUpdate, 0, 40.f));
   EXPECT_FLOAT_EQ(0.f, webView->browserControls().contentOffset());
-  EXPECT_SIZE_EQ(ScrollOffset(0, 160), frame()->view()->getScrollOffset());
+  EXPECT_SIZE_EQ(
+      ScrollOffset(0, 160),
+      frame()->view()->layoutViewportScrollableArea()->getScrollOffset());
 
   webView->handleInputEvent(
       generateEvent(WebInputEvent::GestureScrollUpdate, 0, 60.f));
   EXPECT_FLOAT_EQ(0.f, webView->browserControls().contentOffset());
-  EXPECT_SIZE_EQ(ScrollOffset(0, 100), frame()->view()->getScrollOffset());
+  EXPECT_SIZE_EQ(
+      ScrollOffset(0, 100),
+      frame()->view()->layoutViewportScrollableArea()->getScrollOffset());
 
   // Now we have hit the threshold so further scroll up should be consumed by
   // browser controls.
   webView->handleInputEvent(
       generateEvent(WebInputEvent::GestureScrollUpdate, 0, 30.f));
   EXPECT_FLOAT_EQ(30.f, webView->browserControls().contentOffset());
-  EXPECT_SIZE_EQ(ScrollOffset(0, 100), frame()->view()->getScrollOffset());
+  EXPECT_SIZE_EQ(
+      ScrollOffset(0, 100),
+      frame()->view()->layoutViewportScrollableArea()->getScrollOffset());
 
   // Once top control is fully shown then page should consume any excess scroll.
   webView->handleInputEvent(
       generateEvent(WebInputEvent::GestureScrollUpdate, 0, 70.f));
   EXPECT_FLOAT_EQ(50.f, webView->browserControls().contentOffset());
-  EXPECT_SIZE_EQ(ScrollOffset(0, 50), frame()->view()->getScrollOffset());
+  EXPECT_SIZE_EQ(
+      ScrollOffset(0, 50),
+      frame()->view()->layoutViewportScrollableArea()->getScrollOffset());
 }
 
 // Scrolling down should always cause visible browser controls to start hiding
@@ -271,18 +291,24 @@
   webView->handleInputEvent(
       generateEvent(WebInputEvent::GestureScrollUpdate, 0, 100.f));
   EXPECT_FLOAT_EQ(50.f, webView->browserControls().contentOffset());
-  EXPECT_SIZE_EQ(ScrollOffset(0, 50), frame()->view()->getScrollOffset());
+  EXPECT_SIZE_EQ(
+      ScrollOffset(0, 50),
+      frame()->view()->layoutViewportScrollableArea()->getScrollOffset());
 
   // Scroll down and ensure only browser controls is scrolled
   webView->handleInputEvent(
       generateEvent(WebInputEvent::GestureScrollUpdate, 0, -40.f));
   EXPECT_FLOAT_EQ(10.f, webView->browserControls().contentOffset());
-  EXPECT_SIZE_EQ(ScrollOffset(0, 50), frame()->view()->getScrollOffset());
+  EXPECT_SIZE_EQ(
+      ScrollOffset(0, 50),
+      frame()->view()->layoutViewportScrollableArea()->getScrollOffset());
 
   webView->handleInputEvent(
       generateEvent(WebInputEvent::GestureScrollUpdate, 0, -60.f));
   EXPECT_FLOAT_EQ(0.f, webView->browserControls().contentOffset());
-  EXPECT_SIZE_EQ(ScrollOffset(0, 100), frame()->view()->getScrollOffset());
+  EXPECT_SIZE_EQ(
+      ScrollOffset(0, 100),
+      frame()->view()->layoutViewportScrollableArea()->getScrollOffset());
 }
 
 // Browser controls should not consume horizontal scroll.
@@ -299,12 +325,16 @@
   webView->handleInputEvent(
       generateEvent(WebInputEvent::GestureScrollUpdate, -110.f, -100.f));
   EXPECT_FLOAT_EQ(0.f, webView->browserControls().contentOffset());
-  EXPECT_SIZE_EQ(ScrollOffset(110, 50), frame()->view()->getScrollOffset());
+  EXPECT_SIZE_EQ(
+      ScrollOffset(110, 50),
+      frame()->view()->layoutViewportScrollableArea()->getScrollOffset());
 
   webView->handleInputEvent(
       generateEvent(WebInputEvent::GestureScrollUpdate, -40.f, 0));
   EXPECT_FLOAT_EQ(0.f, webView->browserControls().contentOffset());
-  EXPECT_SIZE_EQ(ScrollOffset(150, 50), frame()->view()->getScrollOffset());
+  EXPECT_SIZE_EQ(
+      ScrollOffset(150, 50),
+      frame()->view()->layoutViewportScrollableArea()->getScrollOffset());
 }
 
 // Page scale should not impact browser controls scrolling
@@ -396,35 +426,47 @@
   // main frame should not scroll.
   verticalScroll(-800.f);
   EXPECT_FLOAT_EQ(50.f, webView->browserControls().contentOffset());
-  EXPECT_SIZE_EQ(ScrollOffset(0, 50), frame()->view()->getScrollOffset());
+  EXPECT_SIZE_EQ(
+      ScrollOffset(0, 50),
+      frame()->view()->layoutViewportScrollableArea()->getScrollOffset());
 
   // Continued scroll down should start hiding browser controls but main frame
   // should not scroll.
   verticalScroll(-40.f);
   EXPECT_FLOAT_EQ(10.f, webView->browserControls().contentOffset());
-  EXPECT_SIZE_EQ(ScrollOffset(0, 50), frame()->view()->getScrollOffset());
+  EXPECT_SIZE_EQ(
+      ScrollOffset(0, 50),
+      frame()->view()->layoutViewportScrollableArea()->getScrollOffset());
 
   // Continued scroll down should scroll down the main frame
   verticalScroll(-40.f);
   EXPECT_FLOAT_EQ(0.f, webView->browserControls().contentOffset());
-  EXPECT_SIZE_EQ(ScrollOffset(0, 80), frame()->view()->getScrollOffset());
+  EXPECT_SIZE_EQ(
+      ScrollOffset(0, 80),
+      frame()->view()->layoutViewportScrollableArea()->getScrollOffset());
 
   // Test scroll up
   // scroll up should scroll overflow div first
   verticalScroll(800.f);
   EXPECT_FLOAT_EQ(0.f, webView->browserControls().contentOffset());
-  EXPECT_SIZE_EQ(ScrollOffset(0, 80), frame()->view()->getScrollOffset());
+  EXPECT_SIZE_EQ(
+      ScrollOffset(0, 80),
+      frame()->view()->layoutViewportScrollableArea()->getScrollOffset());
 
   // Continued scroll up should start showing browser controls but main frame
   // should not scroll.
   verticalScroll(40.f);
   EXPECT_FLOAT_EQ(40.f, webView->browserControls().contentOffset());
-  EXPECT_SIZE_EQ(ScrollOffset(0, 80), frame()->view()->getScrollOffset());
+  EXPECT_SIZE_EQ(
+      ScrollOffset(0, 80),
+      frame()->view()->layoutViewportScrollableArea()->getScrollOffset());
 
   // Continued scroll down up scroll up the main frame
   verticalScroll(40.f);
   EXPECT_FLOAT_EQ(50.f, webView->browserControls().contentOffset());
-  EXPECT_SIZE_EQ(ScrollOffset(0, 50), frame()->view()->getScrollOffset());
+  EXPECT_SIZE_EQ(
+      ScrollOffset(0, 50),
+      frame()->view()->layoutViewportScrollableArea()->getScrollOffset());
 }
 
 // Scrollable iframes should scroll before browser controls
@@ -440,35 +482,47 @@
   // frame should not scroll.
   verticalScroll(-800.f);
   EXPECT_FLOAT_EQ(50.f, webView->browserControls().contentOffset());
-  EXPECT_SIZE_EQ(ScrollOffset(0, 50), frame()->view()->getScrollOffset());
+  EXPECT_SIZE_EQ(
+      ScrollOffset(0, 50),
+      frame()->view()->layoutViewportScrollableArea()->getScrollOffset());
 
   // Continued scroll down should start hiding browser controls but main frame
   // should not scroll.
   verticalScroll(-40.f);
   EXPECT_FLOAT_EQ(10.f, webView->browserControls().contentOffset());
-  EXPECT_SIZE_EQ(ScrollOffset(0, 50), frame()->view()->getScrollOffset());
+  EXPECT_SIZE_EQ(
+      ScrollOffset(0, 50),
+      frame()->view()->layoutViewportScrollableArea()->getScrollOffset());
 
   // Continued scroll down should scroll down the main frame
   verticalScroll(-40.f);
   EXPECT_FLOAT_EQ(0.f, webView->browserControls().contentOffset());
-  EXPECT_SIZE_EQ(ScrollOffset(0, 80), frame()->view()->getScrollOffset());
+  EXPECT_SIZE_EQ(
+      ScrollOffset(0, 80),
+      frame()->view()->layoutViewportScrollableArea()->getScrollOffset());
 
   // Test scroll up
   // scroll up should scroll iframe first
   verticalScroll(800.f);
   EXPECT_FLOAT_EQ(0.f, webView->browserControls().contentOffset());
-  EXPECT_SIZE_EQ(ScrollOffset(0, 80), frame()->view()->getScrollOffset());
+  EXPECT_SIZE_EQ(
+      ScrollOffset(0, 80),
+      frame()->view()->layoutViewportScrollableArea()->getScrollOffset());
 
   // Continued scroll up should start showing browser controls but main frame
   // should not scroll.
   verticalScroll(40.f);
   EXPECT_FLOAT_EQ(40.f, webView->browserControls().contentOffset());
-  EXPECT_SIZE_EQ(ScrollOffset(0, 80), frame()->view()->getScrollOffset());
+  EXPECT_SIZE_EQ(
+      ScrollOffset(0, 80),
+      frame()->view()->layoutViewportScrollableArea()->getScrollOffset());
 
   // Continued scroll down up scroll up the main frame
   verticalScroll(40.f);
   EXPECT_FLOAT_EQ(50.f, webView->browserControls().contentOffset());
-  EXPECT_SIZE_EQ(ScrollOffset(0, 50), frame()->view()->getScrollOffset());
+  EXPECT_SIZE_EQ(
+      ScrollOffset(0, 50),
+      frame()->view()->layoutViewportScrollableArea()->getScrollOffset());
 }
 
 // Browser controls visibility should remain consistent when height is changed.
@@ -505,11 +559,15 @@
 
   verticalScroll(20.f);
   EXPECT_FLOAT_EQ(0.f, webView->browserControls().contentOffset());
-  EXPECT_SIZE_EQ(ScrollOffset(0, 80), frame()->view()->getScrollOffset());
+  EXPECT_SIZE_EQ(
+      ScrollOffset(0, 80),
+      frame()->view()->layoutViewportScrollableArea()->getScrollOffset());
 
   verticalScroll(-30.f);
   EXPECT_FLOAT_EQ(0.f, webView->browserControls().contentOffset());
-  EXPECT_SIZE_EQ(ScrollOffset(0, 110), frame()->view()->getScrollOffset());
+  EXPECT_SIZE_EQ(
+      ScrollOffset(0, 110),
+      frame()->view()->layoutViewportScrollableArea()->getScrollOffset());
 
   webView->browserControls().setShownRatio(1);
   EXPECT_FLOAT_EQ(0.f, webView->browserControls().contentOffset());
@@ -564,7 +622,9 @@
   // Only shown state is permitted so controls cannot hide
   verticalScroll(-20.f);
   EXPECT_FLOAT_EQ(50, webView->browserControls().contentOffset());
-  EXPECT_SIZE_EQ(ScrollOffset(0, 120), frame()->view()->getScrollOffset());
+  EXPECT_SIZE_EQ(
+      ScrollOffset(0, 120),
+      frame()->view()->layoutViewportScrollableArea()->getScrollOffset());
 
   // Setting permitted state should change content offset to match the
   // constraint.
@@ -575,7 +635,9 @@
   // Only hidden state is permitted so controls cannot show
   verticalScroll(30.f);
   EXPECT_FLOAT_EQ(0, webView->browserControls().contentOffset());
-  EXPECT_SIZE_EQ(ScrollOffset(0, 90), frame()->view()->getScrollOffset());
+  EXPECT_SIZE_EQ(
+      ScrollOffset(0, 90),
+      frame()->view()->layoutViewportScrollableArea()->getScrollOffset());
 
   // Setting permitted state to "both" should not change content offset.
   webView->updateBrowserControlsState(WebBrowserControlsBoth,
@@ -585,11 +647,15 @@
   // Both states are permitted so controls can either show or hide
   verticalScroll(50.f);
   EXPECT_FLOAT_EQ(50, webView->browserControls().contentOffset());
-  EXPECT_SIZE_EQ(ScrollOffset(0, 90), frame()->view()->getScrollOffset());
+  EXPECT_SIZE_EQ(
+      ScrollOffset(0, 90),
+      frame()->view()->layoutViewportScrollableArea()->getScrollOffset());
 
   verticalScroll(-50.f);
   EXPECT_FLOAT_EQ(0, webView->browserControls().contentOffset());
-  EXPECT_SIZE_EQ(ScrollOffset(0, 90), frame()->view()->getScrollOffset());
+  EXPECT_SIZE_EQ(
+      ScrollOffset(0, 90),
+      frame()->view()->layoutViewportScrollableArea()->getScrollOffset());
 
   // Setting permitted state to "both" should not change an in-flight offset.
   verticalScroll(20.f);
diff --git a/third_party/WebKit/Source/web/tests/ScreenWakeLockTest.cpp b/third_party/WebKit/Source/web/tests/ScreenWakeLockTest.cpp
index 6c46408..99724999 100644
--- a/third_party/WebKit/Source/web/tests/ScreenWakeLockTest.cpp
+++ b/third_party/WebKit/Source/web/tests/ScreenWakeLockTest.cpp
@@ -109,8 +109,8 @@
 
   blink::Screen* screen() {
     DCHECK(frame());
-    DCHECK(frame()->localDOMWindow());
-    return frame()->localDOMWindow()->screen();
+    DCHECK(frame()->domWindow());
+    return frame()->domWindow()->screen();
   }
 
   bool screenKeepAwake() {
diff --git a/third_party/WebKit/Source/web/tests/VisualViewportTest.cpp b/third_party/WebKit/Source/web/tests/VisualViewportTest.cpp
index 354c64b..1a891323 100644
--- a/third_party/WebKit/Source/web/tests/VisualViewportTest.cpp
+++ b/third_party/WebKit/Source/web/tests/VisualViewportTest.cpp
@@ -1749,8 +1749,7 @@
   // body element as the viewport and don't apply scrolling to the HTML element.
   RuntimeEnabledFeatures::setScrollTopLeftInteropEnabled(false);
 
-  LocalDOMWindow* window =
-      webViewImpl()->mainFrameImpl()->frame()->localDOMWindow();
+  LocalDOMWindow* window = webViewImpl()->mainFrameImpl()->frame()->domWindow();
   window->scrollTo(100, 150);
   EXPECT_EQ(100, window->scrollX());
   EXPECT_EQ(150, window->scrollY());
diff --git a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
index 018aea3..de74b3f 100644
--- a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
+++ b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
@@ -1001,7 +1001,7 @@
   NonThrowableExceptionState exceptionState;
   MessagePortArray messagePorts;
   frame->domWindow()->postMessage(SerializedScriptValue::serialize("message"),
-                                  messagePorts, "*", frame->localDOMWindow(),
+                                  messagePorts, "*", frame->domWindow(),
                                   exceptionState);
   webViewHelper.reset();
   EXPECT_FALSE(exceptionState.hadException());
@@ -9144,7 +9144,7 @@
   ASSERT_TRUE(mainFrame()->isWebLocalFrame());
   ASSERT_TRUE(mainFrame()->firstChild()->isWebRemoteFrame());
   LocalDOMWindow* mainWindow =
-      toWebLocalFrameImpl(mainFrame())->frame()->localDOMWindow();
+      toWebLocalFrameImpl(mainFrame())->frame()->domWindow();
 
   KURL destination = toKURL("data:text/html:destination");
   mainWindow->open(destination.getString(), "frame1", "", mainWindow,
diff --git a/third_party/WebKit/Tools/Scripts/run-bindings-tests b/third_party/WebKit/Tools/Scripts/run-bindings-tests
index 6f4ab44..ea6a6ad 100755
--- a/third_party/WebKit/Tools/Scripts/run-bindings-tests
+++ b/third_party/WebKit/Tools/Scripts/run-bindings-tests
@@ -26,7 +26,10 @@
 import sys
 
 from webkitpy.bindings.bindings_tests import run_bindings_tests
+from webkitpy.common import webkit_finder
+webkit_finder.add_typ_dir_to_sys_path()
 
+import typ
 
 def main(argv):
     """Runs Blink bindings IDL compiler on test IDL files and compares the
@@ -36,15 +39,38 @@
     (this is automatically done as a presubmit script),
     and submit changes to the test results in the same patch.
     This makes it easier to track and review changes in generated code.
-
-    Options:
-       --reset-results: Overwrites reference files with the generated results.
-       --verbose: Show output on success and logging messages (not just failure)
     """
-    reset_results = '--reset-results' in argv
-    verbose = '--verbose' in argv
+    argument_parser = typ.ArgumentParser()
+    argument_parser.add_argument('--reset-results',
+        default=False,
+        action='store_true',
+        help='Overwrites reference files with the generated results.')
+    argument_parser.add_argument('--skip-unit-tests',
+        default=False,
+        action='store_true',
+        help='Skip running unit tests (only run reference tests).')
+    argument_parser.add_argument('--skip-reference-tests',
+        default=False,
+        action='store_true',
+        help='Skip running reference tests (only run unit tests).')
 
-    return run_bindings_tests(reset_results, verbose)
+    # First, run bindings unit tests.
+    runner = typ.Runner()
+    runner.parse_args(argument_parser, argv[1:])
+    args = runner.args
+    if argument_parser.exit_status is not None:
+        return argument_parser.exit_status
+    runner.args.top_level_dir = webkit_finder.get_bindings_scripts_dir()
+    if not args.skip_unit_tests:
+        return_code, _, _ = runner.run()
+        if return_code != 0:
+            return return_code
+
+    if args.skip_reference_tests:
+        return 0
+
+    # Now run the bindings end-to-end tests.
+    return run_bindings_tests(args.reset_results, args.verbose)
 
 
 if __name__ == '__main__':
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/controllers/layout_test_runner.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/controllers/layout_test_runner.py
index b46e9c2..acabb22 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/controllers/layout_test_runner.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/controllers/layout_test_runner.py
@@ -286,7 +286,7 @@
         self._update_test_input(test_input)
         start = time.time()
 
-        _log.debug("%s %s started", self._name, test_input.test_name)
+        # TODO(qyearsley): Re-add logging if it doesn't create too much load (crbug.com/673207).
         self._caller.post('started_test', test_input)
         result = single_test_runner.run_single_test(
             self._port, self._options, self._results_directory, self._name,
diff --git a/third_party/WebKit/public/web/WebDocument.h b/third_party/WebKit/public/web/WebDocument.h
index 4c72430..486e11ce 100644
--- a/third_party/WebKit/public/web/WebDocument.h
+++ b/third_party/WebKit/public/web/WebDocument.h
@@ -72,7 +72,7 @@
   BLINK_EXPORT WebURL url() const;
   // Note: Security checks should use the getSecurityOrigin(), not url().
   BLINK_EXPORT WebSecurityOrigin getSecurityOrigin() const;
-  BLINK_EXPORT bool isSecureContext(WebString& errorMessage) const;
+  BLINK_EXPORT bool isSecureContext() const;
 
   BLINK_EXPORT WebString encoding() const;
   BLINK_EXPORT WebString contentLanguage() const;
diff --git a/third_party/WebKit/public/web/WebHistoryItem.h b/third_party/WebKit/public/web/WebHistoryItem.h
index 070e7ed9..2b91f34 100644
--- a/third_party/WebKit/public/web/WebHistoryItem.h
+++ b/third_party/WebKit/public/web/WebHistoryItem.h
@@ -93,7 +93,7 @@
   BLINK_EXPORT float pageScaleFactor() const;
   BLINK_EXPORT void setPageScaleFactor(float);
 
-  BLINK_EXPORT WebVector<WebString> documentState() const;
+  BLINK_EXPORT WebVector<WebString> getDocumentState() const;
   BLINK_EXPORT void setDocumentState(const WebVector<WebString>&);
 
   BLINK_EXPORT long long itemSequenceNumber() const;
diff --git a/third_party/WebKit/public/web/WebUserGestureIndicator.h b/third_party/WebKit/public/web/WebUserGestureIndicator.h
index 44b1cacb..1c63f2c 100644
--- a/third_party/WebKit/public/web/WebUserGestureIndicator.h
+++ b/third_party/WebKit/public/web/WebUserGestureIndicator.h
@@ -40,8 +40,13 @@
 
 class WebUserGestureIndicator {
  public:
-  // Returns true if a user gesture is currently being processed.
+  // Returns true if a user gesture is currently being processed. Must be called
+  // on the main thread.
   BLINK_EXPORT static bool isProcessingUserGesture();
+  // Can be called from any thread. Note that this is slower than the non
+  // thread-safe version due to thread id lookups. Prefer the non thread-safe
+  // version for code that will only execute on the main thread.
+  BLINK_EXPORT static bool isProcessingUserGestureThreadSafe();
 
   // Returns true if a consumable gesture exists and has been successfully
   // consumed.
diff --git a/third_party/inspector_protocol/CodeGenerator.py b/third_party/inspector_protocol/CodeGenerator.py
index 8b28d136..1bc9535 100644
--- a/third_party/inspector_protocol/CodeGenerator.py
+++ b/third_party/inspector_protocol/CodeGenerator.py
@@ -440,6 +440,12 @@
         return self.check_options(self.config.protocol.options, domain, event, "include_events", "exclude_events", True)
 
 
+    def generate_type(self, domain, typename):
+        if not self.config.protocol.options:
+            return domain in self.generate_domains
+        return self.check_options(self.config.protocol.options, domain, typename, "include_types", "exclude_types", True)
+
+
     def is_async_command(self, domain, command):
         if not self.config.protocol.options:
             return False
@@ -473,6 +479,10 @@
         return True
 
 
+    def is_imported_dependency(self, domain):
+        return domain in self.generate_domains or domain in self.imported_domains
+
+
 def main():
     jinja_dir, config_file, config = read_config()
 
diff --git a/third_party/inspector_protocol/README.chromium b/third_party/inspector_protocol/README.chromium
index df3ade87..64b757f32 100644
--- a/third_party/inspector_protocol/README.chromium
+++ b/third_party/inspector_protocol/README.chromium
@@ -2,7 +2,7 @@
 Short Name: inspector_protocol
 URL: https://chromium.googlesource.com/deps/inspector_protocol/
 Version: 0
-Revision: c65b17da8a32bc6ab25b4ebbef1008f23c69e7d1
+Revision: 344219890fe40130571f5a5b17f261a654e3b8cc
 License: BSD
 License File: LICENSE
 Security Critical: no
diff --git a/third_party/inspector_protocol/lib/DispatcherBase_cpp.template b/third_party/inspector_protocol/lib/DispatcherBase_cpp.template
index 0d4a305..e9730eb 100644
--- a/third_party/inspector_protocol/lib/DispatcherBase_cpp.template
+++ b/third_party/inspector_protocol/lib/DispatcherBase_cpp.template
@@ -248,7 +248,13 @@
     m_dispatchers[name] = std::move(dispatcher);
 }
 
-DispatchResponse::Status UberDispatcher::dispatch(std::unique_ptr<Value> parsedMessage)
+void UberDispatcher::setupRedirects(const HashMap<String, String>& redirects)
+{
+    for (const auto& pair : redirects)
+        m_redirects[pair.first] = pair.second;
+}
+
+DispatchResponse::Status UberDispatcher::dispatch(std::unique_ptr<Value> parsedMessage, int* outCallId, String* outMethod)
 {
     if (!parsedMessage) {
         reportProtocolErrorTo(m_frontendChannel, DispatchResponse::kParseError, "Message must be a valid JSON");
@@ -263,6 +269,8 @@
     int callId = 0;
     protocol::Value* callIdValue = messageObject->get("id");
     bool success = callIdValue && callIdValue->asInteger(&callId);
+    if (outCallId)
+        *outCallId = callId;
     if (!success) {
         reportProtocolErrorTo(m_frontendChannel, DispatchResponse::kInvalidRequest, "Message must have integer 'id' porperty");
         return DispatchResponse::kError;
@@ -271,11 +279,17 @@
     protocol::Value* methodValue = messageObject->get("method");
     String method;
     success = methodValue && methodValue->asString(&method);
+    if (outMethod)
+        *outMethod = method;
     if (!success) {
         reportProtocolErrorTo(m_frontendChannel, callId, DispatchResponse::kInvalidRequest, "Message must have string 'method' porperty", nullptr);
         return DispatchResponse::kError;
     }
 
+    HashMap<String, String>::iterator redirectIt = m_redirects.find(method);
+    if (redirectIt != m_redirects.end())
+        method = redirectIt->second;
+
     size_t dotIndex = method.find(".");
     if (dotIndex == StringUtil::kNotFound) {
         if (m_fallThroughForNotFound)
diff --git a/third_party/inspector_protocol/lib/DispatcherBase_h.template b/third_party/inspector_protocol/lib/DispatcherBase_h.template
index 3a6069b..5404281 100644
--- a/third_party/inspector_protocol/lib/DispatcherBase_h.template
+++ b/third_party/inspector_protocol/lib/DispatcherBase_h.template
@@ -113,7 +113,8 @@
 public:
     explicit UberDispatcher(FrontendChannel*);
     void registerBackend(const String& name, std::unique_ptr<protocol::DispatcherBase>);
-    DispatchResponse::Status dispatch(std::unique_ptr<Value> message);
+    void setupRedirects(const HashMap<String, String>&);
+    DispatchResponse::Status dispatch(std::unique_ptr<Value> message, int* callId = nullptr, String* method = nullptr);
     FrontendChannel* channel() { return m_frontendChannel; }
     bool fallThroughForNotFound() { return m_fallThroughForNotFound; }
     void setFallThroughForNotFound(bool);
@@ -122,6 +123,7 @@
 private:
     FrontendChannel* m_frontendChannel;
     bool m_fallThroughForNotFound;
+    HashMap<String, String> m_redirects;
     protocol::HashMap<String, std::unique_ptr<protocol::DispatcherBase>> m_dispatchers;
 };
 
diff --git a/third_party/inspector_protocol/templates/TypeBuilder_cpp.template b/third_party/inspector_protocol/templates/TypeBuilder_cpp.template
index 14b55b9..026c1cdb 100644
--- a/third_party/inspector_protocol/templates/TypeBuilder_cpp.template
+++ b/third_party/inspector_protocol/templates/TypeBuilder_cpp.template
@@ -19,6 +19,7 @@
 const char Metainfo::commandPrefix[] = "{{domain.domain}}.";
 const char Metainfo::version[] = "{{domain.version}}";
   {% for type in domain.types %}
+    {% if not protocol.generate_type(domain.domain, type.id) %}{% continue %} {% endif %}
     {% if "enum" in type %}
 
 namespace {{type.id}}Enum {
@@ -200,18 +201,23 @@
         , m_backend(backend)
         , m_fallThroughForNotFound(fallThroughForNotFound) {
   {% for command in domain.commands %}
-    {% if "redirect" in command %}{% continue %}{% endif %}
+    {% if "redirect" in command %}
+      m_redirects["{{domain.domain}}.{{command.name}}"] = "{{command.redirect}}.{{command.name}}";
+      {% continue %}
+    {% endif %}
     {% if not protocol.generate_command(domain.domain, command.name) %}{% continue %}{% endif %}
         m_dispatchMap["{{domain.domain}}.{{command.name}}"] = &DispatcherImpl::{{command.name}};
   {% endfor %}
     }
     ~DispatcherImpl() override { }
     DispatchResponse::Status dispatch(int callId, const String& method, std::unique_ptr<protocol::DictionaryValue> messageObject) override;
+    HashMap<String, String>& redirects() { return m_redirects; }
 
 protected:
     using CallHandler = DispatchResponse::Status (DispatcherImpl::*)(int callId, std::unique_ptr<DictionaryValue> messageObject, ErrorSupport* errors);
     using DispatchMap = protocol::HashMap<String, CallHandler>;
     DispatchMap m_dispatchMap;
+    HashMap<String, String> m_redirects;
 
   {% for command in domain.commands %}
     {% if "redirect" in command %}{% continue %}{% endif %}
@@ -337,9 +343,9 @@
           &out_{{parameter.name}}
         {%- endfor %}
       {% endif %});
-      {% if "returns" in command %}
     if (response.status() == DispatchResponse::kFallThrough)
         return response.status();
+      {% if "returns" in command %}
     std::unique_ptr<protocol::DictionaryValue> result = DictionaryValue::create();
     if (response.status() == DispatchResponse::kSuccess) {
         {% for parameter in command.returns %}
@@ -378,9 +384,11 @@
   {% endfor %}
 
 // static
-void Dispatcher::wire(UberDispatcher* dispatcher, Backend* backend)
+void Dispatcher::wire(UberDispatcher* uber, Backend* backend)
 {
-    dispatcher->registerBackend("{{domain.domain}}", std::unique_ptr<protocol::DispatcherBase>(new DispatcherImpl(dispatcher->channel(), backend, dispatcher->fallThroughForNotFound())));
+    std::unique_ptr<DispatcherImpl> dispatcher(new DispatcherImpl(uber->channel(), backend, uber->fallThroughForNotFound()));
+    uber->setupRedirects(dispatcher->redirects());
+    uber->registerBackend("{{domain.domain}}", std::move(dispatcher));
 }
 
 } // {{domain.domain}}
diff --git a/third_party/inspector_protocol/templates/TypeBuilder_h.template b/third_party/inspector_protocol/templates/TypeBuilder_h.template
index 81dd7f2..681c473 100644
--- a/third_party/inspector_protocol/templates/TypeBuilder_h.template
+++ b/third_party/inspector_protocol/templates/TypeBuilder_h.template
@@ -14,7 +14,9 @@
 // For each imported domain we generate a ValueConversions struct instead of a full domain definition
 // and include Domain::API version from there.
 {% for name in domain.dependencies %}
+  {% if protocol.is_imported_dependency(name) %}
 #include {{format_include(config.protocol.package, name)}}
+  {% endif %}
 {% endfor %}
 {% if protocol.is_exported_domain(domain.domain) %}
 #include {{format_include(config.exported.package, domain.domain)}}
@@ -27,6 +29,7 @@
 
 // ------------- Forward and enum declarations.
   {% for type in domain.types %}
+    {% if not protocol.generate_type(domain.domain, type.id) %}{% continue %}{% endif %}
     {% if type.type == "object" %}
       {% if "properties" in type %}
 // {{type.description}}
@@ -41,6 +44,7 @@
     {% endif %}
   {% endfor %}
   {% for type in domain.types %}
+    {% if not protocol.generate_type(domain.domain, type.id) %}{% continue %}{% endif %}
     {% if "enum" in type %}
 
 namespace {{type.id}}Enum {
@@ -67,6 +71,7 @@
 
 // ------------- Type and builder declarations.
   {% for type in domain.types %}
+    {% if not protocol.generate_type(domain.domain, type.id) %}{% continue %}{% endif %}
     {% if not (type.type == "object") or not ("properties" in type) %}{% continue %}{% endif %}
 
 // {{type.description}}
diff --git a/third_party/wayland-protocols/include/protocol/keyboard-configuration-unstable-v1-client-protocol.h b/third_party/wayland-protocols/include/protocol/keyboard-configuration-unstable-v1-client-protocol.h
index e931bfbf..5939b44 100644
--- a/third_party/wayland-protocols/include/protocol/keyboard-configuration-unstable-v1-client-protocol.h
+++ b/third_party/wayland-protocols/include/protocol/keyboard-configuration-unstable-v1-client-protocol.h
@@ -96,6 +96,16 @@
  */
 extern const struct wl_interface zcr_keyboard_device_configuration_v1_interface;
 
+#ifndef ZCR_KEYBOARD_CONFIGURATION_V1_ERROR_ENUM
+#define ZCR_KEYBOARD_CONFIGURATION_V1_ERROR_ENUM
+enum zcr_keyboard_configuration_v1_error {
+	/**
+	 * the keyboard already has a device configuration object associated
+	 */
+	ZCR_KEYBOARD_CONFIGURATION_V1_ERROR_DEVICE_CONFIGURATION_EXISTS = 0,
+};
+#endif /* ZCR_KEYBOARD_CONFIGURATION_V1_ERROR_ENUM */
+
 #define ZCR_KEYBOARD_CONFIGURATION_V1_GET_KEYBOARD_DEVICE_CONFIGURATION	0
 
 /**
@@ -135,6 +145,9 @@
  *
  * Create keyboard_device_configuration object.
  * See zcr_keyboard_device_configuration interface for details.
+ * If the given wl_keyboard object already has a device configuration
+ * object associated, the keyboard_device_configuration_exists protocol
+ * error is raised.
  */
 static inline struct zcr_keyboard_device_configuration_v1 *
 zcr_keyboard_configuration_v1_get_keyboard_device_configuration(struct zcr_keyboard_configuration_v1 *zcr_keyboard_configuration_v1, struct wl_keyboard *keyboard)
diff --git a/third_party/wayland-protocols/include/protocol/keyboard-configuration-unstable-v1-server-protocol.h b/third_party/wayland-protocols/include/protocol/keyboard-configuration-unstable-v1-server-protocol.h
index 3eda503..5dbb81e5 100644
--- a/third_party/wayland-protocols/include/protocol/keyboard-configuration-unstable-v1-server-protocol.h
+++ b/third_party/wayland-protocols/include/protocol/keyboard-configuration-unstable-v1-server-protocol.h
@@ -99,6 +99,16 @@
  */
 extern const struct wl_interface zcr_keyboard_device_configuration_v1_interface;
 
+#ifndef ZCR_KEYBOARD_CONFIGURATION_V1_ERROR_ENUM
+#define ZCR_KEYBOARD_CONFIGURATION_V1_ERROR_ENUM
+enum zcr_keyboard_configuration_v1_error {
+	/**
+	 * the keyboard already has a device configuration object associated
+	 */
+	ZCR_KEYBOARD_CONFIGURATION_V1_ERROR_DEVICE_CONFIGURATION_EXISTS = 0,
+};
+#endif /* ZCR_KEYBOARD_CONFIGURATION_V1_ERROR_ENUM */
+
 /**
  * @ingroup iface_zcr_keyboard_configuration_v1
  * @struct zcr_keyboard_configuration_v1_interface
@@ -108,7 +118,10 @@
 	 * get keyboard_device_configuration interface for a keyboard
 	 *
 	 * Create keyboard_device_configuration object. See
-	 * zcr_keyboard_device_configuration interface for details.
+	 * zcr_keyboard_device_configuration interface for details. If the
+	 * given wl_keyboard object already has a device configuration
+	 * object associated, the keyboard_device_configuration_exists
+	 * protocol error is raised.
 	 */
 	void (*get_keyboard_device_configuration)(struct wl_client *client,
 						  struct wl_resource *resource,
diff --git a/third_party/wayland-protocols/protocol/keyboard-configuration-protocol.c b/third_party/wayland-protocols/protocol/keyboard-configuration-protocol.c
index b17117a4..0bddf1c 100644
--- a/third_party/wayland-protocols/protocol/keyboard-configuration-protocol.c
+++ b/third_party/wayland-protocols/protocol/keyboard-configuration-protocol.c
@@ -41,7 +41,7 @@
 };
 
 WL_EXPORT const struct wl_interface zcr_keyboard_configuration_v1_interface = {
-	"zcr_keyboard_configuration_v1", 1,
+	"zcr_keyboard_configuration_v1", 2,
 	1, zcr_keyboard_configuration_v1_requests,
 	0, NULL,
 };
diff --git a/third_party/wayland-protocols/unstable/keyboard/keyboard-configuration-unstable-v1.xml b/third_party/wayland-protocols/unstable/keyboard/keyboard-configuration-unstable-v1.xml
index 6acd844f..8d3cf72 100644
--- a/third_party/wayland-protocols/unstable/keyboard/keyboard-configuration-unstable-v1.xml
+++ b/third_party/wayland-protocols/unstable/keyboard/keyboard-configuration-unstable-v1.xml
@@ -24,7 +24,7 @@
     DEALINGS IN THE SOFTWARE.
   </copyright>
 
-  <interface name="zcr_keyboard_configuration_v1" version="1">
+  <interface name="zcr_keyboard_configuration_v1" version="2">
     <description summary="extends wl_keyboard with events for device configuration change">
       Allows a wl_keyboard to notify device configuration change events of
       the keyboard to the client.
@@ -39,10 +39,18 @@
       interface version number is reset.
     </description>
 
+    <enum name="error">
+      <entry name="device_configuration_exists" value="0"
+             summary="the keyboard already has a device configuration object associated"/>
+    </enum>
+
     <request name="get_keyboard_device_configuration">
       <description summary="get keyboard_device_configuration interface for a keyboard">
         Create keyboard_device_configuration object.
         See zcr_keyboard_device_configuration interface for details.
+        If the given wl_keyboard object already has a device configuration
+        object associated, the keyboard_device_configuration_exists protocol
+        error is raised.
       </description>
       <arg name="id" type="new_id" interface="zcr_keyboard_device_configuration_v1"/>
       <arg name="keyboard" type="object" interface="wl_keyboard"/>
diff --git a/tools/clang/scripts/update.py b/tools/clang/scripts/update.py
index 6ab466f..617710b 100755
--- a/tools/clang/scripts/update.py
+++ b/tools/clang/scripts/update.py
@@ -27,7 +27,7 @@
 # Do NOT CHANGE this if you don't know what you're doing -- see
 # https://chromium.googlesource.com/chromium/src/+/master/docs/updating_clang.md
 # Reverting problematic clang rolls is safe, though.
-CLANG_REVISION = '288545'
+CLANG_REVISION = '289228'
 
 use_head_revision = 'LLVM_FORCE_HEAD_REVISION' in os.environ
 if use_head_revision:
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index 90f5d6a2..50a7c2c 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -186,7 +186,7 @@
       'Site Isolation Android': 'android_release_bot_minimal_symbols_arm64',
       'Site Isolation Linux': 'release_trybot',
       'Site Isolation Win': 'release_trybot_x86',
-      'ThinLTO Linux ToT': 'thin_lto_clang_tot_release_static',
+      'ThinLTO Linux ToT': 'thin_lto_clang_tot_release_static_use_lld',
       'UBSanVptr Linux': 'ubsan_vptr_release_bot',
       'WebKit Linux - TraceWrappables': 'debug_bot',
       'WebKit Linux - WPTServe': 'release_bot',
@@ -1405,8 +1405,8 @@
       'syzyasan', 'no_pch', 'release', 'x86',
     ],
 
-    'thin_lto_clang_tot_release_static': [
-      'thin_lto', 'clang_tot', 'release', 'static',
+    'thin_lto_clang_tot_release_static_use_lld': [
+      'thin_lto', 'clang_tot', 'release', 'static', 'use_lld',
     ],
 
     'tsan_disable_nacl_debug_bot': [
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 31dc08ef..61c80867 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -8694,6 +8694,19 @@
   </summary>
 </histogram>
 
+<histogram
+    name="DataReductionProxy.DaysSinceSavingsCleared.NegativeSystemClock"
+    units="days">
+  <owner>tbansal@chromium.org</owner>
+  <owner>bengr@chromium.org</owner>
+  <summary>
+    Records the number of days since the data reduction savings were cleared
+    because the system clock moved back by more than 1 day. Recorded at Chrome
+    startup if data reduction proxy is enabled, and if the data reduction proxy
+    savings were cleared in some previous Chrome session.
+  </summary>
+</histogram>
+
 <histogram name="DataReductionProxy.EnabledState"
     enum="DataReductionProxyEnabledState">
   <owner>bengr@chromium.org</owner>
@@ -9043,6 +9056,17 @@
   </summary>
 </histogram>
 
+<histogram name="DataReductionProxy.SavingsCleared.NegativeSystemClock"
+    enum="BooleanCleared">
+  <owner>tbansal@chromium.org</owner>
+  <owner>bengr@chromium.org</owner>
+  <summary>
+    Records if the data reduction savings were cleared because the system clock
+    moved back by more than 1 day. Recorded at Chrome startup if the data
+    reduction proxy is enabled.
+  </summary>
+</histogram>
+
 <histogram name="DataReductionProxy.SecureProxyCheck.Latency" units="ms">
   <owner>bengr@chromium.org</owner>
   <summary>
@@ -9160,6 +9184,19 @@
   </summary>
 </histogram>
 
+<histogram name="DataReductionProxy.WarmupURL.FetchInitiated" units="count">
+  <owner>tbansal@chromium.org</owner>
+  <summary>
+    Number of times the data reduction proxy warm up URL was fetched.
+  </summary>
+</histogram>
+
+<histogram name="DataReductionProxy.WarmupURL.FetchSuccessful"
+    enum="BooleanSuccess">
+  <owner>tbansal@chromium.org</owner>
+  <summary>Whether the warm up URL was fetched succesfully.</summary>
+</histogram>
+
 <histogram name="DataUsage.MatchingRulesCount.Invalid" units="count">
   <owner>bengr@chromium.org</owner>
   <owner>rajendrant@chromium.org</owner>
@@ -48349,6 +48386,15 @@
   </summary>
 </histogram>
 
+<histogram name="Precache.CacheSize.AllEntries" units="KB">
+  <owner>jamartin@chromium.org</owner>
+  <owner>bengr@chromium.org</owner>
+  <summary>
+    The size in kilobytes occupied by all the entries existing in the cache at
+    the time of the last precache.
+  </summary>
+</histogram>
+
 <histogram name="Precache.CacheStatus.NonPrefetch" enum="HttpCachePattern">
   <owner>jamartin@chromium.org</owner>
   <owner>bengr@chromium.org</owner>
@@ -77180,6 +77226,11 @@
   <int value="1" label="Checked"/>
 </enum>
 
+<enum name="BooleanCleared" type="int">
+  <int value="0" label="Not cleared"/>
+  <int value="1" label="Cleared"/>
+</enum>
+
 <enum name="BooleanClicked" type="int">
   <int value="0" label="Not Clicked"/>
   <int value="1" label="Clicked"/>
diff --git a/tools/metrics/rappor/rappor.xml b/tools/metrics/rappor/rappor.xml
index 6f0adcf9..99f01e9 100644
--- a/tools/metrics/rappor/rappor.xml
+++ b/tools/metrics/rappor/rappor.xml
@@ -1063,6 +1063,30 @@
   </summary>
 </rappor-metric>
 
+<rappor-metric
+    name="Media.Autoplay.CrossOrigin.UserPausedAutoplayingVideo.ChildFrame"
+    type="ETLD_PLUS_ONE">
+  <owner>avayvod@chromium.org</owner>
+  <owner>mlamouri@chromium.org</owner>
+  <owner>zqzhang@chromium.org</owner>
+  <summary>
+    The eTLD+1 of a cross-origin iframe URL containing an autoplaying video but
+    the user actively paused it.
+  </summary>
+</rappor-metric>
+
+<rappor-metric
+    name="Media.Autoplay.CrossOrigin.UserPausedAutoplayingVideo.TopLevelFrame"
+    type="ETLD_PLUS_ONE">
+  <owner>avayvod@chromium.org</owner>
+  <owner>mlamouri@chromium.org</owner>
+  <owner>zqzhang@chromium.org</owner>
+  <summary>
+    The eTLD+1 of the top-level frame URL that has a cross-origin iframe
+    containing an autoplaying video but the user actively paused it.
+  </summary>
+</rappor-metric>
+
 <rappor-metric name="Media.OriginUrl.EME" type="ETLD_PLUS_ONE">
   <owner>xhwang@chromium.org</owner>
   <summary>
diff --git a/tools/perf/chrome_telemetry_build/BUILD.gn b/tools/perf/chrome_telemetry_build/BUILD.gn
index 8914f3c..a6e576b2 100644
--- a/tools/perf/chrome_telemetry_build/BUILD.gn
+++ b/tools/perf/chrome_telemetry_build/BUILD.gn
@@ -85,7 +85,57 @@
 
   data = [
     "//tools/perf/chrome_telemetry_build/",
-    "//third_party/catapult/",
+
+    # Breakdown the catapult directory so we can exclude
+    # third_party/catapult/tracing/test_data.  See crbug.com/670284
+    "//third_party/catapult/AUTHORS",
+    "//third_party/catapult/bin/",
+    "//third_party/catapult/catapult_build/",
+    "//third_party/catapult/codereview.settings",
+    "//third_party/catapult/common/",
+    "//third_party/catapult/CONTRIBUTING.md",
+    "//third_party/catapult/dashboard/",
+    "//third_party/catapult/dependency_manager/",
+    "//third_party/catapult/devil/",
+    "//third_party/catapult/docs/",
+    "//third_party/catapult/experimental/",
+    "//third_party/catapult/firefighter/",
+    "//third_party/catapult/hooks/",
+    "//third_party/catapult/infra/",
+    "//third_party/catapult/LICENSE",
+    "//third_party/catapult/navbar.md",
+    "//third_party/catapult/netlog_viewer/",
+    "//third_party/catapult/OWNERS",
+    "//third_party/catapult/PRESUBMIT.py",
+    "//third_party/catapult/pylintrc",
+    "//third_party/catapult/README.md",
+    "//third_party/catapult/systrace/",
+    "//third_party/catapult/telemetry/",
+    "//third_party/catapult/third_party/",
+    "//third_party/catapult/trace_processor/",
+
+    # We don't want to include catapult/tracing/test_data
+    "//third_party/catapult/tracing/app.yaml",
+    "//third_party/catapult/tracing/bin/",
+    "//third_party/catapult/tracing/bower.json",
+    "//third_party/catapult/tracing/BUILD.gn",
+    "//third_party/catapult/tracing/docs/",
+    "//third_party/catapult/tracing/images/",
+    "//third_party/catapult/tracing/LICENSE",
+    "//third_party/catapult/tracing/OWNERS",
+    "//third_party/catapult/tracing/package.json",
+    "//third_party/catapult/tracing/PRESUBMIT.py",
+    "//third_party/catapult/tracing/README.md",
+    "//third_party/catapult/tracing/skp_data/",
+    "//third_party/catapult/tracing/third_party/",
+    "//third_party/catapult/tracing/trace_viewer.gyp",
+    "//third_party/catapult/tracing/trace_viewer.gypi",
+    "//third_party/catapult/tracing/tracing/",
+    "//third_party/catapult/tracing/tracing_build/",
+    "//third_party/catapult/tracing/tracing_examples/",
+    "//third_party/catapult/tracing/tracing_project.py",
+    "//third_party/catapult/WATCHLISTS",
+
     "//components/crash/content/tools/generate_breakpad_symbols.py",
   ]
 
diff --git a/tools/perf/generate_perf_json.py b/tools/perf/generate_perf_json.py
index b0c29a4..14869ee 100755
--- a/tools/perf/generate_perf_json.py
+++ b/tools/perf/generate_perf_json.py
@@ -152,7 +152,13 @@
       {
        'gpu': '8086:22b1',
        'os': 'Windows-10-10586',
-       'device_ids': ['build47-b4', 'build48-b4'],
+       'device_ids': [
+           'build136-b1', 'build137-b1', 'build138-b1', 'build139-b1',
+           'build140-b1', 'build141-b1', 'build142-b1', 'build143-b1',
+           'build144-b1', 'build145-b1', 'build146-b1', 'build147-b1',
+           'build148-b1', 'build149-b1', 'build150-b1', 'build151-b1',
+           'build152-b1', 'build153-b1', 'build154-b1', 'build155-b1',
+           'build47-b4', 'build48-b4'],
        'perf_tests': [
          ('cc_perftests', 0),
          ('gpu_perftests', 0),
@@ -161,8 +167,7 @@
          ('performance_browser_tests', 1),
          ('tracing_perftests', 1)]
       }
-    ],
-    use_whitelist=True)
+    ])
   waterfall = add_tester(
     waterfall, 'Android Swarming N5X Tester',
     'fyi-android-swarming-n5x', 'android',
@@ -177,8 +182,7 @@
            'build245-m4--device7'
         ]
       }
-    ],
-    use_whitelist=True)
+    ])
   return waterfall
 
 
@@ -692,6 +696,7 @@
   benchmark_sharding_map['22'] = shard_benchmarks(22, all_benchmarks)
   benchmark_sharding_map['5'] = shard_benchmarks(5, all_benchmarks)
   benchmark_sharding_map['1'] = shard_benchmarks(1, all_benchmarks)
+  benchmark_sharding_map['7'] = shard_benchmarks(7, all_benchmarks)
 
   for name, config in waterfall['testers'].iteritems():
     use_whitelist = config['use_whitelist']
diff --git a/ui/android/java/res/layout/dropdown_item.xml b/ui/android/java/res/layout/dropdown_item.xml
index 29964fbf..5159c83 100644
--- a/ui/android/java/res/layout/dropdown_item.xml
+++ b/ui/android/java/res/layout/dropdown_item.xml
@@ -12,7 +12,6 @@
     android:orientation="horizontal" >
 
     <!-- These layout params are overwritten in DropdownAdapter.java -->
-
     <ImageView
         android:id="@+id/start_dropdown_icon"
         android:layout_width="wrap_content"
diff --git a/ui/android/java/src/org/chromium/ui/DropdownAdapter.java b/ui/android/java/src/org/chromium/ui/DropdownAdapter.java
index d8ad3f3..2a5a6e3 100644
--- a/ui/android/java/src/org/chromium/ui/DropdownAdapter.java
+++ b/ui/android/java/src/org/chromium/ui/DropdownAdapter.java
@@ -30,14 +30,34 @@
     private final Context mContext;
     private final Set<Integer> mSeparators;
     private final boolean mAreAllItemsEnabled;
+    private final Integer mBackgroundColor;
+    private final Integer mDividerColor;
+    private final Integer mDropdownItemHeight;
 
-    public DropdownAdapter(
-            Context context, List<? extends DropdownItem> items, Set<Integer> separators) {
+    /**
+     * Creates an {@code ArrayAdapter} with specified parameters.
+     * @param context Application context.
+     * @param items List of labels and icons to display.
+     * @param separators Set of positions that separate {@code items}.
+     * @param backgroundColor Popup background color, or {@code null} to use default background
+     * color. The default color is {@code Color.TRANSPARENT}.
+     * @param dividerColor If {@code null}, use the values in colors.xml for the divider
+     * between items. Otherwise, uses {@param dividerColor} for the divider between items. Always
+     * uses the values in colors.xml for the dark divider for the separators.
+     * @param dropdownItemHeight If {@code null}, uses the {@code dropdown_item_height} in
+     * dimens.xml. Otherwise, uses {@param dropdownItemHeight}.
+     */
+    public DropdownAdapter(Context context, List<? extends DropdownItem> items,
+            Set<Integer> separators, Integer backgroundColor, Integer dividerColor,
+            Integer dropdownItemHeight) {
         super(context, R.layout.dropdown_item);
+        mContext = context;
         addAll(items);
         mSeparators = separators;
-        mContext = context;
         mAreAllItemsEnabled = checkAreAllItemsEnabled();
+        mBackgroundColor = backgroundColor;
+        mDividerColor = dividerColor;
+        mDropdownItemHeight = dropdownItemHeight;
     }
 
     private boolean checkAreAllItemsEnabled() {
@@ -57,25 +77,35 @@
             LayoutInflater inflater =
                     (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
             layout = inflater.inflate(R.layout.dropdown_item, null);
-            layout.setBackground(new DropdownDividerDrawable());
+            layout.setBackground(new DropdownDividerDrawable(mBackgroundColor));
+        }
+        DropdownDividerDrawable divider = (DropdownDividerDrawable) layout.getBackground();
+        int height;
+        if (mDropdownItemHeight == null) {
+            height = mContext.getResources().getDimensionPixelSize(R.dimen.dropdown_item_height);
+        } else {
+            height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
+                    mDropdownItemHeight, mContext.getResources().getDisplayMetrics());
         }
 
-        DropdownDividerDrawable divider = (DropdownDividerDrawable) layout.getBackground();
-        int height = mContext.getResources().getDimensionPixelSize(R.dimen.dropdown_item_height);
         if (position == 0) {
-            divider.setColor(Color.TRANSPARENT);
+            divider.setDividerColor(Color.TRANSPARENT);
         } else {
             int dividerHeight = mContext.getResources().getDimensionPixelSize(
                     R.dimen.dropdown_item_divider_height);
             height += dividerHeight;
             divider.setHeight(dividerHeight);
+            int dividerColor;
             if (mSeparators != null && mSeparators.contains(position)) {
-                divider.setColor(ApiCompatibilityUtils.getColor(mContext.getResources(),
-                        R.color.dropdown_dark_divider_color));
+                dividerColor = ApiCompatibilityUtils.getColor(mContext.getResources(),
+                        R.color.dropdown_dark_divider_color);
+            } else if (mDividerColor == null) {
+                dividerColor = ApiCompatibilityUtils.getColor(mContext.getResources(),
+                        R.color.dropdown_divider_color);
             } else {
-                divider.setColor(ApiCompatibilityUtils.getColor(mContext.getResources(),
-                        R.color.dropdown_divider_color));
+                dividerColor = mDividerColor;
             }
+            divider.setDividerColor(dividerColor);
         }
 
         DropdownItem item = getItem(position);
@@ -113,7 +143,7 @@
         }
 
         labelView.setEnabled(item.isEnabled());
-        if (item.isGroupHeader()) {
+        if (item.isGroupHeader() || item.isBoldLabel()) {
             labelView.setTypeface(null, Typeface.BOLD);
         } else {
             labelView.setTypeface(null, Typeface.NORMAL);
diff --git a/ui/android/java/src/org/chromium/ui/DropdownDividerDrawable.java b/ui/android/java/src/org/chromium/ui/DropdownDividerDrawable.java
index 014192a5..1b45064f 100644
--- a/ui/android/java/src/org/chromium/ui/DropdownDividerDrawable.java
+++ b/ui/android/java/src/org/chromium/ui/DropdownDividerDrawable.java
@@ -13,16 +13,24 @@
 
 class DropdownDividerDrawable extends Drawable {
 
-    private Paint mPaint;
-    private Rect mDividerRect;
+    private final Paint mPaint;
+    private final Rect mDividerRect;
+    private final Integer mBackgroundColor;
 
-    public DropdownDividerDrawable() {
+    /**
+     * Creates a drawable to draw a divider line that separates the list of {@link DropdownItem}
+     * and, optionally, paints the rectangular canvas.
+     * @param backgroundColor Popup background color. If {@code null}, does not paint the canvas.
+     */
+    public DropdownDividerDrawable(Integer backgroundColor) {
         mPaint = new Paint();
         mDividerRect = new Rect();
+        mBackgroundColor = backgroundColor;
     }
 
     @Override
     public void draw(Canvas canvas) {
+        if (mBackgroundColor != null) canvas.drawColor(mBackgroundColor);
         canvas.drawRect(mDividerRect, mPaint);
     }
 
@@ -35,7 +43,7 @@
         mDividerRect.set(0, 0, mDividerRect.right, height);
     }
 
-    public void setColor(int color) {
+    public void setDividerColor(int color) {
         mPaint.setColor(color);
     }
 
diff --git a/ui/android/java/src/org/chromium/ui/DropdownItem.java b/ui/android/java/src/org/chromium/ui/DropdownItem.java
index 7ad26d5..d28db1d 100644
--- a/ui/android/java/src/org/chromium/ui/DropdownItem.java
+++ b/ui/android/java/src/org/chromium/ui/DropdownItem.java
@@ -36,6 +36,10 @@
      */
     boolean isMultilineLabel();
     /**
+     * Returns whether the label should be displayed in bold.
+     */
+    boolean isBoldLabel();
+    /**
      * Returns resource ID of label's font color.
      */
     int getLabelFontColorResId();
diff --git a/ui/android/java/src/org/chromium/ui/DropdownItemBase.java b/ui/android/java/src/org/chromium/ui/DropdownItemBase.java
index 9554d33d..9a0c7658 100644
--- a/ui/android/java/src/org/chromium/ui/DropdownItemBase.java
+++ b/ui/android/java/src/org/chromium/ui/DropdownItemBase.java
@@ -40,6 +40,11 @@
     }
 
     @Override
+    public boolean isBoldLabel() {
+        return false;
+    }
+
+    @Override
     public int getLabelFontColorResId() {
         return R.drawable.dropdown_label_color;
     }
diff --git a/ui/aura/mus/text_input_client_impl.cc b/ui/aura/mus/text_input_client_impl.cc
index 2dbc39e..782e834 100644
--- a/ui/aura/mus/text_input_client_impl.cc
+++ b/ui/aura/mus/text_input_client_impl.cc
@@ -38,9 +38,7 @@
 
 void TextInputClientImpl::InsertChar(std::unique_ptr<ui::Event> event) {
   DCHECK(event->IsKeyEvent());
-  ui::KeyEvent* key_event = event->AsKeyEvent();
-  DCHECK(key_event->is_char());
-  text_input_client_->InsertChar(*key_event);
+  text_input_client_->InsertChar(*event->AsKeyEvent());
 }
 
 }  // namespace aura
diff --git a/ui/base/ime/input_method_chromeos.cc b/ui/base/ime/input_method_chromeos.cc
index a8ac902..27d0a559 100644
--- a/ui/base/ime/input_method_chromeos.cc
+++ b/ui/base/ime/input_method_chromeos.cc
@@ -57,34 +57,9 @@
     ui::IMEBridge::Get()->SetInputContextHandler(NULL);
 }
 
-bool InputMethodChromeOS::OnUntranslatedIMEMessage(
-    const base::NativeEvent& event,
-    NativeEventResult* result) {
-  return false;
-}
-
-void InputMethodChromeOS::ProcessKeyEventDone(ui::KeyEvent* event,
-                                              bool is_handled) {
-  DCHECK(event);
-  if (event->type() == ET_KEY_PRESSED) {
-    if (is_handled) {
-      // IME event has a priority to be handled, so that character composer
-      // should be reset.
-      character_composer_.Reset();
-    } else {
-      // If IME does not handle key event, passes keyevent to character composer
-      // to be able to compose complex characters.
-      is_handled = ExecuteCharacterComposer(*event);
-    }
-  }
-
-  if (event->type() == ET_KEY_PRESSED || event->type() == ET_KEY_RELEASED)
-    ProcessKeyEventPostIME(event, is_handled);
-
-  handling_key_event_ = false;
-}
-
-void InputMethodChromeOS::DispatchKeyEvent(ui::KeyEvent* event) {
+void InputMethodChromeOS::DispatchKeyEvent(
+    ui::KeyEvent* event,
+    std::unique_ptr<AckCallback> ack_callback) {
   DCHECK(event->IsKeyEvent());
   DCHECK(!(event->flags() & ui::EF_IS_SYNTHESIZED));
 
@@ -114,28 +89,68 @@
         // Treating as PostIME event if character composer handles key event and
         // generates some IME event,
         ProcessKeyEventPostIME(event, true);
+        if (ack_callback)
+          ack_callback->Run(true);
         return;
       }
       ProcessUnfilteredKeyPressEvent(event);
     } else {
       ignore_result(DispatchKeyEventPostIME(event));
     }
+    if (ack_callback)
+      ack_callback->Run(false);
     return;
   }
 
   handling_key_event_ = true;
   if (GetEngine()->IsInterestedInKeyEvent()) {
-    ui::IMEEngineHandlerInterface::KeyEventDoneCallback callback =
-        base::Bind(&InputMethodChromeOS::ProcessKeyEventDone,
-                   weak_ptr_factory_.GetWeakPtr(),
-                   // Pass the ownership of the new copied event.
-                   base::Owned(new ui::KeyEvent(*event)));
+    ui::IMEEngineHandlerInterface::KeyEventDoneCallback callback = base::Bind(
+        &InputMethodChromeOS::ProcessKeyEventDone,
+        weak_ptr_factory_.GetWeakPtr(),
+        // Pass the ownership of the new copied event.
+        base::Owned(new ui::KeyEvent(*event)), Passed(&ack_callback));
     GetEngine()->ProcessKeyEvent(*event, callback);
   } else {
-    ProcessKeyEventDone(event, false);
+    ProcessKeyEventDone(event, std::move(ack_callback), false);
   }
 }
 
+bool InputMethodChromeOS::OnUntranslatedIMEMessage(
+    const base::NativeEvent& event,
+    NativeEventResult* result) {
+  return false;
+}
+
+void InputMethodChromeOS::ProcessKeyEventDone(
+    ui::KeyEvent* event,
+    std::unique_ptr<AckCallback> ack_callback,
+    bool is_handled) {
+  DCHECK(event);
+  if (event->type() == ET_KEY_PRESSED) {
+    if (is_handled) {
+      // IME event has a priority to be handled, so that character composer
+      // should be reset.
+      character_composer_.Reset();
+    } else {
+      // If IME does not handle key event, passes keyevent to character composer
+      // to be able to compose complex characters.
+      is_handled = ExecuteCharacterComposer(*event);
+    }
+  }
+
+  if (ack_callback)
+    ack_callback->Run(is_handled);
+
+  if (event->type() == ET_KEY_PRESSED || event->type() == ET_KEY_RELEASED)
+    ProcessKeyEventPostIME(event, is_handled);
+
+  handling_key_event_ = false;
+}
+
+void InputMethodChromeOS::DispatchKeyEvent(ui::KeyEvent* event) {
+  DispatchKeyEvent(event, nullptr);
+}
+
 void InputMethodChromeOS::OnTextInputTypeChanged(
     const TextInputClient* client) {
   if (!IsTextInputClientFocused(client))
diff --git a/ui/base/ime/input_method_chromeos.h b/ui/base/ime/input_method_chromeos.h
index a4145cdd..e3a8728 100644
--- a/ui/base/ime/input_method_chromeos.h
+++ b/ui/base/ime/input_method_chromeos.h
@@ -27,6 +27,10 @@
   explicit InputMethodChromeOS(internal::InputMethodDelegate* delegate);
   ~InputMethodChromeOS() override;
 
+  using AckCallback = base::Callback<void(bool)>;
+  void DispatchKeyEvent(ui::KeyEvent* event,
+                        std::unique_ptr<AckCallback> ack_callback);
+
   // Overridden from InputMethod:
   bool OnUntranslatedIMEMessage(const base::NativeEvent& event,
                                 NativeEventResult* result) override;
@@ -100,7 +104,9 @@
   void HidePreeditText();
 
   // Callback function for IMEEngineHandlerInterface::ProcessKeyEvent.
-  void ProcessKeyEventDone(ui::KeyEvent* event, bool is_handled);
+  void ProcessKeyEventDone(ui::KeyEvent* event,
+                           std::unique_ptr<AckCallback> ack_callback,
+                           bool is_handled);
 
   // Returns whether an non-password input field is focused.
   bool IsNonPasswordInputFieldFocused();
diff --git a/ui/login/account_picker/screen_account_picker.js b/ui/login/account_picker/screen_account_picker.js
index 7cac00b..5044a3d 100644
--- a/ui/login/account_picker/screen_account_picker.js
+++ b/ui/login/account_picker/screen_account_picker.js
@@ -266,6 +266,14 @@
      * @param {array} users Array of user instances.
      */
     initializePinKeyboardStateForUsers_: function(users) {
+      // It is possible that the PIN keyboard HTML has already been loaded. If
+      // that is the case, we want to show the user pods with the PIN keyboard
+      // immediately without running the PIN show/hide effect.
+      document.body.classList.add('disable-pin-animation');
+      setTimeout(function() {
+        document.body.classList.remove('disable-pin-animation');
+      });
+
       for (var i = 0; i < users.length; ++i) {
         var user = users[i];
         if (user.showPin) {
diff --git a/ui/login/account_picker/user_pod_row.css b/ui/login/account_picker/user_pod_row.css
index f4bf5d6..7ef24e11 100644
--- a/ui/login/account_picker/user_pod_row.css
+++ b/ui/login/account_picker/user_pod_row.css
@@ -54,6 +54,10 @@
   top: -87px !important;
 }
 
+.disable-pin-animation .pod.pin-enabled {
+  transition: none;
+}
+
 .pod .pin-container {
   height: 204px;
   position: absolute;
diff --git a/ui/login/screen_container.css b/ui/login/screen_container.css
index cf505f2d..6e0fcfe 100644
--- a/ui/login/screen_container.css
+++ b/ui/login/screen_container.css
@@ -34,6 +34,10 @@
                          checked to determine if loaded. */
 }
 
+.disable-pin-animation .pin-container {
+  transition: none;
+}
+
 #scroll-container {
   bottom: 0;        /* Allows content overlap with control bar. */
   left: 0;
diff --git a/ui/views/controls/button/label_button.cc b/ui/views/controls/button/label_button.cc
index 03738f8..21891fc 100644
--- a/ui/views/controls/button/label_button.cc
+++ b/ui/views/controls/button/label_button.cc
@@ -159,25 +159,13 @@
   label_->SetSubpixelRenderingEnabled(enabled);
 }
 
-const gfx::FontList& LabelButton::GetFontList() const {
-  return label_->font_list();
-}
-
-void LabelButton::SetFontList(const gfx::FontList& font_list) {
-  cached_normal_font_list_ = font_list;
-  if (PlatformStyle::kDefaultLabelButtonHasBoldFont) {
-    cached_bold_font_list_ = font_list.DeriveWithWeight(
-        GetValueBolderThan(font_list.GetFontWeight()));
-    if (is_default_) {
-      label_->SetFontList(cached_bold_font_list_);
-      return;
-    }
-  }
-  label_->SetFontList(cached_normal_font_list_);
+void LabelButton::SetFontListDeprecated(const gfx::FontList& font_list) {
+  SetFontList(font_list);
 }
 
 void LabelButton::AdjustFontSize(int font_size_delta) {
-  LabelButton::SetFontList(GetFontList().DeriveWithSizeDelta(font_size_delta));
+  LabelButton::SetFontList(
+      label()->font_list().DeriveWithSizeDelta(font_size_delta));
 }
 
 void LabelButton::SetElideBehavior(gfx::ElideBehavior elide_behavior) {
@@ -393,6 +381,19 @@
   return GetLocalBounds();
 }
 
+void LabelButton::SetFontList(const gfx::FontList& font_list) {
+  cached_normal_font_list_ = font_list;
+  if (PlatformStyle::kDefaultLabelButtonHasBoldFont) {
+    cached_bold_font_list_ = font_list.DeriveWithWeight(
+        GetValueBolderThan(font_list.GetFontWeight()));
+    if (is_default_) {
+      label_->SetFontList(cached_bold_font_list_);
+      return;
+    }
+  }
+  label_->SetFontList(cached_normal_font_list_);
+}
+
 void LabelButton::OnPaint(gfx::Canvas* canvas) {
   View::OnPaint(canvas);
   Painter::PaintFocusPainter(this, canvas, focus_painter_.get());
diff --git a/ui/views/controls/button/label_button.h b/ui/views/controls/button/label_button.h
index a78ccb0..6228ab2b 100644
--- a/ui/views/controls/button/label_button.h
+++ b/ui/views/controls/button/label_button.h
@@ -56,10 +56,8 @@
   // Sets whether subpixel rendering is used on the label.
   void SetTextSubpixelRenderingEnabled(bool enabled);
 
-  // Gets or sets the font list used by this button.
-  const gfx::FontList& GetFontList() const;
-  // TODO(estade): make this function protected.
-  virtual void SetFontList(const gfx::FontList& font_list);
+  // TODO(estade): remove. See crbug.com/633986
+  void SetFontListDeprecated(const gfx::FontList& font_list);
 
   // Adjusts the font size up or down by the given amount.
   virtual void AdjustFontSize(int font_size_delta);
@@ -120,6 +118,9 @@
   // these bounds if they need room to do manual painting.
   virtual gfx::Rect GetChildAreaBounds();
 
+  // Sets the font list used by this button.
+  virtual void SetFontList(const gfx::FontList& font_list);
+
   // View:
   void OnPaint(gfx::Canvas* canvas) override;
   void OnFocus() override;
diff --git a/ui/views/controls/button/label_button_unittest.cc b/ui/views/controls/button/label_button_unittest.cc
index 4696e73..459991d 100644
--- a/ui/views/controls/button/label_button_unittest.cc
+++ b/ui/views/controls/button/label_button_unittest.cc
@@ -291,24 +291,21 @@
   EXPECT_LT(button_->GetPreferredSize().height(), image_size);
 }
 
-TEST_F(LabelButtonTest, FontList) {
+TEST_F(LabelButtonTest, AdjustFontSize) {
   button_->SetText(base::ASCIIToUTF16("abc"));
 
-  const gfx::FontList original_font_list = button_->GetFontList();
-  const gfx::FontList large_font_list =
-      original_font_list.DeriveWithSizeDelta(100);
   const int original_width = button_->GetPreferredSize().width();
   const int original_height = button_->GetPreferredSize().height();
 
   // The button size increases when the font size is increased.
-  button_->SetFontList(large_font_list);
+  button_->AdjustFontSize(100);
   EXPECT_GT(button_->GetPreferredSize().width(), original_width);
   EXPECT_GT(button_->GetPreferredSize().height(), original_height);
 
   // The button returns to its original size when the minimal size is cleared
   // and the original font size is restored.
   button_->SetMinSize(gfx::Size());
-  button_->SetFontList(original_font_list);
+  button_->AdjustFontSize(-100);
   EXPECT_EQ(original_width, button_->GetPreferredSize().width());
   EXPECT_EQ(original_height, button_->GetPreferredSize().height());
 }
diff --git a/ui/views/mus/text_input_client_impl.cc b/ui/views/mus/text_input_client_impl.cc
index 9e5b216..4193e127 100644
--- a/ui/views/mus/text_input_client_impl.cc
+++ b/ui/views/mus/text_input_client_impl.cc
@@ -38,9 +38,7 @@
 
 void TextInputClientImpl::InsertChar(std::unique_ptr<ui::Event> event) {
   DCHECK(event->IsKeyEvent());
-  ui::KeyEvent* key_event = event->AsKeyEvent();
-  DCHECK(key_event->is_char());
-  text_input_client_->InsertChar(*key_event);
+  text_input_client_->InsertChar(*event->AsKeyEvent());
 }
 
 }  // namespace views
diff --git a/ui/wm/core/shadow.cc b/ui/wm/core/shadow.cc
index 8319095..6b1290d 100644
--- a/ui/wm/core/shadow.cc
+++ b/ui/wm/core/shadow.cc
@@ -15,10 +15,6 @@
 
 namespace {
 
-// The opacity used for active shadow when animating between
-// inactive/active shadow.
-const float kInactiveShadowAnimationOpacity = 0.2f;
-
 // Rounded corners are overdrawn on top of the window's content layer,
 // we need to exclude them from the occlusion area.
 const int kRoundedCornerRadius = 2;
@@ -73,18 +69,16 @@
 
 void Shadow::Init(Style style) {
   style_ = style;
-
   layer_.reset(new ui::Layer(ui::LAYER_NOT_DRAWN));
-  shadow_layer_.reset(new ui::Layer(ui::LAYER_NINE_PATCH));
-  layer()->Add(shadow_layer_.get());
-
-  UpdateImagesForStyle();
-  shadow_layer_->set_name("Shadow");
-  shadow_layer_->SetVisible(true);
-  shadow_layer_->SetFillsBoundsOpaquely(false);
+  RecreateShadowLayer();
 }
 
 void Shadow::SetContentBounds(const gfx::Rect& content_bounds) {
+  // When the window moves but doesn't change size, this is a no-op. (The
+  // origin stays the same in this case.)
+  if (content_bounds == content_bounds_)
+    return;
+
   content_bounds_ = content_bounds;
   UpdateLayerBounds();
 }
@@ -93,64 +87,49 @@
   if (style_ == style)
     return;
 
-  Style old_style = style_;
   style_ = style;
 
   // Stop waiting for any as yet unfinished implicit animations.
   StopObservingImplicitAnimations();
 
-  // If we're switching to or from the small style, don't bother with
-  // animations.
-  if (style == STYLE_SMALL || old_style == STYLE_SMALL) {
-    UpdateImagesForStyle();
-    // Make sure the shadow is fully opaque.
-    shadow_layer_->SetOpacity(1.0f);
-    return;
-  }
-
-  // If we're becoming active, switch images now.  Because the inactive image
-  // has a very low opacity the switch isn't noticeable and this approach
-  // allows us to use only a single set of shadow images at a time.
-  if (style == STYLE_ACTIVE) {
-    UpdateImagesForStyle();
-    // Opacity was baked into inactive image, start opacity low to match.
-    shadow_layer_->SetOpacity(kInactiveShadowAnimationOpacity);
-  }
+  // The old shadow layer is the new fading out layer.
+  DCHECK(shadow_layer_);
+  fading_layer_ = std::move(shadow_layer_);
+  RecreateShadowLayer();
+  shadow_layer_->SetOpacity(0.f);
 
   {
-    // Property sets within this scope will be implicitly animated.
-    ui::ScopedLayerAnimationSettings settings(shadow_layer_->GetAnimator());
+    // Observe the fade out animation so we can clean up the layer when done.
+    ui::ScopedLayerAnimationSettings settings(fading_layer_->GetAnimator());
     settings.AddObserver(this);
     settings.SetTransitionDuration(
         base::TimeDelta::FromMilliseconds(kShadowAnimationDurationMs));
-    switch (style_) {
-      case STYLE_ACTIVE:
-        // Animate the active shadow from kInactiveShadowAnimationOpacity to
-        // 1.0f.
-        shadow_layer_->SetOpacity(1.0f);
-        break;
-      case STYLE_INACTIVE:
-        // The opacity will be reset to 1.0f when animation is completed.
-        shadow_layer_->SetOpacity(kInactiveShadowAnimationOpacity);
-        break;
-      default:
-        NOTREACHED() << "Unhandled style " << style_;
-        break;
-    }
+    fading_layer_->SetOpacity(0.f);
+  }
+
+  {
+    // We don't care to observe this one.
+    ui::ScopedLayerAnimationSettings settings(shadow_layer_->GetAnimator());
+    settings.SetTransitionDuration(
+        base::TimeDelta::FromMilliseconds(kShadowAnimationDurationMs));
+    shadow_layer_->SetOpacity(1.f);
   }
 }
 
 void Shadow::OnImplicitAnimationsCompleted() {
-  // If we just finished going inactive, switch images.  This doesn't cause
-  // a visual pop because the inactive image opacity is so low.
-  if (style_ == STYLE_INACTIVE) {
-    UpdateImagesForStyle();
-    // Opacity is baked into inactive image, so set fully opaque.
-    shadow_layer_->SetOpacity(1.0f);
-  }
+  fading_layer_.reset();
+  // The size needed for layer() may be smaller now that |fading_layer_| is
+  // removed.
+  UpdateLayerBounds();
 }
 
-void Shadow::UpdateImagesForStyle() {
+void Shadow::RecreateShadowLayer() {
+  shadow_layer_.reset(new ui::Layer(ui::LAYER_NINE_PATCH));
+  shadow_layer_->set_name("Shadow");
+  shadow_layer_->SetVisible(true);
+  shadow_layer_->SetFillsBoundsOpaquely(false);
+  layer()->Add(shadow_layer_.get());
+
   const ShadowDetails& details = GetDetailsForElevation(ElevationForStyle());
   shadow_layer_->UpdateNinePatchLayerImage(details.ninebox_image);
   // The ninebox grid is defined in terms of the image size. The shadow blurs in
@@ -170,15 +149,37 @@
   // Shadow margins are negative, so this expands outwards from
   // |content_bounds_|.
   const gfx::Insets margins = gfx::ShadowValue::GetMargin(details.values);
-  gfx::Rect layer_bounds = content_bounds_;
-  layer_bounds.Inset(margins);
-  layer()->SetBounds(layer_bounds);
-  const gfx::Rect shadow_layer_bounds(layer_bounds.size());
+  gfx::Rect new_layer_bounds = content_bounds_;
+  new_layer_bounds.Inset(margins);
+  gfx::Rect shadow_layer_bounds(new_layer_bounds.size());
+
+  // When there's an old shadow fading out, the bounds of layer() have to be
+  // big enough to encompass both shadows.
+  if (fading_layer_) {
+    const gfx::Rect old_layer_bounds = layer()->bounds();
+    gfx::Rect combined_layer_bounds = old_layer_bounds;
+    combined_layer_bounds.Union(new_layer_bounds);
+    layer()->SetBounds(combined_layer_bounds);
+
+    // If this is reached via SetContentBounds, we might hypothetically need
+    // to change the size of the fading layer, but the fade is so fast it's
+    // not really an issue.
+    gfx::Rect fading_layer_bounds(fading_layer_->bounds());
+    fading_layer_bounds.Offset(old_layer_bounds.origin() -
+                               combined_layer_bounds.origin());
+    fading_layer_->SetBounds(fading_layer_bounds);
+
+    shadow_layer_bounds.Offset(new_layer_bounds.origin() -
+                               combined_layer_bounds.origin());
+  } else {
+    layer()->SetBounds(new_layer_bounds);
+  }
+
   shadow_layer_->SetBounds(shadow_layer_bounds);
 
   // Occlude the region inside the bounding box. Occlusion uses shadow layer
   // space. See nine_patch_layer.h for more context on what's going on here.
-  gfx::Rect occlusion_bounds = shadow_layer_bounds;
+  gfx::Rect occlusion_bounds(shadow_layer_bounds.size());
   occlusion_bounds.Inset(-margins + gfx::Insets(kRoundedCornerRadius));
   shadow_layer_->UpdateNinePatchOcclusion(occlusion_bounds);
 
diff --git a/ui/wm/core/shadow.h b/ui/wm/core/shadow.h
index e0b7a1db..24fbfed 100644
--- a/ui/wm/core/shadow.h
+++ b/ui/wm/core/shadow.h
@@ -62,8 +62,8 @@
   void OnImplicitAnimationsCompleted() override;
 
  private:
-  // Updates the shadow images to the current |style_|.
-  void UpdateImagesForStyle();
+  // Updates the shadow layer and its image to the current |style_|.
+  void RecreateShadowLayer();
 
   // Updates the shadow layer bounds based on the inteior inset and the current
   // |content_bounds_|.
@@ -84,6 +84,10 @@
   // The actual shadow layer corresponding to a cc::NinePatchLayer.
   std::unique_ptr<ui::Layer> shadow_layer_;
 
+  // When the style changes, the old shadow cross-fades with the new one.
+  // When non-null, this is an old |shadow_layer_| that's being animated out.
+  std::unique_ptr<ui::Layer> fading_layer_;
+
   // Bounds of the content that the shadow encloses.
   gfx::Rect content_bounds_;